about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-06-13 10:49:49 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-06-13 10:49:49 +0200
commit8bf1ac6577c501199b0e90cb0959badc90fa10be (patch)
treef10ab5c21c05bb2ec60d1951b015597f47dd37f4 /src
parent58c0bce4cf549dab1440bc60315f8b30407ca0f1 (diff)
downloadbox64-8bf1ac6577c501199b0e90cb0959badc90fa10be.tar.gz
box64-8bf1ac6577c501199b0e90cb0959badc90fa10be.zip
[ARM64_DYNAREC] Added AVX.66.0F 7C opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
index a7392b29..46555c93 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
@@ -1094,6 +1094,34 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
             if(!vex.l) YMM0(gd);
             break;
 
+        case 0x7C:
+            INST_NAME("VHADDPD Gx, Vx, Ex");
+            nextop = F8;
+            if(!box64_dynarec_fastnan) {
+                q0 = fpu_get_scratch(dyn, ninst);
+                q1 = fpu_get_scratch(dyn, ninst);
+            }
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                if(!box64_dynarec_fastnan) {
+                    // check if any input value was NAN
+                    // but need to mix low/high part
+                    VTRNQ1_64(q0, v2, v1);
+                    VTRNQ2_64(q1, v2, v1);
+                    VFMAXQD(q0, q0, q1);    // propagate NAN
+                    VFCMEQQD(q0, q0, q0);    // 0 if NAN, 1 if not NAN
+                }
+                VFADDPQD(v0, v2, v1);
+                if(!box64_dynarec_fastnan) {
+                    VFCMEQQD(q1, v0, v0);    // 0 => out is NAN
+                    VBICQ(q1, q0, q1);      // forget it in any input was a NAN already
+                    VSHLQ_64(q1, q1, 63);   // only keep the sign bit
+                    VORRQ(v0, v0, q1);      // NAN -> -NAN
+                }
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+
         case 0x7E:
             INST_NAME("VMOVD Ed,Gx");
             nextop = F8;