commit d8d17705c4f525314471f5526ef3328dd41625cd
parent 1a78659dfab54d808fbc568d6b7ff5e4012695c0
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Fri, 31 Jul 2015 10:21:10 -0400
clean the commutativity + fix bug in emit
The commutativity information only makes sense for
arithmetic expressions. To account for that, I introduced
a new tri-valued boolean type B3. Memory operations, for
example, will receive an undefined commutativity trit.
The code emitter was buggy when rega emitted instructions
like 'rax = add 1, rax', this is now fixed using the
commutativity information (we rewrite it in 'rax = add
rax, 1').
Diffstat:
5 files changed, 28 insertions(+), 16 deletions(-)
diff --git a/lisc/emit.c b/lisc/emit.c
@@ -57,6 +57,15 @@ eins(Ins i, Fn *fn, FILE *f)
switch (i.op) {
case OAdd:
case OSub:
+ if (req(i.to, i.arg[1]))
+ switch (opdesc[i.op].comm) {
+ case T:
+ i.arg[1] = i.arg[0];
+ i.arg[0] = i.to;
+ break;
+ default:
+ diag("emit: instruction can't be encoded");
+ }
if (!req(i.to, i.arg[0]))
eop("mov", i.arg[0], i.to, fn, f);
eop(opi[i.op], i.arg[1], i.to, fn, f);
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -16,6 +16,8 @@ typedef struct Sym Sym;
typedef struct Const Const;
typedef struct Fn Fn;
+typedef enum { U, F, T } B3;
+
enum {
RAX = 1,
RCX,
@@ -105,9 +107,9 @@ enum {
};
struct OpDesc {
- int arity;
- uint commut:1;
char *name;
+ int arity;
+ B3 comm;
};
struct Ins {
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -13,17 +13,18 @@ enum {
Ins insb[NIns], *curi;
OpDesc opdesc[OLast] = {
- [OAdd] = { 2, 1, "add" },
- [OSub] = { 2, 0, "sub" },
- [ODiv] = { 2, 0, "div" },
- [ORem] = { 2, 0, "rem" },
- [OStore] = { 2, 0, "store" },
- [OLoad] = { 1, 0, "load" },
- [ONop] = { 0, 0, "nop" },
- [OCopy] = { 1, 0, "copy" },
- [OSwap] = { 2, 1, "swap" },
- [OIADiv] = { 1, 0, "iadiv" },
- [OIACltd] = { 0, 0, "iacltd" },
+ /* 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 },
+ [OIADiv] = { "iadiv", 1, U },
+ [OIACltd] = { "iacltd", 0, U },
};
typedef enum {
diff --git a/lisc/rega.c b/lisc/rega.c
@@ -350,11 +350,11 @@ rega(Fn *fn)
* situation
* eax = sub ebx, eax
*/
- if (!opdesc[i->op].commut && r)
+ if (opdesc[i->op].comm == F && r)
BSET(cur.br, r);
t = i->arg[1].val;
i->arg[1] = ralloc(&cur, t);
- if (!opdesc[i->op].commut && r)
+ if (opdesc[i->op].comm == F && r)
BCLR(cur.br, r);
}
}
diff --git a/lisc/spill.c b/lisc/spill.c
@@ -355,7 +355,7 @@ spill(Fn *fn)
w = (Bits){{0}};
if (rtype(i->arg[1]) == RSym
&& !req(i->to, R)
- && !opdesc[i->op].commut) {
+ && opdesc[i->op].comm == F) {
/* <arch>
* here we make sure that we
* will never have to compile