summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/isel.c88
-rw-r--r--lisc/lisc.h2
-rw-r--r--lisc/slot.txt33
3 files changed, 52 insertions, 71 deletions
diff --git a/lisc/isel.c b/lisc/isel.c
index 3887114..aa3c521 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -341,60 +341,6 @@ seljmp(Blk *b, Fn *fn)
 	b->jmp.type = JXJc + Cne;
 }
 
-int
-slota(int sz, int al /* log2 */, int *sa)
-{
-	int j, k, s, l, a, ret;
-
-	a = 1 << al;
-	l = sz;
-
-	if (l > a) {
-		/* for large slots, we just
-		 * tack them on the next max
-		 * alignment slot available
-		 * todo, could sophisticate
-		 */
-		l = (l + a-1) & ~(a-1);
-		s = sa[NAlign-1] + l;
-		ret = s;
-		for (j=0, k=1; j<NAlign; j++, k*=2) {
-			l = (l + k-1) & ~(k-1);
-			sa[j] = sa[NAlign-1] + l;
-		}
-	} else {
-		j = al;
-		s = sa[j] + a;
-		ret = s;
-	Shift:
-		if (j < NAlign-1 && s < sa[j+1])
-			/* ........-----------...
-			 * ^       ^          ^
-			 * sa[j]  sa[j]+a    sa[j+1]
-			 *
-			 * we have to skip to the
-			 * next large whole
-			 */
-			s = sa[j+1];
-
-		for (k=0; k<=j; k++)
-			/* move all smaller holes
-			 * that we contain with us
-			 */
-			if (sa[k] == sa[j])
-				sa[k] = s;
-
-		if (j < NAlign-1 && s > sa[j+1]) {
-			/* we were in a bigger hole,
-			 * it needs to shift further
-			 */
-			s = sa[++j] + (a *= 2);
-			goto Shift;
-		}
-	}
-	return ret;
-}
-
 typedef struct AClass AClass;
 
 struct AClass {
@@ -693,8 +639,8 @@ isel(Fn *fn)
 	int64_t sz;
 
 	for (n=Tmp0; n<fn->ntmp; n++)
-		fn->tmp[n].spill = 0;
-	memset(fn->svec, 0, sizeof fn->svec);
+		fn->tmp[n].spill = -1;
+	fn->stk0 = 0;
 
 	/* lower arguments */
 	for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
@@ -735,20 +681,22 @@ isel(Fn *fn)
 	}
 
 	/* assign slots to fast allocs */
-	for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
-		if (OAlloc <= i->op && i->op <= OAlloc1) {
-			if (rtype(i->arg[0]) != RCon)
-				break;
-			sz = fn->con[i->arg[0].val].val;
-			if (sz < 0 || sz >= INT_MAX-3)
-				diag("isel: invalid alloc size");
-			n = 16 / (1 << (NAlign-1));
-			sz = (sz + n-1) / n;
-			al = i->op - OAlloc;
-			s = slota(sz, al, fn->svec);
-			fn->tmp[i->to.val].spill = s;
-			i->to = R;
-		}
+	b = fn->start;
+	assert(NAlign == 3 && "change n=4 and sz /= 4 below");
+	for (al=OAlloc, n=4; al<=OAlloc1; al++, n*=2)
+		for (i=b->ins; i-b->ins < b->nins; i++)
+			if (i->op == al) {
+				if (rtype(i->arg[0]) != RCon)
+					break;
+				sz = fn->con[i->arg[0].val].val;
+				if (sz < 0 || sz >= INT_MAX-3)
+					diag("isel: invalid alloc size");
+				sz = (sz + n-1) & -n;
+				sz /= 4;
+				fn->tmp[i->to.val].spill = fn->stk0;
+				fn->stk0 -= sz;
+				i->to = R;
+			}
 
 	for (b=fn->start; b; b=b->link) {
 		for (sb=(Blk*[3]){b->s1, b->s2, 0}; *sb; sb++)
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 127aa78..dcc3652 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -249,7 +249,7 @@ struct Fn {
 	int retty;
 	Blk **rpo;
 	ulong reg;
-	int svec[NAlign];
+	int stk0, stk1;
 	char name[NString];
 };
 
diff --git a/lisc/slot.txt b/lisc/slot.txt
new file mode 100644
index 0000000..4eec245
--- /dev/null
+++ b/lisc/slot.txt
@@ -0,0 +1,33 @@
+Plan for new slot computations:
+
+- reverse the allocation of all stack slots
+  so that isel slots go below spill locations
+- the fast allocs must be allocated by decreasing
+  alignment constraints
+- instead of the svec vector, we simply need two
+  numbers that contain the size of both the locals
+  and spills (stk0, stk1)
+- maybe it's time to include small alignments
+- use Tmp.spill == -1 to mark unallocated slots
+
+Layout:
+
+  ---------- rbp = 0 [16]
+  | << padding 1 >>
+  | .. spills   ..
+  |                <- enforce align 16
+  | .. align 16 ..
+  | .. align  8 ..
+  | .. align  4 ..
+  | << padding 0 >>
+  ---------- rsp = 0 [16]
+
+  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
+
+Examples:
+
+  if the first local is aligned 4 of size 4, its slot
+  number will be set 0, to emit the proper offset to