aboutsummaryrefslogtreecommitdiffhomepage
path: root/ir
diff options
context:
space:
mode:
authorlemon <lsof@mailbox.org>2025-10-22 10:47:09 +0200
committerlemon <lsof@mailbox.org>2025-10-22 10:47:09 +0200
commit2cfd137e001758887e4f0a64db6f2f4787ff69a4 (patch)
tree73b0af17d9a00e8f31bb0b3820d34717e6b5b026 /ir
parentcfbe79d726ceff1aba98345e4f7b82ec6530bb3b (diff)
fix edge case codegen bugs (w/ stack offsets, spilling)
Diffstat (limited to 'ir')
-rw-r--r--ir/regalloc.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/ir/regalloc.c b/ir/regalloc.c
index 0dcb11c..81ebff9 100644
--- a/ir/regalloc.c
+++ b/ir/regalloc.c
@@ -938,7 +938,9 @@ devirt(struct rega *ra, struct block *blk)
struct instr *ins = &instrtab[temp];
struct interval *it;
struct alloc *alloc;
+ struct addr newaddr;
union ref *argref[4];
+ int naddr = 0;
int nargref = 0;
int nspill = 0;
@@ -946,16 +948,17 @@ devirt(struct rega *ra, struct block *blk)
for (int i = 0; i < 2; ++i) {
union ref *r = &i[&ins->l];
if (r->t == RADDR) {
- /* XXX mutating hashed addr.. should be fine though (because
- * new RADDRs shouldn't be created after regalloc)
- * maybe hashing them in the first place is unnecessary */
struct addr *a = &addrht[r->i];
- argref[nargref++] = &a->base;
- argref[nargref++] = &a->index;
+ ++naddr;
+ newaddr = *a;
+ argref[nargref++] = &newaddr.base;
+ argref[nargref++] = &newaddr.index;
} else {
argref[nargref++] = r;
}
}
+ assert(naddr < 2);
+
for (int i = 0; i < nargref; ++i) {
static uchar cls2load[] = {
[KI4] = Oloads4, [KI8] = Oloadi8, [KF4] = Oloadf4, [KF8] = Oloadf8, [KPTR] = 0
@@ -1010,6 +1013,10 @@ devirt(struct rega *ra, struct block *blk)
}
}
if (nspill > 0) assert(ins->op != Ocall);
+ if (naddr) {
+ union ref *r = ins->l.t == RADDR ? &ins->l : &ins->r;
+ *r = mkaddr(newaddr);
+ }
/* devirtualize destination */
alloc = temp < ra->intervals.ntemps && (it = &ra->intervals.temps[temp]) && it->nrange ? &it->alloc : NULL;
@@ -1025,7 +1032,7 @@ devirt(struct rega *ra, struct block *blk)
assert(nspill == 0);
ins->reg = reg+1;
addstkslotref(
- insertinstr(blk, ++curi, mkinstr(store, 0, .r = mkref(RREG, reg))).i,
+ insertinstr(blk, curi+1, mkinstr(store, 0, .r = mkref(RREG, reg))).i,
alloc->a*8);
}
}