about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-04-26 10:46:11 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-04-26 10:46:11 +0200
commitff4ae1f4d83d49b1071506146ca403316d914b61 (patch)
tree8f97f0619af37011d57f202b2f14b14fba2e8729 /src
parentf7acb787432b3cf2b5b8127d80476d80e362dd1e (diff)
downloadbox64-ff4ae1f4d83d49b1071506146ca403316d914b61.tar.gz
box64-ff4ae1f4d83d49b1071506146ca403316d914b61.zip
[ARM64_DYNAREC] Allow shift with saturation on (V)PMULH(U)W because it will never saturate
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c3
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c6
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f.c6
3 files changed, 5 insertions, 10 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 5d983399..7850393d 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -2814,8 +2814,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             GETEM(v1, 0);

             q0 = fpu_get_scratch(dyn, ninst);

             VUMULL_16(q0, v0, v1);

-            VSHRQ_32(q0, q0, 16);

-            XTN_16(v0, q0);

+            UQSHRN_16(v0, q0, 16);  // saturation will never happens as only 16bits remain and fits in 16bits

             break;

         case 0xE5:

             INST_NAME("PMULHW Gm,Em");

diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index d36dea7b..49477f16 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -3108,10 +3108,8 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             q1 = fpu_get_scratch(dyn, ninst);

             VUMULL_16(q0, v0, v1);

             VUMULL2_16(q1, v0, v1);

-            VSHRQ_32(q0, q0, 16);

-            VSHRQ_32(q1, q1, 16);

-            XTN_16(v0, q0);

-            XTN2_16(v0, q1);

+            UQSHRN_16(v0, q0, 16);  // 16bits->16bits: no saturation

+            UQSHRN2_16(v0, q1, 16);

             break;

         case 0xE5:

             INST_NAME("PMULHW Gx, Ex");

diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
index aea2f378..e878056d 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
@@ -1626,10 +1626,8 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
                 if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
                 VUMULL_16(q0, v2, v1);
                 VUMULL2_16(q1, v2, v1);
-                VSHRQ_32(q0, q0, 16);
-                VSHRQ_32(q1, q1, 16);
-                XTN_16(v0, q0);
-                XTN2_16(v0, q1);
+                UQSHRN_16(v0, q0, 16);  // 16bits->16bits: no saturation
+                UQSHRN2_16(v0, q1, 16);
             }
             if(!vex.l) YMM0(gd);
             break;