see 5c-nan-cmp on sources by richard miller announced on 9fans with: 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). the readme says: Ensure floating point comparisons with NaN are unordered (always return FALSE except for !=). On ARM this is just a matter of using the right condition codes (cc in PSR has different meaning when set from the FPSCR after a floating point comparison). Reference: /n/atom/patch/applied2013/x5c-nan-cmp Date: Fri Sep 20 14:31:36 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/cmd/5c/txt.c Fri Sep 20 14:29:44 2013 +++ /sys/src/cmd/5c/txt.c Fri Sep 20 14:29:45 2013 @@ -929,12 +929,14 @@ 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 @@ 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; --- /sys/src/cmd/5c/gc.h Fri Sep 20 14:29:45 2013 +++ /sys/src/cmd/5c/gc.h Fri Sep 20 14:29:46 2013 @@ -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; @@ -125,7 +126,7 @@ }; #define R ((Reg*)0) -#define NRGN 600 +#define NRGN 1000 /* was 600; raised for paranoia.c */ struct Rgn { Reg* enter; --- /sys/src/cmd/5c/cgen.c Fri Sep 20 14:29:47 2013 +++ /sys/src/cmd/5c/cgen.c Fri Sep 20 14:29:48 2013 @@ -701,7 +701,7 @@ 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 @@ 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 @@ 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);