summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--lisc/emit.c3
-rw-r--r--lisc/isel.c13
-rw-r--r--lisc/lisc.h3
-rw-r--r--lisc/parse.c3
4 files changed, 18 insertions, 4 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index 4eeee8d..dcda556 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -87,7 +87,8 @@ static struct {
 	{ OSwap,   Ki, "xchg%k %0, %1" },
 	{ OSign,   Kl, "cqto" },
 	{ OSign,   Kw, "cltd" },
-	{ OXDiv,   Ki, "idiv%k %0" },
+	{ OXDiv,   Ki, "div%k %0" },
+	{ OXIDiv,  Ki, "idiv%k %0" },
 	{ OXCmp,   Ks, "comiss %S0, %S1" },  /* fixme, Kf */
 	{ OXCmp,   Kd, "comisd %D0, %D1" },
 	{ OXCmp,   Ki, "cmp%k %0, %1" },
diff --git a/lisc/isel.c b/lisc/isel.c
index da7e946..8752012 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -221,7 +221,9 @@ sel(Ins i, ANum *an, Fn *fn)
 	switch (i.op) {
 	case ODiv:
 	case ORem:
-		if (i.op == ODiv)
+	case OUDiv:
+	case OURem:
+		if (i.op == ODiv || i.op == OUDiv)
 			r0 = TMP(RAX), r1 = TMP(RDX);
 		else
 			r0 = TMP(RDX), r1 = TMP(RAX);
@@ -234,8 +236,13 @@ sel(Ins i, ANum *an, Fn *fn)
 			r0 = newtmp("isel", fn);
 		} else
 			r0 = i.arg[1];
-		emit(OXDiv, k, R, r0, R);
-		emit(OSign, k, TMP(RDX), TMP(RAX), R);
+		if (i.op == ODiv || i.op == ORem) {
+			emit(OXIDiv, k, R, r0, R);
+			emit(OSign, k, TMP(RDX), TMP(RAX), R);
+		} else {
+			emit(OXDiv, k, R, r0, R);
+			emit(OCopy, k, TMP(RDX), CON_Z, R);
+		}
 		emit(OCopy, k, TMP(RAX), i.arg[0], R);
 		if (rtype(i.arg[1]) == RCon)
 			emit(OCopy, k, r0, i.arg[1], R);
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 354c8c7..5374bdd 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -213,6 +213,8 @@ enum Op {
 	OSub,
 	ODiv,
 	ORem,
+	OUDiv,
+	OURem,
 	OMul,
 	OAnd,
 	OOr,
@@ -277,6 +279,7 @@ enum Op {
 	OSwap,
 	OSign,
 	OSAlloc,
+	OXIDiv,
 	OXDiv,
 	OXCmp,
 	OXSet,
diff --git a/lisc/parse.c b/lisc/parse.c
index 45b1b96..e91e32d 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -15,6 +15,8 @@ OpDesc opdesc[NOp] = {
 	[OSub]    = { "sub",      2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0 },
 	[ODiv]    = { "div",      2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0 },
 	[ORem]    = { "rem",      2, {A(w,l,x,x), A(w,l,x,x)}, 0, 0 },
+	[OUDiv]   = { "udiv",     2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0 },
+	[OURem]   = { "urem",     2, {A(w,l,x,x), A(w,l,x,x)}, 0, 0 },
 	[OMul]    = { "mul",      2, {A(w,l,s,d), A(w,l,s,d)}, 0, 0 },
 	[OAnd]    = { "and",      2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0 },
 	[OOr]     = { "or",       2, {A(w,l,s,d), A(w,l,s,d)}, 1, 0 },
@@ -995,6 +997,7 @@ printfn(Fn *fn, FILE *f)
 		[OXCmp] = 1,
 		[OXTest] = 1,
 		[OXDiv] = 1,
+		[OXIDiv] = 1,
 	};
 	static char ktoc[] = "wlsd";
 	Blk *b;