commit 76bf96b2682190686e2f570405ae8762a8791c55
parent 9966a181c13928bd145ee35a945520f94c3cd61d
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Sat, 8 Aug 2015 18:06:47 -0400
add nmem to opdesc for use in the spiller
This new machine-independent mechanism might not be general
enough in the long term but, now, it provides a flexible way
to inform the spiller about the maximum number of arguments
of an instruction that can be spill locations.
Diffstat:
4 files changed, 36 insertions(+), 34 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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]);