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.
Unified · Split
| @@ -895,7 +895,10 @@ ST_FUNC void gen_opf(int op) · 894 unmodified lines | ||
| 895 | 895 | swapped = 0; |
| 896 | 896 | if (swapped) |
| 897 | 897 | o(0xc9d9); /* fxch %st(1) */ |
| 898 | − o(0xe9da); /* fucompp */ | |
| 898 | + if (op == TOK_EQ || op == TOK_NE) | |
| 899 | + o(0xe9da); /* fucompp */ | |
| 900 | + else | |
| 901 | + o(0xd9de); /* fcompp */ | |
| 899 | 902 | o(0xe0df); /* fnstsw %ax */ |
| 900 | 903 | if (op == TOK_EQ) { |
| 901 | 904 | o(0x45e480); /* and $0x45, %ah */ |
| @@ -1793,7 +1793,10 @@ void gen_opf(int op) · 1792 unmodified lines | ||
| 1793 | 1793 | swapped = 0; |
| 1794 | 1794 | if (swapped) |
| 1795 | 1795 | o(0xc9d9); /* fxch %st(1) */ |
| 1796 | − o(0xe9da); /* fucompp */ | |
| 1796 | + if (op == TOK_EQ || op == TOK_NE) | |
| 1797 | + o(0xe9da); /* fucompp */ | |
| 1798 | + else | |
| 1799 | + o(0xd9de); /* fcompp */ | |
| 1797 | 1800 | o(0xe0df); /* fnstsw %ax */ |
| 1798 | 1801 | if (op == TOK_EQ) { |
| 1799 | 1802 | o(0x45e480); /* and $0x45, %ah */ |
| @@ -1877,8 +1880,11 @@ void gen_opf(int op) · 77 unmodified lines | ||
| 1877 | 1880 | |
| 1878 | 1881 | if ((vtop->type.t & VT_BTYPE) == VT_DOUBLE) |
| 1879 | 1882 | o(0x66); |
| 1880 | − o(0x2e0f); /* ucomisd */ | |
| 1881 | − | |
| 1883 | + if (op == TOK_EQ || op == TOK_NE) | |
| 1884 | + o(0x2e0f); /* ucomisd */ | |
| 1885 | + else | |
| 1886 | + o(0x2f0f); /* comisd */ | |
| 1887 | + | |
| 1882 | 1888 | if (vtop->r & VT_LVAL) { |
| 1883 | 1889 | gen_modrm(vtop[-1].r, r, vtop->sym, fc); |
| 1884 | 1890 | } else { |