diff options
-rw-r--r-- | lisc/emit.c | 22 | ||||
-rw-r--r-- | lisc/isel.c | 16 | ||||
-rw-r--r-- | lisc/lisc.h | 4 | ||||
-rw-r--r-- | lisc/rega.c | 2 | ||||
-rw-r--r-- | lisc/slot.txt | 4 | ||||
-rw-r--r-- | lisc/spill.c | 46 |
6 files changed, 59 insertions, 35 deletions
diff --git a/lisc/emit.c b/lisc/emit.c index 2e81862..8492a71 100644 --- a/lisc/emit.c +++ b/lisc/emit.c @@ -83,8 +83,10 @@ Next: break; case RSlot: Slot: { - struct { int i:14; } x = {ref.val}; /* fixme, HACK */ - fprintf(f, "%d(%%rbp)", -4 * x.i); + struct { int i:14; } x = {ref.val}; /* fixme */ + assert(NAlign == 3); + assert(fn->slot >= x.i); + fprintf(f, "%d(%%rbp)", -4 * (fn->slot - x.i)); break; } case RCon: @@ -289,19 +291,15 @@ eins(Ins i, Fn *fn, FILE *f) static int framesz(Fn *fn) { - int i, o, a, f; + int i, o, f; + assert(NAlign == 3); for (i=0, o=0; i<NRClob; i++) o ^= 1 & (fn->reg >> rclob[i]); - f = 0; - for (i=NAlign-1, a=1<<i; i>=0; i--, a/=2) - if (f == 0 || f - a == fn->svec[i]) - f = fn->svec[i]; - a = 1 << (NAlign-2); - o *= a; - while ((f + o) % (2 * a)) - f += a - f % a; - return f * 16 / (1 << (NAlign-1)); + f = fn->slot; + if (f & 3) + f += 4 - (f & 3); + return 4*f + 8*o; } void diff --git a/lisc/isel.c b/lisc/isel.c index 181f73a..83617d2 100644 --- a/lisc/isel.c +++ b/lisc/isel.c @@ -118,7 +118,7 @@ sel(Ins i, Fn *fn) r0 = i.arg[n]; cpy[n].s = -1; s = rslot(r0, fn); - if (s >= 0) { + if (s != -1) { r0 = newtmp(fn); i.arg[n] = r0; cpy[n].r = r0; @@ -172,7 +172,7 @@ sel(Ins i, Fn *fn) case OStorew: case OStoreb: case OStores: - if (cpy[1].s >= 0) { + if (cpy[1].s != -1) { i.arg[1] = SLOT(cpy[1].s); cpy[1].s = -1; } @@ -183,7 +183,7 @@ sel(Ins i, Fn *fn) case OLoaduh: case OLoadsb: case OLoadub: - if (cpy[0].s >= 0) { + if (cpy[0].s != -1) { i.arg[0] = SLOT(cpy[0].s); cpy[0].s = -1; } @@ -237,7 +237,7 @@ Emit: } for (n=0; n<2; n++) - if (cpy[n].s >= 0) + if (cpy[n].s != -1) emit(OAddr, 1, cpy[n].r, SLOT(cpy[n].s), R); } @@ -638,7 +638,7 @@ isel(Fn *fn) for (n=Tmp0; n<fn->ntmp; n++) fn->tmp[n].spill = -1; - fn->stk0 = 0; + fn->slot = 0; /* lower arguments */ for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++) @@ -691,8 +691,8 @@ isel(Fn *fn) diag("isel: invalid alloc size"); sz = (sz + n-1) & -n; sz /= 4; - fn->tmp[i->to.val].spill = fn->stk0; - fn->stk0 -= sz; + fn->tmp[i->to.val].spill = fn->slot; + fn->slot += sz; *i = (Ins){.op = ONop}; } @@ -702,7 +702,7 @@ isel(Fn *fn) for (a=0; p->blk[a] != b; a++) assert(a+1 < p->narg); s = rslot(p->arg[a], fn); - if (s >= 0) { + if (s != -1) { p->arg[a] = newtmp(fn); emit(OAddr, 1, p->arg[a], SLOT(s), R); } diff --git a/lisc/lisc.h b/lisc/lisc.h index 0f4b507..05099ff 100644 --- a/lisc/lisc.h +++ b/lisc/lisc.h @@ -44,7 +44,7 @@ enum Reg { Tmp0, /* first non-reg temporary */ - NReg = R12 - RAX + 1, + NReg = RDX - RAX + 1, NRSave = 9, NRClob = 5, }; @@ -249,7 +249,7 @@ struct Fn { int retty; Blk **rpo; ulong reg; - int stk0, stk1; + int slot; char name[NString]; }; diff --git a/lisc/rega.c b/lisc/rega.c index c9d726a..48dc636 100644 --- a/lisc/rega.c +++ b/lisc/rega.c @@ -48,7 +48,7 @@ rref(RMap *m, int t) r = rfind(m, t); if (r == -1) { s = tmp[t].spill; - assert(s && "should have spilled"); + assert(s != -1 && "should have spilled"); return SLOT(s); } else return TMP(r); diff --git a/lisc/slot.txt b/lisc/slot.txt index b8fdf31..9212cde 100644 --- a/lisc/slot.txt +++ b/lisc/slot.txt @@ -33,8 +33,8 @@ Layout: padding 0: inserted at last minute by the code emitter to respect the ABI - padding 1: inserted at the beginning of spill - it can be 4 or 0 + padding 1: inserted at the end of spill it can + be 4 or 0 Examples: diff --git a/lisc/spill.c b/lisc/spill.c index 36b08cd..d78136e 100644 --- a/lisc/spill.c +++ b/lisc/spill.c @@ -143,7 +143,9 @@ extern Ins insb[NIns], *curi; /* shared work buffer */ static Bits *f; /* temps to prioritize in registers (for tcmp1) */ static Tmp *tmp; /* current temporaries (for tcmpX) */ static int ntmp; /* current # of temps (for limit) */ -static int *svec; /* free slots vector */ +static int locs; /* stack size used by locals */ +static int slot4; /* next slot of 4 bytes */ +static int slot8; /* ditto, 8 bytes */ static int tcmp0(const void *pa, const void *pb) @@ -168,11 +170,28 @@ slot(int t) if (t < Tmp0) diag("spill: cannot spill register"); s = tmp[t].spill; - if (!s) { - if (tmp[t].wide) - s = slota(2, 1, svec); - else - s = slota(1, 0, svec); + if (s == -1) { + assert(NAlign == 3); + /* nice logic to pack stack slots + * on demand, there can be only + * one hole and slot4 points to it + * + * invariant: slot4 <= slot8 + */ + if (tmp[t].wide) { + s = slot8; + if (slot4 == slot8) + slot4 += 2; + slot8 += 2; + } else { + s = slot4; + if (slot4 == slot8) { + slot8 += 2; + slot4 += 1; + } else + slot4 = slot8; + } + s += locs; tmp[t].spill = s; } return SLOT(s); @@ -312,9 +331,11 @@ spill(Fn *fn) int j, s; Phi *p; - svec = fn->svec; tmp = fn->tmp; ntmp = fn->ntmp; + locs = fn->slot; + slot4 = 0; + slot8 = 0; assert(ntmp < NBit*BITS); for (b=fn->start; b; b=b->link) { @@ -382,7 +403,7 @@ spill(Fn *fn) i = dopm(b, i, &v); continue; } - s = 0; + s = -1; w = (Bits){{0}}; if (!req(i->to, R)) { assert(rtype(i->to) == RTmp); @@ -400,7 +421,7 @@ spill(Fn *fn) if (!j && rtype(i->arg[1]) == RTmp) BSET(w, i->arg[1].val); j -= setloc(&i->arg[1], &v, &w); - if (s) + if (s != -1) store(i->to, s); emit(*i); } @@ -411,7 +432,7 @@ spill(Fn *fn) if (BGET(v, t)) { BCLR(v, t); s = tmp[t].spill; - if (s) + if (s != -1) store(p->to, s); } else p->to = slot(p->to.val); @@ -422,4 +443,9 @@ spill(Fn *fn) b->ins = alloc(b->nins * sizeof(Ins)); memcpy(b->ins, curi, b->nins * sizeof(Ins)); } + + /* align the locals to a 16 byte boundary */ + assert(NAlign == 3); + slot8 += slot8 & 3; + fn->slot += slot8; } |