ref: 064b5d2b2f9c54fcbd0e928d75253032e51f7e6f
parent: 1750fba1a4fc55641cfd5a9ced3a33f012ff221f
author: Ori Bernstein <ori@eigenstate.org>
date: Mon Jan 20 11:47:23 EST 2014
Correctly handle signed/unsigned comparisons.
--- a/6/insns.def
+++ b/6/insns.def
@@ -60,6 +60,10 @@
Insn(Isetle, "\tsetle %v\n", Use(), Def(.l={1})) Insn(Isetg, "\tsetg %v\n", Use(), Def(.l={1})) Insn(Isetge, "\tsetge %v\n", Use(), Def(.l={1}))+Insn(Isetb, "\tsetb %v\n", Use(), Def(.l={1}))+Insn(Isetbe, "\tsetbe %v\n", Use(), Def(.l={1}))+Insn(Iseta, "\tseta %v\n", Use(), Def(.l={1}))+Insn(Isetae, "\tsetae %v\n", Use(), Def(.l={1}))/* fp specific instructions */
Insn(Imovs, "\tmovs%1t %x,%x\n", Use(.l={1}), Def(.l={2}))@@ -82,6 +86,10 @@
Insn(Ijle, "\tjle %v\n", Use(.l={1}), Def()) Insn(Ijg, "\tjg %v\n", Use(.l={1}), Def()) Insn(Ijge, "\tjge %v\n", Use(.l={1}), Def())+Insn(Ijb, "\tjb %v\n", Use(.l={1}), Def())+Insn(Ijbe, "\tjbe %v\n", Use(.l={1}), Def())+Insn(Ija, "\tja %v\n", Use(.l={1}), Def())+Insn(Ijae, "\tjae %v\n", Use(.l={1}), Def())Insn(Iret, "\tret\n", Use(), Def())
/* not really an insn... */
--- a/6/isel.c
+++ b/6/isel.c
@@ -40,18 +40,32 @@
/* used to decide which operator is appropriate
* for implementing various conditional operators */
struct {- AsmOp itest;
- AsmOp fptest;
+ AsmOp test;
AsmOp jmp;
AsmOp getflag;
} reloptab[Numops] = {- [Olnot] = {Itest, 0, Ijz, Isetz}, /* lnot invalid for floats */- [Oeq] = {Icmp, Icomis, Ijz, Isetz},- [One] = {Icmp, Icomis, Ijnz, Isetnz},- [Ogt] = {Icmp, Icomis, Ijg, Isetg},- [Oge] = {Icmp, Icomis, Ijge, Isetge},- [Olt] = {Icmp, Icomis, Ijl, Isetl},- [Ole] = {Icmp, Icomis, Ijle, Isetle}+ [Olnot] = {Itest, Ijz, Isetz}, /* lnot invalid for floats */+ /* signed int */
+ [Oeq] = {Icmp, Ijz, Isetz},+ [One] = {Icmp, Ijnz, Isetnz},+ [Ogt] = {Icmp, Ijg, Isetg},+ [Oge] = {Icmp, Ijge, Isetge},+ [Olt] = {Icmp, Ijl, Isetl},+ [Ole] = {Icmp, Ijle, Isetle},+ /* unsigned int */
+ [Oueq] = {Icmp, Ijz, Isetz},+ [Oune] = {Icmp, Ijnz, Isetnz},+ [Ougt] = {Icmp, Ija, Iseta},+ [Ouge] = {Icmp, Ijae, Isetae},+ [Oult] = {Icmp, Ijb, Isetb},+ [Oule] = {Icmp, Ijbe, Isetbe},+ /* float */
+ [Ofeq] = {Icomis, Ijz, Isetz},+ [Ofne] = {Icomis, Ijnz, Isetnz},+ [Ofgt] = {Icomis, Ija, Iseta},+ [Ofge] = {Icomis, Ijae, Isetae},+ [Oflt] = {Icomis, Ijb, Isetb},+ [Ofle] = {Icomis, Ijbe, Isetbe},};
static Mode mode(Node *n)
@@ -235,14 +249,6 @@
return inr(s, a);
}
-static int floatcompare(Node *e)
-{- if (exprop(e) == Ovar || exprop(e) == Olit)
- return floatnode(e);
- assert(e->expr.nargs > 0);
- return floatnode(e->expr.args[0]);
-}
-
/* If we're testing equality, etc, it's a bit silly
* to generate the test, store it to a bite, expand it
* to the right width, and then test it again. Try to optimize
@@ -258,10 +264,7 @@
Loc *l1, *l2;
AsmOp cond, jmp;
- if (floatcompare(args[0]))
- cond = reloptab[exprop(args[0])].fptest;
- else
- cond = reloptab[exprop(args[0])].itest;
+ cond = reloptab[exprop(args[0])].test;
jmp = reloptab[exprop(args[0])].jmp;
/* if we have a cond, we're knocking off the redundant test,
* and want to eval the children */
@@ -610,21 +613,20 @@
b = locreg(ModeB);
r = locreg(mode(n));
/* lnot only valid for integer-like values */
- g(s, reloptab[exprop(n)].itest, a, a, NULL);
+ g(s, reloptab[exprop(n)].test, a, a, NULL);
g(s, reloptab[exprop(n)].getflag, b, NULL);
movz(s, b, r);
break;
case Oeq: case One: case Ogt: case Oge: case Olt: case Ole:
+ case Ofeq: case Ofne: case Ofgt: case Ofge: case Oflt: case Ofle:
+ case Oueq: case Oune: case Ougt: case Ouge: case Oult: case Oule:
a = selexpr(s, args[0]);
b = selexpr(s, args[1]);
a = inr(s, a);
c = locreg(ModeB);
r = locreg(mode(n));
- if (floatnode(args[0]))
- g(s, reloptab[exprop(n)].fptest, b, a, NULL);
- else
- g(s, reloptab[exprop(n)].itest, b, a, NULL);
+ g(s, reloptab[exprop(n)].test, b, a, NULL);
g(s, reloptab[exprop(n)].getflag, c, NULL);
movz(s, c, r);
return r;
--- a/6/simp.c
+++ b/6/simp.c
@@ -1246,8 +1246,15 @@
[Obsleq] = Obsl,
[Obsreq] = Obsr,
};
+ const Op cmpmap[Numops][3] = {+ [Oeq] = {Oeq, Ofeq, Oueq},+ [One] = {One, Ofne, Oune},+ [Ogt] = {Ogt, Ofgt, Ougt},+ [Oge] = {Oge, Ofge, Ouge},+ [Olt] = {Olt, Oflt, Oult},+ [Ole] = {Ole, Ofle, Oule}+ };
-
r = NULL;
args = n->expr.args;
switch (exprop(n)) {@@ -1431,6 +1438,17 @@
if (s->nloopstep == 0)
fatal(n->line, "trying to continue when not in loop");
jmp(s, s->loopstep[s->nloopstep - 1]);
+ break;
+ case Oeq: case One: case Ogt: case Oge: case Olt: case Ole:
+ if (istyfloat(tybase(exprtype(args[0]))))
+ i = 1;
+ else if (istysigned(tybase(exprtype(args[0]))))
+ i = 0;
+ else
+ i = 2;
+ assert(cmpmap[n->expr.op][i] != Obad);
+ n->expr.op = cmpmap[n->expr.op][i];
+ r = visit(s, n);
break;
default:
if (istyfloat(exprtype(n))) {--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1245,6 +1245,8 @@
case Otrunc: case Oswiden: case Ozwiden:
case Oint2flt: case Oflt2int:
case Ofadd: case Ofsub: case Ofmul: case Ofdiv: case Ofneg:
+ case Ofeq: case Ofne: case Ofgt: case Ofge: case Oflt: case Ofle:
+ case Oueq: case Oune: case Ougt: case Ouge: case Oult: case Oule:
case Ouget:
die("Should not see %s in fe", opstr(exprop(n)));break;
--- a/parse/ops.def
+++ b/parse/ops.def
@@ -56,7 +56,8 @@
O(Otup, 1)
O(Ostruct, 1)
O(Oarr, 1)
-/* backend-only */
+
+/* all below this point are backend-only */
O(Ocjmp, 1) /* conditional jump */
O(Oset, 1) /* store to var */
O(Osllen, 1) /* size of slice */
@@ -72,3 +73,18 @@
O(Ofmul, 1)
O(Ofdiv, 1)
O(Ofneg, 1)
+
+/* floating point comparisons */
+O(Ofeq, 1)
+O(Ofne, 1)
+O(Ofgt, 1)
+O(Ofge, 1)
+O(Oflt, 1)
+O(Ofle, 1)
+/* unsigned comparisons */
+O(Oueq, 1)
+O(Oune, 1)
+O(Ougt, 1)
+O(Ouge, 1)
+O(Oult, 1)
+O(Oule, 1)
--
⑨