summary refs log tree commit diff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-08-07 16:01:07 -0400
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2015-09-15 23:01:30 -0400
commite65a615c903c96eaaad17a05e83d1d763cc21675 (patch)
treee6596e00623620092f727d02c63f05b887797e9f
parentad012e9d558138b61881156ab8b31e74cd759825 (diff)
downloadroux-e65a615c903c96eaaad17a05e83d1d763cc21675.tar.gz
jez becomes jnz, complete cmp+jmp contraction
-rw-r--r--lisc/emit.c40
-rw-r--r--lisc/isel.c72
-rw-r--r--lisc/lisc.h2
-rw-r--r--lisc/parse.c14
-rw-r--r--lisc/test/alt.ssa6
-rw-r--r--lisc/test/cup.ssa2
-rw-r--r--lisc/test/eucl.ssa2
-rw-r--r--lisc/test/fix1.ssa2
-rw-r--r--lisc/test/fix2.ssa4
-rw-r--r--lisc/test/live.ssa2
-rw-r--r--lisc/test/loop.ssa2
-rw-r--r--lisc/test/rpo.ssa4
12 files changed, 77 insertions, 75 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index c1fd49a..ad48a27 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -73,6 +73,20 @@ static char *ctoa[NCmp] = {
 	[Cne] = "ne",
 };
 
+static int
+cneg(int cmp)
+{
+	switch (cmp) {
+	default:   diag("cneg: unhandled comparison");
+	case Ceq:  return Cne;
+	case Csle: return Csgt;
+	case Cslt: return Csge;
+	case Csgt: return Csle;
+	case Csge: return Cslt;
+	case Cne:  return Ceq;
+	}
+}
+
 static void
 eref(Ref r, Fn *fn, FILE *f)
 {
@@ -187,9 +201,9 @@ eins(Ins i, Fn *fn, FILE *f)
 void
 emitfn(Fn *fn, FILE *f)
 {
-	char *js;
 	Blk *b, *s;
 	Ins *i;
+	int c;
 
 	fprintf(f,
 		".text\n"
@@ -216,19 +230,19 @@ emitfn(Fn *fn, FILE *f)
 			if (b->s1 != b->link)
 				fprintf(f, "\tjmp .L%s\n", b->s1->name);
 			break;
-		case JJez:
-			if (b->s1 == b->link) {
-				js = "jne";
-				s = b->s2;
-			} else if (b->s2 == b->link) {
-				js = "je";
-				s = b->s1;
-			} else
-				diag("emit: unhandled jump (1)");
-			eop("cmp $0,", b->jmp.arg, R, fn, f);
-			fprintf(f, "\t%s .L%s\n", js, s->name);
-			break;
 		default:
+			c = b->jmp.type - JXJc;
+			if (0 <= c && c <= NCmp) {
+				if (b->link == b->s2) {
+					s = b->s1;
+				} else if (b->link == b->s1) {
+					c = cneg(c);
+					s = b->s2;
+				} else
+					diag("emit: unhandled jump (1)");
+				fprintf(f, "\tj%s .L%s\n", ctoa[c], s->name);
+				break;
+			}
 			diag("emit: unhandled jump (2)");
 		}
 	}
diff --git a/lisc/isel.c b/lisc/isel.c
index db5cb92..7feb6f7 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -40,20 +40,6 @@ newtmp(int type, Fn *fn)
 }
 
 static int
-cneg(int cmp)
-{
-	switch (cmp) {
-	default:   diag("cneg: unhandled comparison");
-	case Ceq:  return Cne;
-	case Csle: return Csgt;
-	case Cslt: return Csge;
-	case Csgt: return Csle;
-	case Csge: return Cslt;
-	case Cne:  return Ceq;
-	}
-}
-
-static int
 islong(Ref r, Fn *fn)
 {
 	return rtype(r) == RTmp && fn->tmp[r.val].type == TLong;
@@ -131,6 +117,8 @@ sel(Ins i, Fn *fn)
 	case OCopy:
 		emit(i.op, i.to, i.arg[0], i.arg[1]);
 		break;
+	case ONop:
+		break;
 	default:
 		if (OCmp <= i.op && i.op <= OCmp1) {
 			c = i.op - OCmp;
@@ -150,6 +138,9 @@ flagi(Ins *i0, Ins *i)
 	while (i>i0)
 		switch ((--i)->op) {
 		default:
+			return 0;
+		case OAdd: /* <arch> */
+		case OSub:
 			return i;
 		case OCopy:
 		case OStore:
@@ -158,51 +149,48 @@ flagi(Ins *i0, Ins *i)
 	return 0;
 }
 
-static Ins *
+static void
 seljmp(Blk *b, Fn *fn)
 {
 	Ref r;
 	int c;
 	Ins *fi;
 
-	fi = &b->ins[b->nins];
-	if (b->jmp.type != JJez)
-		return fi;
+	if (b->jmp.type != JJnz)
+		return;
 	r = b->jmp.arg;
 	b->jmp.arg = R;
 	assert(!req(r, R));
 	if (rtype(r) == RCon) {
 		b->jmp.type = JJmp;
-		if (!req(r, CON_Z))
+		if (req(r, CON_Z))
 			b->s1 = b->s2;
 		b->s2 = 0;
-		return fi;
+		return;
 	}
-	fi = flagi(b->ins, fi);
+	fi = flagi(b->ins, &b->ins[b->nins]);
 	if (fi && req(fi->to, r)) {
-		assert(1 == fn->tmp[r.val].nuse);
-		if (fn->tmp[r.val].nuse == 1
-		&& OCmp <= fi->op && fi->op <= OCmp1) {
+		if (OCmp <= fi->op && fi->op <= OCmp1) {
 			c = fi->op - OCmp;
 			if (rtype(fi->arg[0]) == RCon)
 				c = COP(c);
-			b->jmp.type = JXJc + cneg(c);
-			selcmp(fi->arg, fn);
-			return fi;
-		}
-		/* what if it is a comparison
-		 * that is used more than once?
-		 * !!!
-		 */
-		b->jmp.type = JXJc + Ceq;
-		return fi+1;
+			b->jmp.type = JXJc + c;
+			if (fn->tmp[r.val].nuse == 1) {
+				assert(fn->tmp[r.val].ndef==1);
+				selcmp(fi->arg, fn);
+				*fi = (Ins){ONop, R, {R, R}};
+				/* !!! use counts are invalid after that !!! */
+				return;
+			}
+		} else
+			b->jmp.type = JXJc + Cne;
+	} else {
+		if (islong(r, fn))
+			emit(OXCmpl, R, CON_Z, r);
+		else
+			emit(OXCmpw, R, CON_Z, r);
+		b->jmp.type = JXJc + Cne;
 	}
-	if (islong(r, fn))
-		emit(OXCmpl, R, CON_Z, r);
-	else
-		emit(OXCmpw, R, CON_Z, r);
-	b->jmp.type = JXJc + Ceq;
-	return &b->ins[b->nins];
 }
 
 /* instruction selection
@@ -217,8 +205,8 @@ isel(Fn *fn)
 
 	for (b=fn->start; b; b=b->link) {
 		curi = &insb[NIns];
-		i = seljmp(b, fn);
-		while (i>b->ins) {
+		seljmp(b, fn);
+		for (i=&b->ins[b->nins]; i>b->ins;) {
 			sel(*--i, fn);
 		}
 		nins = &insb[NIns] - curi;
diff --git a/lisc/lisc.h b/lisc/lisc.h
index ecd0fcc..2c78da4 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -146,7 +146,7 @@ enum {
 	JXXX,
 	JRet,
 	JJmp,
-	JJez,
+	JJnz,
 	JXJc,
 	JXJc1 = JXJc + NCmp-1,
 	JLast
diff --git a/lisc/parse.c b/lisc/parse.c
index 8320a87..eca9d1d 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -53,7 +53,7 @@ typedef enum {
 	TCsle,
 	TPhi,
 	TJmp,
-	TJez,
+	TJnz,
 	TRet,
 	TW,
 	TL,
@@ -138,7 +138,7 @@ lex()
 		{ "csle", TCsle },
 		{ "phi", TPhi },
 		{ "jmp", TJmp },
-		{ "jez", TJez },
+		{ "jnz", TJnz },
 		{ "ret", TRet },
 		{ "w", TW },
 		{ "l", TL },
@@ -396,11 +396,11 @@ parseline(PState ps)
 	case TJmp:
 		curb->jmp.type = JJmp;
 		goto Jump;
-	case TJez:
-		curb->jmp.type = JJez;
+	case TJnz:
+		curb->jmp.type = JJnz;
 		r = parseref();
 		if (req(r, R))
-			err("invalid argument for jez jump");
+			err("invalid argument for jnz jump");
 		curb->jmp.arg = r;
 		expect(TComma);
 	Jump:
@@ -582,7 +582,7 @@ void
 printfn(Fn *fn, FILE *f)
 {
 	static char *jtoa[JLast] = {
-		[JJez]      = "jez",
+		[JJnz]      = "jnz",
 		[JXJc+Ceq]  = "xjeq",
 		[JXJc+Csle] = "xjsle",
 		[JXJc+Cslt] = "xjslt",
@@ -642,7 +642,7 @@ printfn(Fn *fn, FILE *f)
 			break;
 		default:
 			fprintf(f, "\t%s ", jtoa[b->jmp.type]);
-			if (b->jmp.type == JJez) {
+			if (b->jmp.type == JJnz) {
 				printref(b->jmp.arg, fn, f);
 				fprintf(f, ", ");
 			}
diff --git a/lisc/test/alt.ssa b/lisc/test/alt.ssa
index 480177a..f96ecc2 100644
--- a/lisc/test/alt.ssa
+++ b/lisc/test/alt.ssa
@@ -9,15 +9,15 @@
 	%alt =w phi @start 0, @left %alt1, @right %alt1
 	%cnt =w phi @start 100, @left %cnt, @right %cnt1
 	%alt1 =w sub 1, %alt
-	jez %alt1, @left, @right
+	jnz %alt1, @right, @left
 @left
 	%x =w phi @loop 10, @left %x1
 	%x1 =w sub %x, 1
 	%z =w copy %x
-	jez %z, @loop, @left
+	jnz %z, @left, @loop
 @right
 	%cnt1 =w sub %cnt, %ten
-	jez %cnt1, @end, @loop
+	jnz %cnt1, @loop, @end
 @end
 	%ret =w add %cnt, %dum
 	ret
diff --git a/lisc/test/cup.ssa b/lisc/test/cup.ssa
index bd6501e..da9bd77 100644
--- a/lisc/test/cup.ssa
+++ b/lisc/test/cup.ssa
@@ -5,6 +5,6 @@
 	%n0  =l phi @start -1988, @loop %n1
 	%n1  =l add 1, %n0
 	%cmp =w csle 1991, %n1
-	jez %cmp, @loop, @end
+	jnz %cmp, @end, @loop
 @end
 	ret
diff --git a/lisc/test/eucl.ssa b/lisc/test/eucl.ssa
index fdbca57..741a742 100644
--- a/lisc/test/eucl.ssa
+++ b/lisc/test/eucl.ssa
@@ -9,7 +9,7 @@
 	%a =w phi @start 380, @loop %r
 	%b =w phi @start 747, @loop %a
 	%r =w rem %b, %a
-	jez %r, @end, @loop
+	jnz %r, @loop, @end
 
 @end
 	ret
diff --git a/lisc/test/fix1.ssa b/lisc/test/fix1.ssa
index d6250d2..61b6395 100644
--- a/lisc/test/fix1.ssa
+++ b/lisc/test/fix1.ssa
@@ -1,7 +1,7 @@
 @start
 	%x =w copy 1
 @loop
-	jez %x, @isz, @noz
+	jnz %x, @noz, @isz
 @noz
 	%x =w copy 0
 	jmp @end
diff --git a/lisc/test/fix2.ssa b/lisc/test/fix2.ssa
index 0b07584..94f1573 100644
--- a/lisc/test/fix2.ssa
+++ b/lisc/test/fix2.ssa
@@ -1,10 +1,10 @@
 @start
 	%x =w copy 1
 @loop
-	jez %x, @isz, @noz
+	jnz %x, @noz, @isz
 @noz
 	%x =w copy 0
-	jez %x, @end, @loop
+	jnz %x, @loop, @end
 @isz
 	%x =w copy 1
 	jmp @loop
diff --git a/lisc/test/live.ssa b/lisc/test/live.ssa
index 2e3110d..8513fc4 100644
--- a/lisc/test/live.ssa
+++ b/lisc/test/live.ssa
@@ -8,7 +8,7 @@
 @start
 	%b =w copy 0
 	%x =w copy 10
-	jez 0, @left, @loop
+	jnz 0, @loop, @left
 @left
 	jmp @inloop
 @loop
diff --git a/lisc/test/loop.ssa b/lisc/test/loop.ssa
index 1b55e02..7fb70a7 100644
--- a/lisc/test/loop.ssa
+++ b/lisc/test/loop.ssa
@@ -8,7 +8,7 @@
 	%n  =w phi @start   0, @loop %n1
 	%n1 =w sub %n, 1
 	%s1 =w add %s, %n
-	jez %n1, @end, @loop
+	jnz %n1, @loop, @end
 
 @end
 	ret
diff --git a/lisc/test/rpo.ssa b/lisc/test/rpo.ssa
index 44d0056..1b63ab7 100644
--- a/lisc/test/rpo.ssa
+++ b/lisc/test/rpo.ssa
@@ -1,10 +1,10 @@
 @start
 	jmp @foo
 @baz
-	jez 1, @end, @foo
+	jnz 1, @end, @foo
 @bar
 	jmp @end
 @foo
-	jez 0, @bar, @baz
+	jnz 0, @bar, @baz
 @end
 	ret