summary refs log tree commit diff
path: root/lisc
diff options
context:
space:
mode:
Diffstat (limited to 'lisc')
-rw-r--r--lisc/emit.c21
-rw-r--r--lisc/isel.c10
-rw-r--r--lisc/lisc.h6
-rw-r--r--lisc/spill.c21
4 files changed, 41 insertions, 17 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index e9887ef..ce39168 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -280,12 +280,28 @@ eins(Ins i, Fn *fn, FILE *f)
 	}
 }
 
+static int
+framesz(Fn *fn)
+{
+	enum { N = sizeof (Fn){0}.svec / sizeof (Fn){0}.svec[0] };
+	int i, a, f;
+
+	f = 0;
+	for (i=N-1, a=1<<i; i>=0; i--, a/=2)
+		if (f == 0 || f - a == fn->svec[i])
+			f = fn->svec[i];
+	a = 1 << (N-2);
+	while (f % (2 * a) != a)
+		f += a - f % a;
+	return f * 16 / (1 << (N-1));
+}
+
 void
 emitfn(Fn *fn, FILE *f)
 {
 	Blk *b, *s;
 	Ins *i;
-	int c;
+	int c, fs;
 
 	fprintf(f,
 		".text\n"
@@ -295,6 +311,9 @@ emitfn(Fn *fn, FILE *f)
 		"\tpush %%rbp\n"
 		"\tmov %%rsp, %%rbp\n"
 	);
+	fs = framesz(fn);
+	if (fs)
+		fprintf(f, "\tsub $%d, %%rsp\n", fs);
 	for (b=fn->start; b; b=b->link) {
 		fprintf(f, ".L%s:\n", b->name);
 		for (i=b->ins; i-b->ins < b->nins; i++)
diff --git a/lisc/isel.c b/lisc/isel.c
index 5fbe8d9..af21bcb 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -357,13 +357,11 @@ seljmp(Blk *b, Fn *fn)
 }
 
 int
-slot_(int sz, int al /* log2 */, Fn *fn)
+slota(int sz, int al /* log2 */, int *sa)
 {
-	enum { N = sizeof fn->slot / sizeof fn->slot[0] };
+	enum { N = sizeof (Fn){0}.svec / sizeof (Fn){0}.svec[0] };
 	int j, k, s, l, a, ret;
-	int *sa;
 
-	sa = fn->slot;
 	a = 1 << al;
 	l = sz;
 
@@ -429,7 +427,7 @@ isel(Fn *fn)
 	/* assign slots to fast allocs */
 	for (n=Tmp0; n<fn->ntmp; n++)
 		fn->tmp[n].spill = 0;
-	memcpy(fn->slot, (int[3]){0, 0, 2}, 3 * sizeof(int));
+	memcpy(fn->svec, (int[3]){0, 0, 2}, 3 * sizeof(int));
 
 	for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
 		if (OAlloc <= i->op && i->op <= OAlloc1) {
@@ -440,7 +438,7 @@ isel(Fn *fn)
 				diag("isel: invalid alloc size");
 			sz = (sz + 3) / 4;
 			al = i->op - OAlloc;
-			s = slot_(sz, al, fn);
+			s = slota(sz, al, fn->svec);
 			fn->tmp[i->to.val].spill = s;
 			i->to = R;
 		}
diff --git a/lisc/lisc.h b/lisc/lisc.h
index a70c7a5..ce32bb5 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -58,7 +58,7 @@ enum Reg {
 
 	Tmp0, /* first non-reg temporary */
 
-	NReg = R11 - RAX + 1
+	NReg = RDX - RAX + 1
 };
 
 #define RWORD(r) (r + (EAX-RAX))
@@ -244,7 +244,7 @@ struct Fn {
 	int ncon;
 	int nblk;
 	Blk **rpo;
-	int slot[3];
+	int svec[3];
 };
 
 
@@ -269,7 +269,7 @@ void ssafix(Fn *, int);
 void filllive(Fn *);
 
 /* isel.c */
-int slot_(int, int, Fn *);
+int slota(int, int, int *);
 void isel(Fn *);
 
 /* spill.c */
diff --git a/lisc/spill.c b/lisc/spill.c
index a407047..5fa54ca 100644
--- a/lisc/spill.c
+++ b/lisc/spill.c
@@ -141,10 +141,10 @@ bcnt(Bits *b) /* glad I can pull it :) */
 }
 
 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 uint ns;  /* current # of spill slots */
+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
 tcmp0(const void *pa, const void *pb)
@@ -170,7 +170,12 @@ slot(int t)
 		diag("spill: cannot spill register");
 	s = tmp[t].spill;
 	if (!s) {
-		s = ++ns;
+		if (tmp[t].type == TWord)
+			s = slota(1, 1, svec);
+		else if (tmp[t].type == TLong)
+			s = slota(2, 2, svec);
+		else
+			diag("spill: unknown type (1)");
 		tmp[t].spill = s;
 	}
 	return SLOT(s);
@@ -189,8 +194,10 @@ store(Ref r, int s)
 {
 	if (tmp[r.val].type == TLong)
 		emit(OStorel, R, r, SLOT(s));
-	else
+	else if (tmp[r.val].type == TWord)
 		emit(OStorew, R, r, SLOT(s));
+	else
+		diag("spill: unknown type (2)");
 }
 
 static int
@@ -293,7 +300,7 @@ spill(Fn *fn)
 	int j, s;
 	Phi *p;
 
-	ns = 0;
+	svec = fn->svec;
 	tmp = fn->tmp;
 	ntmp = fn->ntmp;
 	assert(ntmp < NBit*BITS);