From 539fe6990fecc38bd3b634be5857da3ee59bafee Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Fri, 20 Sep 2013 14:58:43 +0200 Subject: [PATCH] 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). --- sys/src/cmd/5c/cgen.c | 8 ++++---- sys/src/cmd/5c/gc.h | 1 + sys/src/cmd/5c/txt.c | 13 ++++++++++++- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/sys/src/cmd/5c/cgen.c b/sys/src/cmd/5c/cgen.c index c639b180f..18971103b 100644 --- a/sys/src/cmd/5c/cgen.c +++ b/sys/src/cmd/5c/cgen.c @@ -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); diff --git a/sys/src/cmd/5c/gc.h b/sys/src/cmd/5c/gc.h index e62955617..3d43b015c 100644 --- a/sys/src/cmd/5c/gc.h +++ b/sys/src/cmd/5c/gc.h @@ -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; diff --git a/sys/src/cmd/5c/txt.c b/sys/src/cmd/5c/txt.c index 9ee8cb5b6..574694cdd 100644 --- a/sys/src/cmd/5c/txt.c +++ b/sys/src/cmd/5c/txt.c @@ -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;