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");
}
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) {
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) {
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);
} 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) {
boolgen(Node *n, int true, Node *nn)
{
int o;
- Prog *p1, *p2;
+ Prog *p1, *p2, *p3;
Node *l, *r, nod, nod1;
int32 curs;
cgen64(n, Z);
goto com;
}
+ 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) {
} else
fgopcode(o, l, &fregnode0, 0, 1);
}
+ 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;
+ }
goto com;
}
if(l->op == OCONST) {