summaryrefslogtreecommitdiff
path: root/src/cmd/6c/cgen.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/6c/cgen.c')
-rw-r--r--src/cmd/6c/cgen.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/cmd/6c/cgen.c b/src/cmd/6c/cgen.c
index 7f717dcbb..71822586c 100644
--- a/src/cmd/6c/cgen.c
+++ b/src/cmd/6c/cgen.c
@@ -1237,11 +1237,12 @@ void
boolgen(Node *n, int true, Node *nn)
{
int o;
- Prog *p1, *p2;
+ Prog *p1, *p2, *p3;
Node *l, *r, nod, nod1;
int32 curs;
if(debug['g']) {
+ print("boolgen %d\n", true);
prtree(nn, "boolgen lhs");
prtree(n, "boolgen");
}
@@ -1353,6 +1354,15 @@ boolgen(Node *n, int true, Node *nn)
case OLO:
case OLS:
o = n->op;
+ if(true && typefd[l->type->etype] && (o == OEQ || o == ONE)) {
+ // Cannot rewrite !(l == r) into l != r with float64; it breaks NaNs.
+ // Jump around instead.
+ boolgen(n, 0, Z);
+ p1 = p;
+ gbranch(OGOTO);
+ patch(p1, pc);
+ goto com;
+ }
if(true)
o = comrel[relindex(o)];
if(l->complex >= FNX && r->complex >= FNX) {
@@ -1367,6 +1377,10 @@ boolgen(Node *n, int true, Node *nn)
break;
}
if(immconst(l)) {
+ // NOTE: Reversing the comparison here is wrong
+ // for floating point ordering comparisons involving NaN,
+ // but we don't have any of those yet so we don't
+ // bother worrying about it.
o = invrel[relindex(o)];
/* bad, 13 is address of external that becomes constant */
if(r->addable < INDEXED || r->addable == 13) {
@@ -1388,10 +1402,11 @@ boolgen(Node *n, int true, Node *nn)
cgen(r, &nod1);
gopcode(o, l->type, &nod, &nod1);
regfree(&nod1);
- } else
+ } else {
gopcode(o, l->type, &nod, r);
+ }
regfree(&nod);
- goto com;
+ goto fixfloat;
}
regalloc(&nod, r, nn);
cgen(r, &nod);
@@ -1406,6 +1421,33 @@ boolgen(Node *n, int true, Node *nn)
} else
gopcode(o, l->type, l, &nod);
regfree(&nod);
+ fixfloat:
+ if(typefd[l->type->etype]) {
+ switch(o) {
+ case OEQ:
+ // Already emitted AJEQ; want AJEQ and AJPC.
+ p1 = p;
+ gbranch(OGOTO);
+ p2 = p;
+ patch(p1, pc);
+ gins(AJPC, Z, Z);
+ patch(p2, pc);
+ break;
+
+ case ONE:
+ // Already emitted AJNE; want AJNE or AJPS.
+ p1 = p;
+ gins(AJPS, Z, Z);
+ p2 = p;
+ gbranch(OGOTO);
+ p3 = p;
+ patch(p1, pc);
+ patch(p2, pc);
+ gbranch(OGOTO);
+ patch(p3, pc);
+ break;
+ }
+ }
com:
if(nn != Z) {