diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-07-06 14:23:57 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-07-06 14:23:57 +0200 |
| commit | cb73eaf7768cd765cb242bb4526c9ce998e4d82d (patch) | |
| tree | 2c2ed253027ad78ead5271bba67f7558d8062e3a | |
| parent | bb38d8d1ca3289422b52b2eb3a89a305afd88436 (diff) | |
| download | box64-cb73eaf7768cd765cb242bb4526c9ce998e4d82d.tar.gz box64-cb73eaf7768cd765cb242bb4526c9ce998e4d82d.zip | |
Work on CMPSS and CMPSD ([DYNAREC] too)
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f20f.c | 11 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_f30f.c | 11 | ||||
| -rw-r--r-- | src/emu/x64runf20f.c | 2 | ||||
| -rw-r--r-- | tests/ref16.txt | 99 | ||||
| -rwxr-xr-x | tests/test16 | bin | 16648 -> 30344 bytes | |||
| -rw-r--r-- | tests/test16.c | 154 |
6 files changed, 262 insertions, 15 deletions
diff --git a/src/dynarec/dynarec_arm64_f20f.c b/src/dynarec/dynarec_arm64_f20f.c index ef709d02..4064b004 100755 --- a/src/dynarec/dynarec_arm64_f20f.c +++ b/src/dynarec/dynarec_arm64_f20f.c @@ -288,14 +288,13 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n FCMPD(v0, v1); } switch(u8&7) { - case 0: CSETMx(x2, cEQ); break; // Equal - case 1: CSETMx(x2, cMI); break; // Less than - case 2: //CSETMx(x2, cLE); break; // Less or equal (or unordered on ARM64, not on x86...) - CSETMx(x2, cPL); CSINVx(x2, xZR, x2, cEQ); break; // so use a 2 step here, but 1st test inverted because 2nd step invert again + case 0: CSETMx(x2, cEQ); CSELx(x2, xZR, x2, cVS); break; // Equal + case 1: CSETMx(x2, cMI); CSELx(x2, xZR, x2, cVS); break; // Less than + case 2: CSETMx(x2, cLE); CSELx(x2, xZR, x2, cVS); break; // Less or equal case 3: CSETMx(x2, cVS); break; // NaN - case 4: CSETMx(x2, cNE); break; // Not Equal (or unordered on ARM, not on X86...) + case 4: CSETMx(x2, cNE); break; // Not Equal case 5: CSETMx(x2, cCS); break; // Greater or equal or unordered - case 6: CSETMx(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordereded or less than (inverted) + case 6: CSETMx(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted) case 7: CSETMx(x2, cVC); break; // not NaN } VMOVQDfrom(v0, 0, x2); diff --git a/src/dynarec/dynarec_arm64_f30f.c b/src/dynarec/dynarec_arm64_f30f.c index 2df33bcf..b8479d5c 100755 --- a/src/dynarec/dynarec_arm64_f30f.c +++ b/src/dynarec/dynarec_arm64_f30f.c @@ -376,14 +376,13 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n FCMPS(v0, v1); } switch(u8&7) { - case 0: CSETMw(x2, cEQ); break; // Equal - case 1: CSETMw(x2, cMI); break; // Less than - case 2: //CSETMw(x2, cLE); break; // Less or equal (or unordered on ARM64, not on x86...) - CSETMw(x2, cPL); CSINVw(x2, xZR, x2, cEQ); break; // so use a 2 step here, but 1st test inverted because 2nd step invert again + case 0: CSETMw(x2, cEQ); CSELw(x2, xZR, x2, cVS); break; // Equal + case 1: CSETMw(x2, cMI); CSELw(x2, xZR, x2, cVS); break; // Less than + case 2: CSETMw(x2, cLE); CSELw(x2, xZR, x2, cVS); break; // Less or equal case 3: CSETMw(x2, cVS); break; // NaN - case 4: CSETMw(x2, cNE); break; // Not Equal (or unordered on ARM, not on X86...) + case 4: CSETMw(x2, cNE); break; // Not Equal case 5: CSETMw(x2, cCS); break; // Greater or equal or unordered - case 6: CSETMw(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordereded or less than (inverted) + case 6: CSETMw(x2, cLT); break; // Greater or unordered, test inverted, N!=V so unordered or less than (inverted) case 7: CSETMw(x2, cVC); break; // not NaN } VMOVQSfrom(v0, 0, x2); diff --git a/src/emu/x64runf20f.c b/src/emu/x64runf20f.c index 766a69f8..7bf3c99e 100644 --- a/src/emu/x64runf20f.c +++ b/src/emu/x64runf20f.c @@ -212,7 +212,7 @@ int RunF20F(x64emu_t *emu, rex_t rex) case 0xC2: /* CMPSD Gx, Ex, Ib */ nextop = F8; - GETEX(0); + GETEX(1); GETGX; tmp8u = F8; tmp8s = 0; diff --git a/tests/ref16.txt b/tests/ref16.txt index 4f5916e0..75b0fa8d 100644 --- a/tests/ref16.txt +++ b/tests/ref16.txt @@ -9,3 +9,102 @@ ucomiss nan, 1.000000 => 0x247 ucomiss 1.000000, 1.000000 => 0x242 ucomiss inf, inf => 0x242 ucomiss nan, nan => 0x247 +ucomisd 1.000000, 2.000000 => 0x202 +ucomisd 2.000000, 1.000000 => 0x203 +ucomisd 1.000000, inf => 0x202 +ucomisd inf, 1.000000 => 0x203 +ucomisd 1.000000, -inf => 0x203 +ucomisd -inf, 1.000000 => 0x202 +ucomisd 1.000000, nan => 0x247 +ucomisd nan, 1.000000 => 0x247 +ucomisd 1.000000, 1.000000 => 0x242 +ucomisd inf, inf => 0x242 +ucomisd nan, nan => 0x247 +cmpsd 1.000000, 2.000000, 0 => 0x0 +cmpsd 2.000000, 1.000000, 0 => 0x0 +cmpsd 1.000000, inf, 0 => 0x0 +cmpsd inf, 1.000000, 0 => 0x0 +cmpsd 1.000000, -inf, 0 => 0x0 +cmpsd -inf, 1.000000, 0 => 0x0 +cmpsd 1.000000, nan, 0 => 0x0 +cmpsd nan, 1.000000, 0 => 0x0 +cmpsd 1.000000, 1.000000, 0 => 0xffffffffffffffff +cmpsd inf, inf, 0 => 0xffffffffffffffff +cmpsd nan, nan, 0 => 0x0 +cmpsd 1.000000, 2.000000, 1 => 0xffffffffffffffff +cmpsd 2.000000, 1.000000, 1 => 0x0 +cmpsd 1.000000, inf, 1 => 0xffffffffffffffff +cmpsd inf, 1.000000, 1 => 0x0 +cmpsd 1.000000, -inf, 1 => 0x0 +cmpsd -inf, 1.000000, 1 => 0xffffffffffffffff +cmpsd 1.000000, nan, 1 => 0x0 +cmpsd nan, 1.000000, 1 => 0x0 +cmpsd 1.000000, 1.000000, 1 => 0x0 +cmpsd inf, inf, 1 => 0x0 +cmpsd nan, nan, 1 => 0x0 +cmpsd 1.000000, 2.000000, 2 => 0xffffffffffffffff +cmpsd 2.000000, 1.000000, 2 => 0x0 +cmpsd 1.000000, inf, 2 => 0xffffffffffffffff +cmpsd inf, 1.000000, 2 => 0x0 +cmpsd 1.000000, -inf, 2 => 0x0 +cmpsd -inf, 1.000000, 2 => 0xffffffffffffffff +cmpsd 1.000000, nan, 2 => 0x0 +cmpsd nan, 1.000000, 2 => 0x0 +cmpsd 1.000000, 1.000000, 2 => 0xffffffffffffffff +cmpsd inf, inf, 2 => 0xffffffffffffffff +cmpsd nan, nan, 2 => 0x0 +cmpsd 1.000000, 2.000000, 3 => 0x0 +cmpsd 2.000000, 1.000000, 3 => 0x0 +cmpsd 1.000000, inf, 3 => 0x0 +cmpsd inf, 1.000000, 3 => 0x0 +cmpsd 1.000000, -inf, 3 => 0x0 +cmpsd -inf, 1.000000, 3 => 0x0 +cmpsd 1.000000, nan, 3 => 0xffffffffffffffff +cmpsd nan, 1.000000, 3 => 0xffffffffffffffff +cmpsd 1.000000, 1.000000, 3 => 0x0 +cmpsd inf, inf, 3 => 0x0 +cmpsd nan, nan, 3 => 0xffffffffffffffff +cmpsd 1.000000, 2.000000, 4 => 0xffffffffffffffff +cmpsd 2.000000, 1.000000, 4 => 0xffffffffffffffff +cmpsd 1.000000, inf, 4 => 0xffffffffffffffff +cmpsd inf, 1.000000, 4 => 0xffffffffffffffff +cmpsd 1.000000, -inf, 4 => 0xffffffffffffffff +cmpsd -inf, 1.000000, 4 => 0xffffffffffffffff +cmpsd 1.000000, nan, 4 => 0xffffffffffffffff +cmpsd nan, 1.000000, 4 => 0xffffffffffffffff +cmpsd 1.000000, 1.000000, 4 => 0x0 +cmpsd inf, inf, 4 => 0x0 +cmpsd nan, nan, 4 => 0xffffffffffffffff +cmpsd 1.000000, 2.000000, 5 => 0x0 +cmpsd 2.000000, 1.000000, 5 => 0xffffffffffffffff +cmpsd 1.000000, inf, 5 => 0x0 +cmpsd inf, 1.000000, 5 => 0xffffffffffffffff +cmpsd 1.000000, -inf, 5 => 0xffffffffffffffff +cmpsd -inf, 1.000000, 5 => 0x0 +cmpsd 1.000000, nan, 5 => 0xffffffffffffffff +cmpsd nan, 1.000000, 5 => 0xffffffffffffffff +cmpsd 1.000000, 1.000000, 5 => 0xffffffffffffffff +cmpsd inf, inf, 5 => 0xffffffffffffffff +cmpsd nan, nan, 5 => 0xffffffffffffffff +cmpsd 1.000000, 2.000000, 6 => 0x0 +cmpsd 2.000000, 1.000000, 6 => 0xffffffffffffffff +cmpsd 1.000000, inf, 6 => 0x0 +cmpsd inf, 1.000000, 6 => 0xffffffffffffffff +cmpsd 1.000000, -inf, 6 => 0xffffffffffffffff +cmpsd -inf, 1.000000, 6 => 0x0 +cmpsd 1.000000, nan, 6 => 0xffffffffffffffff +cmpsd nan, 1.000000, 6 => 0xffffffffffffffff +cmpsd 1.000000, 1.000000, 6 => 0x0 +cmpsd inf, inf, 6 => 0x0 +cmpsd nan, nan, 6 => 0xffffffffffffffff +cmpsd 1.000000, 2.000000, 7 => 0xffffffffffffffff +cmpsd 2.000000, 1.000000, 7 => 0xffffffffffffffff +cmpsd 1.000000, inf, 7 => 0xffffffffffffffff +cmpsd inf, 1.000000, 7 => 0xffffffffffffffff +cmpsd 1.000000, -inf, 7 => 0xffffffffffffffff +cmpsd -inf, 1.000000, 7 => 0xffffffffffffffff +cmpsd 1.000000, nan, 7 => 0x0 +cmpsd nan, 1.000000, 7 => 0x0 +cmpsd 1.000000, 1.000000, 7 => 0xffffffffffffffff +cmpsd inf, inf, 7 => 0xffffffffffffffff +cmpsd nan, nan, 7 => 0x0 diff --git a/tests/test16 b/tests/test16 index af645769..6f9a4b30 100755 --- a/tests/test16 +++ b/tests/test16 Binary files differdiff --git a/tests/test16.c b/tests/test16.c index 2b312834..4096de18 100644 --- a/tests/test16.c +++ b/tests/test16.c @@ -5,6 +5,7 @@ #include <stdint.h> #include <math.h> +#if defined(__x86_64__) uint64_t _ucomiss_(float a, float b) { uint64_t ret; @@ -13,11 +14,65 @@ uint64_t _ucomiss_(float a, float b) "pushf\n" "pop %%rax" :"=a" (ret)::"xmm0","xmm1","cc"); - return ret; } +uint64_t _ucomisd_(double a, double b) +{ + uint64_t ret; + asm volatile ( + "ucomisd %%xmm0, %%xmm1\n" + "pushf\n" + "pop %%rax" + :"=a" (ret)::"xmm0","xmm1","cc"); + return ret; +} +#define GO(n) \ +uint64_t _cmpsd_##n##_(double a, double b) \ +{ \ + uint64_t ret; \ + asm volatile ( \ + "cmpsd $" #n ", %%xmm1, %%xmm0\n" \ + "movq %%xmm0, %%rax" \ + :"=a" (ret)::"xmm0","xmm1","cc"); \ + return ret; \ +} +GO(0) +GO(1) +GO(2) +GO(3) +GO(4) +GO(5) +GO(6) +GO(7) +#undef GO +#else +uint64_t _ucomiss_(float a, float b) +{ + uint32_t ret; + asm volatile ( + "movss %1, %%xmm0\n" + "movss %2, %%xmm1\n" + "ucomiss %%xmm0, %%xmm1\n" + "pushf\n" + "pop %%eax" + :"=a" (ret):"m"(a), "m"(b):"xmm0", "xmm1", "cc"); + return ret; +} +uint64_t _ucomisd_(double a, double b) +{ + uint32_t ret; + asm volatile ( + "movsd %1, %%xmm0\n" + "movsd %2, %%xmm1\n" + "ucomisd %%xmm0, %%xmm1\n" + "pushf\n" + "pop %%eax" + :"=a" (ret):"m"(a), "m"(b):"xmm0", "xmm1", "cc"); + return ret; +} +#endif -int main(int argc, const char** argv) +void test_ucomiss() { float a, b; uint64_t flags; @@ -50,6 +105,101 @@ int main(int argc, const char** argv) a = b = NAN; flags = _ucomiss_(a, b); printf("ucomiss %f, %f => 0x%lx\n", a, b, flags); +} + +void test_ucomisd() +{ + double a, b; + uint64_t flags; + a = 1.0; b = 2.0; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); + flags = _ucomisd_(b, a); + printf("ucomisd %f, %f => 0x%lx\n", b, a, flags); + b = INFINITY; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); + flags = _ucomisd_(b, a); + printf("ucomisd %f, %f => 0x%lx\n", b, a, flags); + b = -INFINITY; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); + flags = _ucomisd_(b, a); + printf("ucomisd %f, %f => 0x%lx\n", b, a, flags); + b = NAN; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); + flags = _ucomisd_(b, a); + printf("ucomisd %f, %f => 0x%lx\n", b, a, flags); + b = a; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); + a = b = INFINITY; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); + a = b = NAN; + flags = _ucomisd_(a, b); + printf("ucomisd %f, %f => 0x%lx\n", a, b, flags); +} +#if defined(__x86_64__) +#define GO(n) \ +void test_cmpsd_##n() \ +{ \ + double a, b; \ + uint64_t flags; \ + a = 1.0; b = 2.0; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ + flags = _cmpsd_##n##_(b, a); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", b, a, flags); \ + b = INFINITY; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ + flags = _cmpsd_##n##_(b, a); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", b, a, flags); \ + b = -INFINITY; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ + flags = _cmpsd_##n##_(b, a); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", b, a, flags); \ + b = NAN; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ + flags = _cmpsd_##n##_(b, a); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", b, a, flags); \ + b = a; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ + a = b = INFINITY; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ + a = b = NAN; \ + flags = _cmpsd_##n##_(a, b); \ + printf("cmpsd %f, %f, " #n " => 0x%lx\n", a, b, flags); \ +} +GO(0) +GO(1) +GO(2) +GO(3) +GO(4) +GO(5) +GO(6) +GO(7) +#endif +int main(int argc, const char** argv) +{ + test_ucomiss(); + test_ucomisd(); + #if defined(__x86_64__) + test_cmpsd_0(); + test_cmpsd_1(); + test_cmpsd_2(); + test_cmpsd_3(); + test_cmpsd_4(); + test_cmpsd_5(); + test_cmpsd_6(); + test_cmpsd_7(); + #endif return 0; } |