summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lisc/emit.c2
-rw-r--r--lisc/lisc.h2
-rw-r--r--lisc/parse.c38
-rw-r--r--lisc/spill.c28
4 files changed, 36 insertions, 34 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index 5ea9a3f..0a13676 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -158,8 +158,6 @@ eins(Ins i, Fn *fn, FILE *f)
 				eop("add", i.arg[0], i.to, fn, f);
 				break;
 			}
-			if (opdesc[i.op].comm != T)
-				diag("emit: unhandled instruction (1)");
 			i.arg[1] = i.arg[0];
 			i.arg[0] = i.to;
 		}
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 1a711ca..44115aa 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -161,7 +161,7 @@ enum {
 struct OpDesc {
 	char *name;
 	int arity;
-	B3 comm;
+	int nmem;
 };
 
 struct Ins {
diff --git a/lisc/parse.c b/lisc/parse.c
index eca9d1d..4f4a850 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -11,24 +11,30 @@ enum {
 Ins insb[NIns], *curi;
 
 OpDesc opdesc[OLast] = {
-	/*            NAME  ARTY  C */
-	[OAdd]    = { "add",   2, T },
-	[OSub]    = { "sub",   2, F },
-	[ODiv]    = { "div",   2, U },
-	[ORem]    = { "rem",   2, U },
-	[OStore]  = { "store", 2, U },
-	[OLoad]   = { "load",  1, U },
-	[ONop]    = { "nop",   0, U },
-	[OCopy]   = { "copy",  1, U },
-	[OSwap]   = { "swap",  2, T },
-	[OSign]   = { "sign",  1, U },
-	[OXDiv]   = { "xdiv",  1, U },
-	[OXCmpw]  = { "xcmpw", 2, U },
-	[OXCmpl]  = { "xcmpl", 2, U },
+	/*            NAME   ARTY NM */
+	[OAdd]    = { "add",    2, 2 },
+	[OSub]    = { "sub",    2, 2 },
+	[ODiv]    = { "div",    2, 2 },
+	[ORem]    = { "rem",    2, 2 },
+	[OStore]  = { "store",  2, 0 },
+	[OStores] = { "stores", 2, 0 },
+	[OStoreb] = { "storeb", 2, 0 },
+	[OLoad]   = { "load",   1, 0 },
+	[OLoadss] = { "loadss", 1, 0 },
+	[OLoadus] = { "loadus", 1, 0 },
+	[OLoadsb] = { "loadsb", 1, 0 },
+	[OLoadub] = { "loadub", 1, 0 },
+	[ONop]    = { "nop",    0, 0 },
+	[OCopy]   = { "copy",   1, 1 },
+	[OSwap]   = { "swap",   2, 2 },
+	[OSign]   = { "sign",   1, 0 },
+	[OXDiv]   = { "xdiv",   1, 1 },
+	[OXCmpw]  = { "xcmpw",  2, 1 },
+	[OXCmpl]  = { "xcmpl",  2, 1 },
 
 	#define X(c)                        \
-	[OCmp+C##c]  = { "c"    #c, 2, U }, \
-	[OXSet+C##c] = { "xset" #c, 0, U }
+	[OCmp+C##c]  = { "c"    #c, 2, 0 }, \
+	[OXSet+C##c] = { "xset" #c, 0, 0 }
 
 	X(eq), X(sle), X(slt), X(sgt), X(sge), X(ne),
 	#undef X
diff --git a/lisc/spill.c b/lisc/spill.c
index 3ca297a..14b33c5 100644
--- a/lisc/spill.c
+++ b/lisc/spill.c
@@ -223,7 +223,7 @@ limit(Bits *b, int k, Bits *fst)
 	return t;
 }
 
-static void
+static int
 setloc(Ref *pr, Bits *v, Bits *w)
 {
 	int t;
@@ -242,7 +242,7 @@ setloc(Ref *pr, Bits *v, Bits *w)
 		BSET(br, pr->val);
 	}
 	if (rtype(*pr) != RTmp)
-		return;
+		return 0;
 	t = pr->val;
 	BSET(*v, t);
 	if (limit(v, nreg, w) == t)
@@ -250,10 +250,13 @@ setloc(Ref *pr, Bits *v, Bits *w)
 		 * it was not live so we don't
 		 * have to reload it */
 		curi++;
-	if (!BGET(*v, t))
+	if (!BGET(*v, t)) {
 		*pr = slot(t);
-	else
+		return 1;
+	} else {
 		BSET(*w, t);
+		return 0;
+	}
 }
 
 /* spill code insertion
@@ -361,18 +364,13 @@ spill(Fn *fn)
 			case -1:;
 			}
 			w = (Bits){{0}};
-			setloc(&i->arg[0], &v, &w);
-			if (i->op == OXCmpw || i->op == OXCmpl)
-			if (rtype(i->arg[0]) == RSlot) {
-				/* <arch>
-				 * we make sure that comparisons
-				 * do not get their two operands
-				 * in memory slots
-				 */
-				assert(rtype(i->arg[1]) == RTmp);
+			j = opdesc[i->op].nmem;
+			if (!j && rtype(i->arg[0]) == RTmp)
+				BSET(w, i->arg[0].val);
+			j -= setloc(&i->arg[0], &v, &w);
+			if (!j && rtype(i->arg[1]) == RTmp)
 				BSET(w, i->arg[1].val);
-			}
-			setloc(&i->arg[1], &v, &w);
+			j -= setloc(&i->arg[1], &v, &w);
 			if (s)
 				emit(OStore, R, i->to, SLOT(s));
 			emit(i->op, i->to, i->arg[0], i->arg[1]);