commit 7c6fadc6ba9d162aa636bd1b92009c522cec5528
parent a655b8b3ebe77c236048b330ad35ef54a938217e
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Mon, 19 Oct 2015 17:28:21 -0400
uniformize sign extension and mem loads
Diffstat:
4 files changed, 59 insertions(+), 71 deletions(-)
diff --git a/lisc/emit.c b/lisc/emit.c
@@ -152,13 +152,13 @@ eins(Ins i, Fn *fn, FILE *f)
[OSub] = "sub",
[OMul] = "imul",
[OAnd] = "and",
- [OSext] = "movsl",
- [OZext] = "movzl",
- [OLoad] = "mov",
- [OLoadsh] = "movsw",
- [OLoaduh] = "movzw",
- [OLoadsb] = "movsb",
- [OLoadub] = "movzb",
+ [OLoad+Tl] = "mov",
+ [OLoad+Tsw] = "movsl",
+ /* [OLoad+Tuw] treated manually */
+ [OLoad+Tsh] = "movsw",
+ [OLoad+Tuh] = "movzw",
+ [OLoad+Tsb] = "movsb",
+ [OLoad+Tub] = "movzb",
};
Ref r0, r1;
int64_t val;
@@ -197,11 +197,6 @@ eins(Ins i, Fn *fn, FILE *f)
emitf(fn, f, "%s%w %R, %R", otoa[i.op],
i.wide, i.arg[1], i.to);
break;
- case OSext:
- case OZext:
- emitf(fn, f, "%sq %R, %W%R", otoa[i.op],
- i.arg[0], i.wide, i.to);
- break;
case OCopy:
if (req(i.to, R) || req(i.arg[0], R))
break;
@@ -223,11 +218,19 @@ eins(Ins i, Fn *fn, FILE *f)
emitf(fn, f, "mov%t %R, %M",
i.op - OStorel, i.arg[0], i.arg[1]);
break;
- case OLoad:
- case OLoadsh:
- case OLoaduh:
- case OLoadsb:
- case OLoadub:
+ case OLoad+Tuw:
+ emitf(fn, f, "movl %M, %R", i.arg[0], i.to);
+ break;
+ case OLoad+Tsw:
+ if (i.wide == 0) {
+ emitf(fn, f, "movl %M, %R", i.arg[0], i.to);
+ break;
+ }
+ case OLoad+Tl:
+ case OLoad+Tsh:
+ case OLoad+Tuh:
+ case OLoad+Tsb:
+ case OLoad+Tub:
emitf(fn, f, "%s%w %M, %R", otoa[i.op],
i.wide, i.arg[0], i.to);
break;
diff --git a/lisc/isel.c b/lisc/isel.c
@@ -117,8 +117,7 @@ sel(Ins i, Fn *fn)
case OCall:
case OSAlloc:
case OCopy:
- case OSext:
- case OZext:
+ case_OExt:
n = 0;
goto Emit;
case OAdd:
@@ -138,11 +137,7 @@ sel(Ins i, Fn *fn)
}
n = i.op == OStorel;
goto Emit;
- case OLoad:
- case OLoadsh:
- case OLoaduh:
- case OLoadsb:
- case OLoadub:
+ case_OLoad:
if (cpy[0].s != -1) {
i.arg[0] = SLOT(cpy[0].s);
cpy[0].s = -1;
@@ -185,6 +180,10 @@ Emit:
}
break;
default:
+ if (OExt <= i.op && i.op <= OExt1)
+ goto case_OExt;
+ if (OLoad <= i.op && i.op <= OLoad1)
+ goto case_OLoad;
if (OCmp <= i.op && i.op <= OCmp1) {
c = i.op - OCmp;
if (rtype(i.arg[0]) == RCon)
@@ -209,23 +208,20 @@ flagi(Ins *i0, Ins *i)
default:
if (OCmp <= i->op && i->op <= OCmp1)
return i;
+ if (OExt <= i->op && i->op <= OExt1)
+ continue;
+ if (OLoad <= i->op && i->op <= OLoad1)
+ continue;
return 0;
case OAdd: /* flag-setting */
case OSub:
case OAnd:
return i;
case OCopy: /* flag-transparent */
- case OSext:
- case OZext:
case OStorel:
case OStorew:
case OStoreb:
- case OStores:
- case OLoad:
- case OLoadsh:
- case OLoaduh:
- case OLoadsb:
- case OLoadub:;
+ case OStores:;
}
return 0;
}
diff --git a/lisc/lisc.h b/lisc/lisc.h
@@ -102,15 +102,17 @@ static inline int isreg(Ref r)
#define CMPS(X) \
X(eq) X(sle) X(slt) \
X(sgt) X(sge) X(ne) /* mirror opposite cmps! */
+#define COP(c) (c==Ceq||c==Cne ? c : NCmp-1 - c)
-enum Cmp {
-#define C(c) C##c,
- CMPS(C)
-#undef C
- NCmp
-};
+#define X(c) C##c,
+enum Cmp { CMPS(X) NCmp };
+#undef X
-#define COP(c) (c==Ceq||c==Cne ? c : NCmp-1 - c)
+#define TYS(X) X(l) X(sw) X(uw) X(sh) X(uh) X(sb) X(ub)
+
+#define X(t) T##t,
+enum Ty { TYS(X) NTy };
+#undef X
enum Op {
OXXX,
@@ -122,8 +124,6 @@ enum Op {
ORem,
OMul,
OAnd,
- OSext,
- OZext,
OCmp,
OCmp1 = OCmp + NCmp-1,
OStorel,
@@ -131,10 +131,9 @@ enum Op {
OStores,
OStoreb,
OLoad,
- OLoadsh,
- OLoaduh,
- OLoadsb,
- OLoadub,
+ OLoad1 = OLoad + NTy-1,
+ OExt,
+ OExt1 = OExt + NTy-1,
OAlloc,
OAlloc1 = OAlloc + NAlign-1,
OCopy,
diff --git a/lisc/parse.c b/lisc/parse.c
@@ -1,13 +1,6 @@
-/* really crude parser
- */
#include "lisc.h"
#include <ctype.h>
-enum {
- NTmp = 256,
- NCon = 256,
-};
-
OpDesc opdesc[NOp] = {
/* NAME NM */
[OAdd] = { "add", 2 },
@@ -16,17 +9,10 @@ OpDesc opdesc[NOp] = {
[ORem] = { "rem", 2 },
[OMul] = { "mul", 2 },
[OAnd] = { "and", 2 },
- [OSext] = { "sext", 1 },
- [OZext] = { "zext", 1 },
[OStorel] = { "storel", 0 },
[OStorew] = { "storew", 0 },
[OStores] = { "stores", 0 },
[OStoreb] = { "storeb", 0 },
- [OLoad] = { "load", 0 },
- [OLoadsh] = { "loadsh", 0 },
- [OLoaduh] = { "loaduh", 0 },
- [OLoadsb] = { "loadsb", 0 },
- [OLoadub] = { "loadub", 0 },
[OCopy] = { "copy", 1 },
[ONop] = { "nop", 0 },
[OSwap] = { "swap", 2 },
@@ -46,6 +32,12 @@ OpDesc opdesc[NOp] = {
[OAlloc+1] = { "alloc8", 1 },
[OAlloc+2] = { "alloc16", 1 },
+#define X(t) \
+ [OLoad+T##t] = { "load" #t, 0 }, \
+ [OExt+T##t] = { "ext" #t, 1 },
+ TYS(X)
+#undef X
+
#define X(c) \
[OCmp+C##c] = { "c" #c, 0 }, \
[OXSet+C##c] = { "xset" #c, 0 },
@@ -104,8 +96,8 @@ static struct {
} tokval;
static int lnum;
-static Tmp tmp[NTmp];
-static Con con[NCon] = {[0] = {.type = CNum}};
+static Tmp *tmp;
+static Con *con;
static int ntmp;
static int ncon;
static Phi **plink;
@@ -148,6 +140,7 @@ lex()
{ "b", TB },
{ "d", TD },
{ "s", TS },
+ { "loadw", OLoad+Tsw }, /* for convenience */
{ 0, TXXX }
};
static char tok[NString];
@@ -313,8 +306,7 @@ tmpref(char *v, int use)
for (t=Tmp0; t<ntmp; t++)
if (strcmp(v, tmp[t].name) == 0)
goto Found;
- if (ntmp++ >= NTmp)
- err("too many temporaries");
+ vgrow(&tmp, ++ntmp);
strcpy(tmp[t].name, v);
Found:
tmp[t].ndef += !use;
@@ -344,8 +336,7 @@ parseref()
&& con[i].val == c.val
&& strcmp(con[i].label, c.label) == 0)
return CON(i);
- if (ncon++ >= NCon)
- err("too many constants");
+ vgrow(&con, ++ncon);
con[i] = c;
return CON(i);
default:
@@ -601,12 +592,13 @@ parsefn()
curb = 0;
nblk = 0;
curi = insb;
+ tmp = vnew(ntmp, sizeof tmp[0]);
+ con = vnew(ncon, sizeof con[0]);
+ con[0].type = CNum;
fn = alloc(sizeof *fn);
blink = &fn->start;
for (i=0; i<NBlk; i++)
bmap[i] = 0;
- for (i=Tmp0; i<NTmp; i++)
- tmp[i] = (Tmp){.name = ""};
if (peek() != TGlo)
rcls = parsecls(&fn->retty);
else
@@ -625,10 +617,8 @@ parsefn()
err("empty file");
if (curb->jmp.type == JXXX)
err("last block misses jump");
- fn->tmp = vnew(ntmp, sizeof tmp[0]);
- memcpy(fn->tmp, tmp, ntmp * sizeof tmp[0]);
- fn->con = vnew(ncon, sizeof con[0]);
- memcpy(fn->con, con, ncon * sizeof con[0]);
+ fn->tmp = tmp;
+ fn->con = con;
fn->ntmp = ntmp;
fn->ncon = ncon;
fn->nblk = nblk;