5c: apply richard millers 5c-nan-cmp patch (from sources)

On ARM, it turns out that comparisons with NaN can be made to do the
right thing with no code penalty, by a more careful selection of
condition code values in the subsequent conditional branch.  The
meaning of the CC bits in the PSR is subtly different when they've
been copied from the floating point status register.

Suggested patch is 5c-nan-cmp (works on both vfp and emulated arm7500).
This commit is contained in:
cinap_lenrek 2013-09-20 14:58:43 +02:00
parent 171aafcc22
commit 539fe6990f
3 changed files with 17 additions and 5 deletions

View file

@ -701,7 +701,7 @@ boolgen(Node *n, int true, Node *nn)
if(true)
o = comrel[relindex(o)];
if(typefd[n->type->etype]) {
gopcode(o, nodfconst(0), &nod, Z);
gopcode(true ? o | BTRUE : o, nodfconst(0), &nod, Z);
} else
gopcode(o, nodconst(0), &nod, Z);
regfree(&nod);
@ -800,14 +800,14 @@ boolgen(Node *n, int true, Node *nn)
regalloc(&nod, r, nn);
cgenrel(r, &nod, 1);
o = invrel[relindex(o)];
gopcode(o, l, &nod, Z);
gopcode(true ? o | BTRUE : o, l, &nod, Z);
regfree(&nod);
goto com;
}
if(sconst(r)) {
regalloc(&nod, l, nn);
cgenrel(l, &nod, 1);
gopcode(o, r, &nod, Z);
gopcode(true ? o | BTRUE : o, r, &nod, Z);
regfree(&nod);
goto com;
}
@ -822,7 +822,7 @@ boolgen(Node *n, int true, Node *nn)
regalloc(&nod1, l, Z);
cgenrel(l, &nod1, 1);
}
gopcode(o, &nod, &nod1, Z);
gopcode(true ? o | BTRUE : o, &nod, &nod1, Z);
regfree(&nod);
regfree(&nod1);

View file

@ -14,6 +14,7 @@
#define SZ_VLONG 8
#define SZ_DOUBLE 8
#define FNX 100
#define BTRUE 0x1000
typedef struct Adr Adr;
typedef struct Prog Prog;

View file

@ -929,12 +929,14 @@ gins(int a, Node *f, Node *t)
void
gopcode(int o, Node *f1, Node *f2, Node *t)
{
int a, et;
int a, et, true;
Adr ta;
et = TLONG;
if(f1 != Z && f1->type != T)
et = f1->type->etype;
true = o & BTRUE;
o &= ~BTRUE;
a = AGOK;
switch(o) {
case OAS:
@ -1076,15 +1078,24 @@ gopcode(int o, Node *f1, Node *f2, Node *t)
break;
case OLT:
a = ABLT;
/* ensure NaN comparison is always false */
if(typefd[et] && !true)
a = ABMI;
break;
case OLE:
a = ABLE;
if(typefd[et] && !true)
a = ABLS;
break;
case OGE:
a = ABGE;
if(typefd[et] && true)
a = ABPL;
break;
case OGT:
a = ABGT;
if(typefd[et] && true)
a = ABHI;
break;
case OLO:
a = ABLO;