summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lisc/emit.c22
-rw-r--r--lisc/isel.c16
-rw-r--r--lisc/lisc.h4
-rw-r--r--lisc/rega.c2
-rw-r--r--lisc/slot.txt4
-rw-r--r--lisc/spill.c46
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;
 }