mirror of
https://github.com/golang/go
synced 2024-11-21 23:04:39 -07:00
6c, 8c: make floating point code NaN-safe
R=ken2 CC=golang-dev https://golang.org/cl/5569071
This commit is contained in:
parent
29dbd988b8
commit
109a976355
@ -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) {
|
||||
|
@ -1221,7 +1221,7 @@ void
|
||||
boolgen(Node *n, int true, Node *nn)
|
||||
{
|
||||
int o;
|
||||
Prog *p1, *p2;
|
||||
Prog *p1, *p2, *p3;
|
||||
Node *l, *r, nod, nod1;
|
||||
int32 curs;
|
||||
|
||||
@ -1346,6 +1346,15 @@ boolgen(Node *n, int true, Node *nn)
|
||||
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) {
|
||||
@ -1378,6 +1387,30 @@ boolgen(Node *n, int true, Node *nn)
|
||||
} 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) {
|
||||
|
Loading…
Reference in New Issue
Block a user