about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-05-18 19:26:32 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-05-18 19:26:32 +0200
commit16bdcc0c93939df3d242253bde28c2b58840a7be (patch)
tree0840dfb69c5d02131ec88aff1878f45987090436 /src
parent2798c3c8cde74ee98b7e5144303905eee0c638ae (diff)
downloadbox64-16bdcc0c93939df3d242253bde28c2b58840a7be.tar.gz
box64-16bdcc0c93939df3d242253bde28c2b58840a7be.zip
[ARM64_DYNAREC] Added fastnan=0 handling to 0F 52 opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_printer.c2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c26
2 files changed, 13 insertions, 15 deletions
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index 3d369fb3..20294a32 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -1341,7 +1341,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         return buff;

     }

     //FCMEQ

-    if(isMask(opcode, "000111100f1mmmmm111001nnnnnddddd", &a)) {

+    if(isMask(opcode, "010111100f1mmmmm111001nnnnnddddd", &a)) {

         char s = (sf==0)?'S':'D';

         snprintf(buff, sizeof(buff), "FCMEQ %c%d, %c%d, %c%d", s, Rd, s, Rn, s, Rm);

         return buff;

diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index a4cf07ec..f6535005 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1083,24 +1083,22 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             nextop = F8;

             GETEX(q0, 0, 0);

             GETGX_empty(q1);

-            #if 0

-            SKIPTEST(x1);

-            v0 = fpu_get_scratch(dyn, ninst);

-            // more precise

-            if(q1==q0)

-                v1 = fpu_get_scratch(dyn, ninst);

-            else

-                v1 = q1;

-            VFRSQRTEQS(v0, q0);

-            VFMULQS(v1, v0, q0);

-            VFRSQRTSQS(v1, v1, v0);

-            VFMULQS(q1, v1, v0);

-            #else

             v0 = fpu_get_scratch(dyn, ninst);

+            if(!BOX64ENV(dynarec_fastnan)) {

+                d0 = fpu_get_scratch(dyn, ninst);

+                d1 = fpu_get_scratch(dyn, ninst);

+                // check if any input value was NAN

+                VFCMEQQS(d0, q0, q0);    // 0 if NAN, 1 if not NAN

+            }

             VFMOVSQ_8(v0, 0b01110000);    //1.0f

             VFSQRTQS(q1, q0);

             VFDIVQS(q1, v0, q1);

-            #endif

+            if(!BOX64ENV(dynarec_fastnan)) {

+                VFCMEQQS(d1, q1, q1);    // 0 => out is NAN

+                VBICQ(d1, d0, d1);      // forget it in any input was a NAN already

+                VSHLQ_32(d1, d1, 31);   // only keep the sign bit

+                VORRQ(q1, q1, d1);      // NAN -> -NAN

+            }

             break;

         case 0x53:

             INST_NAME("RCPPS Gx, Ex");