commit ce7fd0cb49fc1864eb1ef290cd835a64ce25efbf
parent db6f7ad72dda70f5dd3b34a3faea1e08537e77be
Author: Quentin Carbonneaux <quentin.carbonneaux@yale.edu>
Date: Wed, 16 Mar 2016 11:30:57 -0400
add unsigned division and remainder
Diffstat:
4 files changed, 18 insertions(+), 4 deletions(-)
diff --git 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
@@ -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
@@ -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
@@ -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;