summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-10-19 17:28:21 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-10-19 17:28:21 -0400
commit7c6fadc6ba9d162aa636bd1b92009c522cec5528 (patch)
treea2cdf8518da17ca08ff75fabd552e727c4e7a152
parenta655b8b3ebe77c236048b330ad35ef54a938217e (diff)
downloadroux-7c6fadc6ba9d162aa636bd1b92009c522cec5528.tar.gz
uniformize sign extension and mem loads
-rw-r--r--lisc/emit.c37
-rw-r--r--lisc/isel.c26
-rw-r--r--lisc/lisc.h25
-rw-r--r--lisc/parse.c42
4 files changed, 59 insertions, 71 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index 93ec793..9500dc9 100644
--- 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
index fd2d760..c3da2cf 100644
--- 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
index b7b7c75..d2f6ef2 100644
--- 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
index df153ee..a4cc484 100644
--- 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;