Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bjorng committed Jan 6, 2024
1 parent 97fc616 commit bb64172
Showing 1 changed file with 42 additions and 56 deletions.
98 changes: 42 additions & 56 deletions erts/emulator/beam/jit/arm/beam_asm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -995,86 +995,77 @@ class BeamModuleAssembler : public BeamAssembler,
last_destination_offset = a.offset();
}

int get_cache_entry() {
for (int slot = 0; slot < num_cache_entries; slot++) {
if (!cache[slot].mem.hasBase()) {
return slot;
void invalidate_cache(arm::Gp dst) {
for (int i = 0; i < num_cache_entries; i++) {
if (dst == cache[i].reg1) {
cache[i].reg1 = arm::Gp();
if (!cache[i].reg2.isValid()) {
cache[i].mem = arm::Mem();
}
} else if (dst == cache[i].reg2) {
cache[i].reg2 = arm::Gp();
if (!cache[i].reg1.isValid()) {
cache[i].mem = arm::Mem();
}
}
}

if (num_cache_entries < max_cache_entries) {
return num_cache_entries++;
} else {
return 0;
}
}

int get_cache_entry(arm::Mem mem) {
for (int slot = 0; slot < num_cache_entries; slot++) {
void put_cache_entry(arm::Mem mem, arm::Gp reg) {
int slot;

for (slot = 0; slot < num_cache_entries; slot++) {
if (cache[slot].mem == mem) {
return slot;
break;
}
}

if (slot >= num_cache_entries) {
for (slot = 0; slot < num_cache_entries; slot++) {
if (!cache[slot].mem.hasBase()) {
break;
}
}

if (slot >= num_cache_entries) {
if (num_cache_entries < max_cache_entries) {
slot = num_cache_entries++;
} else {
slot = 0;
}
}
cache[slot].mem = mem;
}

return get_cache_entry();
cache[slot].reg1 = reg;
cache[slot].reg2 = arm::Gp();
}

/* Works as the STR instruction, but also updates the cache. */
void str_cache(arm::Gp src, arm::Mem dst) {
int slot;

consolidate_cache();
invalidate_cache(src);

a.str(src, dst);

slot = get_cache_entry(dst);

put_cache_entry(dst, src);
last_destination_offset = a.offset();

cache[slot].reg1 = src;
cache[slot].reg2 = arm::Gp();
cache[slot].mem = dst;
}

/* Works as the STP instruction, but also updates the cache. */
void stp_cache(arm::Gp src1, arm::Gp src2, arm::Mem dst) {
arm::Mem next_dst = arm::Mem(arm::GpX(dst.baseId()), dst.offset() + 8);
int slot;

consolidate_cache();
invalidate_cache(src1);
invalidate_cache(src2);

safe_stp(src1, src2, dst);

last_destination_offset = a.offset();
put_cache_entry(dst, src1);
put_cache_entry(next_dst, src2);

slot = get_cache_entry(dst);
cache[slot].reg1 = src1;
cache[slot].reg2 = arm::Gp();
cache[slot].mem = dst;

slot = get_cache_entry(next_dst);
cache[slot].reg1 = src2;
cache[slot].reg2 = arm::Gp();
cache[slot].mem = next_dst;
}

void invalidate_cache(arm::Gp dst) {
for (int i = 0; i < num_cache_entries; i++) {
if (dst == cache[i].reg1) {
cache[i].reg1 = arm::Gp();
if (!cache[i].reg2.isValid()) {
cache[i].mem = arm::Mem();
}
} else if (dst == cache[i].reg2) {
cache[i].reg2 = arm::Gp();
if (!cache[i].reg1.isValid()) {
cache[i].mem = arm::Mem();
}
}
}
last_destination_offset = a.offset();
}

/* Works like LDR, but looks in the cache first. */
Expand Down Expand Up @@ -1108,16 +1099,11 @@ class BeamModuleAssembler : public BeamAssembler,
cache[slot].reg2 = dst;
}
} else {
int slot;

/* Not cached. Load and preserve the cache. */
/* Not cached. Load and update cache. */
a.ldr(dst, mem);
preserve__cache(dst);

slot = get_cache_entry();
cache[slot].reg1 = dst;
cache[slot].reg2 = arm::Gp();
cache[slot].mem = mem;
put_cache_entry(mem, dst);
}
}

Expand Down

0 comments on commit bb64172

Please sign in to comment.