about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-07-11 16:47:24 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-07-11 16:47:24 +0200
commit302a358476b4787e583c309558b94cf816bcf536 (patch)
treeef6a1d4e08f0706d302bb1830b179cf0b9c25a69
parent74dd9f2778523f4ba113f6cbc88d8361b8f1572d (diff)
downloadbox64-302a358476b4787e583c309558b94cf816bcf536.tar.gz
box64-302a358476b4787e583c309558b94cf816bcf536.zip
[ARM64_DYNAREC] Added handling of FASTNAN=0 to MULSS opcode
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f30f.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_f30f.c b/src/dynarec/arm64/dynarec_arm64_f30f.c
index 2cf40246..eb487766 100644
--- a/src/dynarec/arm64/dynarec_arm64_f30f.c
+++ b/src/dynarec/arm64/dynarec_arm64_f30f.c
@@ -251,11 +251,24 @@ uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
         case 0x59:

             INST_NAME("MULSS Gx, Ex");

             nextop = F8;

-            GETGX(v0, 1);

-            d1 = fpu_get_scratch(dyn, ninst);

+            GETGX(d1, 1);

+            v1 = fpu_get_scratch(dyn, ninst);

             GETEXSS(d0, 0, 0);

-            FMULS(d1, v0, d0);

-            VMOVeS(v0, 0, d1, 0);

+            if(!box64_dynarec_fastnan) {

+                v0 = fpu_get_scratch(dyn, ninst);

+                q0 = fpu_get_scratch(dyn, ninst);

+                // check if any input value was NAN

+                FMAXS(v0, d0, d1);    // propagate NAN

+                FCMEQS(v0, v0, v0);    // 0 if NAN, 1 if not NAN

+                FMULS(v1, d1, d0);

+                FCMEQS(q0, v1, v1);    // 0 => out is NAN

+                VBIC(q0, v0, q0);      // forget it in any input was a NAN already

+                VSHL_32(q0, q0, 31);   // only keep the sign bit

+                VORR(v1, v1, q0);      // NAN -> -NAN

+            } else {

+                FMULS(v1, d1, d0);

+            }

+            VMOVeS(d1, 0, v1, 0);

             break;

         case 0x5A:

             INST_NAME("CVTSS2SD Gx, Ex");