summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-02-11 16:10:08 -0500
committerQuentin Carbonneaux <quentin.carbonneaux@yale.edu>2016-02-11 16:12:11 -0500
commit53a5d7de2a7f84bf364753aaa3587121e8077937 (patch)
tree71ce6a5754f4dc91d97124e6a65431092f5519b9
parent96251837db7c698a76d997f1449f0cd47885f203 (diff)
downloadroux-53a5d7de2a7f84bf364753aaa3587121e8077937.tar.gz
fp cmp fixes (highly untested)
-rw-r--r--lisc/emit.c48
-rw-r--r--lisc/isel.c71
-rw-r--r--lisc/lisc.h76
-rw-r--r--lisc/parse.c20
4 files changed, 160 insertions, 55 deletions
diff --git a/lisc/emit.c b/lisc/emit.c
index ecc6b36..3b916c4 100644
--- a/lisc/emit.c
+++ b/lisc/emit.c
@@ -74,12 +74,14 @@ static struct {
{ OXCmp, Kd, "comisd %D0, %D1" },
{ OXCmp, Ki, "cmp%k %0, %1" },
{ OXTest, Ki, "test%k %0, %1" },
- { OXSet+Ceq, Ki, "setz %B=\n\tmovzb%k %B=, %=" },
- { OXSet+Csle, Ki, "setle %B=\n\tmovzb%k %B=, %=" },
- { OXSet+Cslt, Ki, "setl %B=\n\tmovzb%k %B=, %=" },
- { OXSet+Csgt, Ki, "setg %B=\n\tmovzb%k %B=, %=" },
- { OXSet+Csge, Ki, "setge %B=\n\tmovzb%k %B=, %=" },
- { OXSet+Cne, Ki, "setnz %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICeq, Ki, "setz %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICsle, Ki, "setle %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICslt, Ki, "setl %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICsgt, Ki, "setg %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICsge, Ki, "setge %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICne, Ki, "setnz %B=\n\tmovzb%k %B=, %=" },
+ { OXSet+ICXnp, Ki, "setnp %B=\n\tmovsb%k %B=, %=" },
+ { OXSet+ICXp, Ki, "setp %B=\n\tmovsb%k %B=, %=" },
{ NOp, 0, 0 }
};
@@ -411,12 +413,18 @@ cneg(int cmp)
{
switch (cmp) {
default: diag("emit: 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;
+ case ICule: return ICugt;
+ case ICult: return ICuge;
+ case ICsle: return ICsgt;
+ case ICslt: return ICsge;
+ case ICsgt: return ICsle;
+ case ICsge: return ICslt;
+ case ICugt: return ICule;
+ case ICuge: return ICult;
+ case ICeq: return ICne;
+ case ICne: return ICeq;
+ case ICXnp: return ICXp;
+ case ICXp: return ICXnp;
}
}
@@ -437,8 +445,18 @@ void
emitfn(Fn *fn, FILE *f)
{
static char *ctoa[] = {
- [Ceq] = "z", [Csle] = "le", [Cslt] = "l",
- [Csgt] = "g", [Csge] = "ge", [Cne] = "nz"
+ [ICeq] = "z",
+ [ICule] = "be",
+ [ICult] = "b",
+ [ICsle] = "le",
+ [ICslt] = "l",
+ [ICsgt] = "g",
+ [ICsge] = "ge",
+ [ICugt] = "a",
+ [ICuge] = "ae",
+ [ICne] = "nz",
+ [ICXnp] = "np",
+ [ICXp] = "p"
};
Blk *b, *s;
Ins *i, itmp;
@@ -484,7 +502,7 @@ emitfn(Fn *fn, FILE *f)
break;
default:
c = b->jmp.type - JXJc;
- if (0 <= c && c <= NCmp) {
+ if (0 <= c && c <= NXICmp) {
if (b->link == b->s2) {
s = b->s1;
} else if (b->link == b->s1) {
diff --git a/lisc/isel.c b/lisc/isel.c
index 45f793c..41ca011 100644
--- a/lisc/isel.c
+++ b/lisc/isel.c
@@ -31,6 +31,48 @@ struct ANum {
static void amatch(Addr *, Ref, ANum *, Fn *, int);
static int
+fcmptoi(int fc)
+{
+ switch (fc) {
+ default: diag("isel: fcmptoi defaulted");
+ case FCle: return ICule;
+ case FClt: return ICult;
+ case FCgt: return ICugt;
+ case FCge: return ICuge;
+ case FCne: return ICne;
+ case FCeq: return ICeq;
+ case FCo: return ICXnp;
+ case FCuo: return ICXp;
+ }
+}
+
+static int
+iscmp(int op, int *k, int *c)
+{
+ if (OCmpw <= op && op <= OCmpw1) {
+ *c = op - OCmpw;
+ *k = Kw;
+ return 1;
+ }
+ if (OCmpl <= op && op <= OCmpl1) {
+ *c = op - OCmpl;
+ *k = Kl;
+ return 1l;
+ }
+ if (OCmps <= op && op <= OCmps1) {
+ *c = fcmptoi(op - OCmps);
+ *k = Ks;
+ return 1;
+ }
+ if (OCmpd <= op && op <= OCmpd1) {
+ *c = fcmptoi(op - OCmpd);
+ *k = Kd;
+ return 1;
+ }
+ return 0;
+}
+
+static int
noimm(Ref r, Fn *fn)
{
int64_t val;
@@ -159,7 +201,7 @@ static void
sel(Ins i, ANum *an, Fn *fn)
{
Ref r0, r1;
- int x, k;
+ int x, k, kc;
int64_t val;
Ins *i0;
@@ -248,12 +290,11 @@ Emit:
goto case_OExt;
if (OLoad <= i.op && i.op <= OLoad1)
goto case_OLoad;
- if (OCmp <= i.op && i.op <= OCmp1) {
- x = i.op - OCmp;
+ if (iscmp(i.op, &kc, &x)) {
if (rtype(i.arg[0]) == RCon)
- x = COP(x);
- emit(OXSet+x, Kw, i.to, R, R);
- selcmp(i.arg, k, fn);
+ x = icmpop(x);
+ emit(OXSet+x, k, i.to, R, R);
+ selcmp(i.arg, kc, fn);
break;
}
diag("isel: non-exhaustive implementation");
@@ -271,7 +312,10 @@ flagi(Ins *i0, Ins *i)
while (i>i0)
switch ((--i)->op) {
default:
- if (OCmp <= i->op && i->op <= OCmp1)
+ if ((OCmpw <= i->op && i->op <= OCmpw1)
+ || (OCmpl <= i->op && i->op <= OCmpl1)
+ || (OCmps <= i->op && i->op <= OCmps1)
+ || (OCmpd <= i->op && i->op <= OCmpd1))
return i;
if (OExt <= i->op && i->op <= OExt1)
continue;
@@ -295,7 +339,7 @@ static void
seljmp(Blk *b, Fn *fn)
{
Ref r;
- int c, w;
+ int c, w, k;
Ins *fi;
switch (b->jmp.type) {
@@ -325,10 +369,9 @@ seljmp(Blk *b, Fn *fn)
}
fi = flagi(b->ins, &b->ins[b->nins]);
if (fi && req(fi->to, r)) {
- if (OCmp <= fi->op && fi->op <= OCmp1) {
- c = fi->op - OCmp;
+ if (iscmp(fi->op, &k, &c)) {
if (rtype(fi->arg[0]) == RCon)
- c = COP(c);
+ c = icmpop(c);
b->jmp.type = JXJc + c;
if (fn->tmp[r.val].nuse == 1) {
assert(fn->tmp[r.val].ndef == 1);
@@ -342,7 +385,7 @@ seljmp(Blk *b, Fn *fn)
rtype(fi->arg[1]) == RTmp)) {
fi->op = OXTest;
fi->to = R;
- b->jmp.type = JXJc + Cne;
+ b->jmp.type = JXJc + ICne;
if (rtype(fi->arg[1]) == RCon) {
r = fi->arg[1];
fi->arg[1] = fi->arg[0];
@@ -351,12 +394,12 @@ seljmp(Blk *b, Fn *fn)
return;
}
if (fn->tmp[r.val].nuse > 1) {
- b->jmp.type = JXJc + Cne;
+ b->jmp.type = JXJc + ICne;
return;
}
}
selcmp((Ref[2]){r, CON_Z}, 0, fn); /* todo, add long branch if non-zero */
- b->jmp.type = JXJc + Cne;
+ b->jmp.type = JXJc + ICne;
}
struct AClass {
diff --git a/lisc/lisc.h b/lisc/lisc.h
index 2e99374..90f3ee2 100644
--- a/lisc/lisc.h
+++ b/lisc/lisc.h
@@ -150,22 +150,49 @@ static inline int isreg(Ref r)
return rtype(r) == RTmp && r.val < Tmp0;
}
-#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 X(c) C##c,
- CMPS(X)
+enum ICmp {
+#define ICMPS(X) \
+ X(ule) \
+ X(ult) \
+ X(sle) \
+ X(slt) \
+ X(sgt) \
+ X(sge) \
+ X(ugt) \
+ X(uge) \
+ X(eq) \
+ X(ne) /* make sure icmpop() below works! */
+
+#define X(c) IC##c,
+ ICMPS(X)
#undef X
+ NICmp,
- NCmp
+ ICXnp = NICmp, /* x64 specific */
+ ICXp,
+ NXICmp
+};
+
+static inline int icmpop(int c)
+{
+ return c >= ICeq ? c : ICuge - c;
+}
+
+enum FCmp {
+#define FCMPS(X) \
+ X(le) \
+ X(lt) \
+ X(gt) \
+ X(ge) \
+ X(ne) \
+ X(eq) \
+ X(o) \
+ X(uo)
+
+#define X(c) FC##c,
+ FCMPS(X)
+#undef X
+ NFCmp
};
enum Class {
@@ -188,8 +215,14 @@ enum Op {
ORem,
OMul,
OAnd,
- OCmp,
- OCmp1 = OCmp + NCmp-1,
+ OCmpw,
+ OCmpw1 = OCmpw + NICmp-1,
+ OCmpl,
+ OCmpl1 = OCmpl + NICmp-1,
+ OCmps,
+ OCmps1 = OCmps + NFCmp-1,
+ OCmpd,
+ OCmpd1 = OCmpd + NFCmp-1,
OStored,
OStores,
@@ -243,7 +276,8 @@ enum Op {
OXDiv,
OXCmp,
OXSet,
- OXSet1 = OXSet + NCmp-1,
+ OXSetnp = OXSet + NICmp,
+ OXSetp,
OXTest,
NOp
};
@@ -257,7 +291,8 @@ enum Jmp {
JJmp,
JJnz,
JXJc,
- JXJc1 = JXJc + NCmp-1,
+ JXJnp = JXJc + NICmp,
+ JXJp,
NJmp
};
@@ -456,10 +491,9 @@ void copy(Fn *);
Bits liveon(Blk *, Blk *);
void filllive(Fn *);
-
/* isel.c */
-extern int rsave[NRSave];
-extern int rclob[NRClob];
+extern int rsave[/* NRSave */];
+extern int rclob[/* NRClob */];
ulong calldef(Ins, int[2]);
ulong calluse(Ins, int[2]);
void isel(Fn *);
diff --git a/lisc/parse.c b/lisc/parse.c
index b0d011c..a77904c 100644
--- a/lisc/parse.c
+++ b/lisc/parse.c
@@ -49,10 +49,18 @@ OpDesc opdesc[NOp] = {
[OAlloc] = { "alloc4", 1 },
[OAlloc+1] = { "alloc8", 1 },
[OAlloc+2] = { "alloc16", 1 },
+ [OXSetnp] = { "xsetnp", 0},
+ [OXSetp] = { "xsetp", 0},
#define X(c) \
- [OCmp+C##c] = { "c" #c, 0 }, \
- [OXSet+C##c] = { "xset" #c, 0 },
- CMPS(X)
+ [OCmpw+IC##c] = { "c" #c "w", 0 }, \
+ [OCmpl+IC##c] = { "c" #c "l", 0 }, \
+ [OXSet+IC##c] = { "xset" #c, 0 },
+ ICMPS(X)
+#undef X
+#define X(c) \
+ [OCmps+FC##c] = { "c" #c "s", 0 }, \
+ [OCmpd+FC##c] = { "c" #c "d", 0 },
+ FCMPS(X)
#undef X
};
@@ -917,8 +925,10 @@ printfn(Fn *fn, FILE *f)
[JRetl] = "retl",
[JRetc] = "retc",
[JJnz] = "jnz",
- #define X(c) [JXJc+C##c] = "xj" #c,
- CMPS(X)
+ [JXJnp] = "xjnp",
+ [JXJp] = "xjp",
+ #define X(c) [JXJc+IC##c] = "xj" #c,
+ ICMPS(X)
#undef X
};
static char prcls[NOp] = {