summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--all.h31
-rw-r--r--isel.c3
-rw-r--r--live.c3
-rw-r--r--rega.c20
-rw-r--r--spill.c20
5 files changed, 40 insertions, 37 deletions
diff --git a/all.h b/all.h
index a40627c..1ccf053 100644
--- a/all.h
+++ b/all.h
@@ -29,6 +29,18 @@ typedef struct Typ Typ;
 typedef struct Seg Seg;
 typedef struct Dat Dat;
 
+enum {
+	NString = 32,
+	NPred   = 63,
+	NIns    = 8192,
+	NAlign  = 3,
+	NSeg    = 32,
+	NTyp    = 128,
+	NBit    = CHAR_BIT * sizeof(bits),
+};
+
+#define BIT(n) ((bits)1 << (n))
+
 enum Reg {
 	RXX,
 
@@ -48,8 +60,9 @@ enum Reg {
 	R14,
 	R15,
 
-	RBP, /* reserved */
+	RBP, /* globally live */
 	RSP,
+#define RGLOB (BIT(RBP)|BIT(RSP))
 
 	XMM0, /* sse */
 	XMM1,
@@ -70,7 +83,8 @@ enum Reg {
 
 	Tmp0, /* first non-reg temporary */
 
-	NIReg = R15 - RAX + 1,
+	NRGlob = 2,
+	NIReg = R15 - RAX + 1 + NRGlob,
 	NFReg = XMM14 - XMM0 + 1, /* XMM15 is reserved */
 	NISave = R11 - RAX + 1,
 	NFSave = NFReg,
@@ -78,19 +92,8 @@ enum Reg {
 	NRClob = R15 - RBX + 1,
 };
 
-enum {
-	NString = 32,
-	NPred   = 63,
-	NIns    = 8192,
-	NAlign  = 3,
-	NSeg    = 32,
-	NTyp    = 128,
-	NBit    = CHAR_BIT * sizeof(bits),
-};
-
 MAKESURE(NBit_is_enough, NBit >= (int)Tmp0);
 
-#define BIT(n) ((bits)1 << (n))
 
 struct BSet {
 	uint nt;
@@ -388,7 +391,7 @@ struct Tmp {
 	Use *use;
 	uint ndef, nuse;
 	uint cost;
-	short slot;
+	short slot; /* -1 for unset */
 	short cls;
 	struct {
 		int r;
diff --git a/isel.c b/isel.c
index 0c92dcd..8b4b823 100644
--- a/isel.c
+++ b/isel.c
@@ -149,7 +149,8 @@ fixarg(Ref *r, int k, int phi, Fn *fn)
 		 */
 		r1 = newtmp("isel", Kl, fn);
 		emit(Oaddr, Kl, r1, SLOT(s), R);
-	} else if (rtype(r0) == RMem) {
+	}
+	else if (rtype(r0) == RMem) {
 		/* apple asm fix */
 		m = &fn->mem[r0.val];
 		if (req(m->base, R)) {
diff --git a/live.c b/live.c
index be5ec8c..18c9b63 100644
--- a/live.c
+++ b/live.c
@@ -104,13 +104,14 @@ Again:
 
 		memset(phi, 0, f->ntmp * sizeof phi[0]);
 		memset(nlv, 0, sizeof nlv);
+		b->out->t[0] |= RGLOB;
 		bscopy(b->in, b->out);
 		for (t=0; bsiter(b->in, &t); t++) {
 			phifix(t, phi, f->tmp);
 			nlv[KBASE(f->tmp[t].cls)]++;
 		}
 		if (rtype(b->jmp.arg) == RCall) {
-			assert(bscount(b->in) == 0 && nlv[0] == 0 && nlv[1] == 0);
+			assert(bscount(b->in) == NRGlob && nlv[0] == NRGlob && nlv[1] == 0);
 			b->in->t[0] |= retregs(b->jmp.arg, nlv);
 		} else
 			bset(b->jmp.arg, b, nlv, phi, f->tmp);
diff --git a/rega.c b/rega.c
index fae7538..9f02a63 100644
--- a/rega.c
+++ b/rega.c
@@ -154,9 +154,10 @@ mdump(RMap *m)
 	int i;
 
 	for (i=0; i<m->n; i++)
-		fprintf(stderr, " (%s, R%d)",
-			tmp[m->t[i]].name,
-			m->r[i]);
+		if (m->t[i] >= Tmp0)
+			fprintf(stderr, " (%s, R%d)",
+				tmp[m->t[i]].name,
+				m->r[i]);
 	fprintf(stderr, "\n");
 }
 
@@ -360,15 +361,10 @@ doblk(Blk *b, RMap *cur)
 	Mem *m;
 	Ref *ra[4];
 
+	for (r=0; bsiter(b->out, &r) && r<Tmp0; r++)
+		radd(cur, r, r);
 	if (rtype(b->jmp.arg) == RTmp)
 		b->jmp.arg = ralloc(cur, b->jmp.arg.val);
-	else if (rtype(b->jmp.arg) == RCall) {
-		/* add return registers */
-		rs = retregs(b->jmp.arg, 0);
-		for (r=0; rs; rs/=2, r++)
-			if (rs & 1)
-				radd(cur, r, r);
-	}
 	for (i=&b->ins[b->nins]; i!=b->ins;) {
 		switch ((--i)->op) {
 		case Ocall:
@@ -444,8 +440,8 @@ rega(Fn *fn)
 	bsinit(cur.b, fn->ntmp);
 	bsinit(old.b, fn->ntmp);
 
-	for (t=Tmp0; t<fn->ntmp; t++)
-		*hint(t) = -1;
+	for (t=0; t<fn->ntmp; t++)
+		*hint(t) = t < Tmp0 ? t : -1;
 	for (b=fn->start, i=b->ins; i-b->ins < b->nins; i++)
 		if (i->op != Ocopy || !isreg(i->arg[0]))
 			break;
diff --git a/spill.c b/spill.c
index 5d1726e..5e2b9ec 100644
--- a/spill.c
+++ b/spill.c
@@ -62,7 +62,7 @@ fillcost(Fn *fn)
 		}
 	}
 	for (t=fn->tmp; t-fn->tmp < fn->ntmp; t++) {
-		t->cost = t-fn->tmp < Tmp0 ? 1e6 : 0;
+		t->cost = t-fn->tmp < Tmp0 ? UINT_MAX : 0;
 		t->nuse = 0;
 		t->ndef = 0;
 	}
@@ -107,7 +107,11 @@ static BSet mask[2][1]; /* class masks */
 static int
 tcmp0(const void *pa, const void *pb)
 {
-	return tmp[*(int *)pb].cost - tmp[*(int *)pa].cost;
+	uint ca, cb;
+
+	ca = tmp[*(int *)pa].cost;
+	cb = tmp[*(int *)pb].cost;
+	return (cb < ca) ? -1 : (cb > ca);
 }
 
 static int
@@ -337,9 +341,10 @@ spill(Fn *fn)
 		if (!hd || s2->id >= hd->id)
 			hd = s2;
 		r = 0;
-		bszero(v);
 		if (hd) {
 			/* back-edge */
+			bszero(v);
+			hd->gen->t[0] |= RGLOB; /* don't spill registers */
 			for (k=0; k<2; k++) {
 				n = k == 0 ? NIReg : NFReg;
 				bscopy(u, b->out);
@@ -365,11 +370,8 @@ spill(Fn *fn)
 				bsunion(v, u);
 			}
 			limit2(v, 0, 0, w);
-		} else if (rtype(b->jmp.arg) == RCall) {
-			/* return */
-			r = retregs(b->jmp.arg, 0);
-			v->t[0] |= r;
-		}
+		} else
+			bscopy(v, b->out);
 		for (t=Tmp0; bsiter(b->out, &t); t++)
 			if (!bshas(v, t))
 				slot(t);
@@ -447,7 +449,7 @@ spill(Fn *fn)
 			if (r)
 				sethint(v, r);
 		}
-		assert(!r || b==fn->start);
+		assert(!(r & ~RGLOB) || b==fn->start);
 
 		for (p=b->phi; p; p=p->link) {
 			assert(rtype(p->to) == RTmp);