aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Preud'homme <robotux@celest.fr>2013-12-31 23:40:21 +0800
committerThomas Preud'homme <robotux@celest.fr>2014-01-03 10:19:38 +0800
commite0e9a2a29562ac0f07c5d29070e1797fa48b144f (patch)
treef0ef686163ef61eb5a0df8c7aa4ed119f193d5f5
parent59b8007f98eb814f6fd19455ab868ecaa07dfc0d (diff)
downloadtinycc-e0e9a2a29562ac0f07c5d29070e1797fa48b144f.tar.gz
tinycc-e0e9a2a29562ac0f07c5d29070e1797fa48b144f.tar.bz2
Report error on NaN comparison
Use comisd / fcompp for float comparison (except TOK_EQ and TOK_NE) instead of ucomisd / fucompp to detect NaN comparison. Thanks Vincent Lefèvre for the bug report and for also giving the solution.
-rw-r--r--i386-gen.c5
-rw-r--r--x86_64-gen.c12
2 files changed, 13 insertions, 4 deletions
diff --git a/i386-gen.c b/i386-gen.c
index b26b844..ebc0d14 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -895,7 +895,10 @@ ST_FUNC void gen_opf(int op)
swapped = 0;
if (swapped)
o(0xc9d9); /* fxch %st(1) */
- o(0xe9da); /* fucompp */
+ if (op == TOK_EQ || op == TOK_NE)
+ o(0xe9da); /* fucompp */
+ else
+ o(0xd9de); /* fcompp */
o(0xe0df); /* fnstsw %ax */
if (op == TOK_EQ) {
o(0x45e480); /* and $0x45, %ah */
diff --git a/x86_64-gen.c b/x86_64-gen.c
index 2f4d8fe..1550c07 100644
--- a/x86_64-gen.c
+++ b/x86_64-gen.c
@@ -1793,7 +1793,10 @@ void gen_opf(int op)
swapped = 0;
if (swapped)
o(0xc9d9); /* fxch %st(1) */
- o(0xe9da); /* fucompp */
+ if (op == TOK_EQ || op == TOK_NE)
+ o(0xe9da); /* fucompp */
+ else
+ o(0xd9de); /* fcompp */
o(0xe0df); /* fnstsw %ax */
if (op == TOK_EQ) {
o(0x45e480); /* and $0x45, %ah */
@@ -1877,8 +1880,11 @@ void gen_opf(int op)
if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE)
o(0x66);
- o(0x2e0f); /* ucomisd */
-
+ if (op == TOK_EQ || op == TOK_NE)
+ o(0x2e0f); /* ucomisd */
+ else
+ o(0x2f0f); /* comisd */
+
if (vtop->r & VT_LVAL) {
gen_modrm(vtop[-1].r, r, vtop->sym, fc);
} else {