about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-30 18:13:01 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-30 18:13:01 +0200
commit60b625bc0fe12933c34f889d75eb9b48d5c4f76e (patch)
tree9402a1f815fc83d24d1dcce821ee6408e0261978 /src/dynarec
parentd1703b9bc044152a15e74bf1650a2d63dd0fd153 (diff)
downloadbox64-60b625bc0fe12933c34f889d75eb9b48d5c4f76e.tar.gz
box64-60b625bc0fe12933c34f889d75eb9b48d5c4f76e.zip
[ARM64_DYNAREC] Added AVX.66.F3A 19 opcodes and some various avx helper fixes
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c15
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c9
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h16
-rw-r--r--src/dynarec/dynarec_native_pass.c1
4 files changed, 36 insertions, 5 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c
index 69dba468..6a90792f 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c
@@ -127,6 +127,21 @@ uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
             if(v0!=v2)
                 VMOVQ((u8&1)?v0:q0, (u8&1)?v2:q2);
             break;
+        case 0x19:
+            INST_NAME("VEXTRACTF128 Ex, Gx, imm8");
+            nextop = F8;
+            u8 = geted_ib(dyn, addr, ninst, nextop);
+            if(u8&1) {GETG; GETGY(v0, 0, -1, -1, -1);} else {GETGX(v0, 0);}
+            if(MODREG) {
+                v1 = sse_get_reg_empty(dyn, ninst, x1, (nextop&7)+(rex.b<<3));
+                VMOVQ(v1, v0);
+                YMM0((nextop&7)+(rex.b<<3));
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
+                VST128(v0, ed, fixedaddress);
+            }
+            F8; // read u8, but it's been already handled
+            break;
 
         default:
             DEFAULT;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index cdf0eeb6..2d08510e 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -1789,6 +1789,15 @@ int ymm_get_reg_empty(dynarec_arm_t* dyn, int ninst, int s1, int a, int k1, int
     return ret;
 }
 
+void ymm_mark_zero(dynarec_arm_t* dyn, int ninst, int a)
+{
+    // look if already exist
+    for(int i=0; i<32; ++i)
+        if((dyn->n.neoncache[i].t==NEON_CACHE_YMMR || dyn->n.neoncache[i].t==NEON_CACHE_YMMW) && dyn->n.neoncache[i].n==a) {
+            dyn->n.neoncache[i].v = 0;  // forget it!
+        }
+    avx_mark_zero(dyn, ninst, a);
+}
 
 void fpu_pushcache(dynarec_arm_t* dyn, int ninst, int s1, int not07)
 {
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index b9f4f01a..6349054b 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -465,6 +465,9 @@
 #define GETGY_empty(a, k1, k2, k3)                          \
     a = ymm_get_reg_empty(dyn, ninst, x1, gd, k1, k2, k3)
 
+#define GETGY(a, w, k1, k2, k3)                             \
+    a = ymm_get_reg(dyn, ninst, x1, gd, w, k1, k2, k3)
+
 #define GETGY_empty_VY(a, b, w2, k1, k2)                    \
     b = ymm_get_reg(dyn, ninst, x1, vex.v, w2, gd, k1, k2); \
     a = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, k1, k2)
@@ -584,7 +587,7 @@
         SMWRITE2();                         \
     }
 
-#define YMM0(a) avx_mark_zero(dyn, ninst, gd);
+#define YMM0(a) ymm_mark_zero(dyn, ninst, a);
 
 // Get Direction with size Z and based of F_DF flag, on register r ready for LDR/STR fetching
 // F_DF is 1<<10, so 1 ROR 11*2 (so F_OF)
@@ -1209,11 +1212,12 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
 #define mmx_get_reg_empty STEPNAME(mmx_get_reg_empty)
 #define sse_get_reg     STEPNAME(sse_get_reg)
 #define sse_get_reg_empty STEPNAME(sse_get_reg_empty)
-#define sse_forget_reg   STEPNAME(sse_forget_reg)
-#define sse_purge07cache STEPNAME(sse_purge07cache)
-#define sse_reflect_reg  STEPNAME(sse_reflect_reg)
-#define ymm_get_reg     STEPNAME(ymm_get_reg)
+#define sse_forget_reg    STEPNAME(sse_forget_reg)
+#define sse_purge07cache  STEPNAME(sse_purge07cache)
+#define sse_reflect_reg   STEPNAME(sse_reflect_reg)
+#define ymm_get_reg       STEPNAME(ymm_get_reg)
 #define ymm_get_reg_empty STEPNAME(ymm_get_reg_empty)
+#define ymm_mark_zero     STEPNAME(ymm_mark_zero)
 
 #define fpu_pushcache   STEPNAME(fpu_pushcache)
 #define fpu_popcache    STEPNAME(fpu_popcache)
@@ -1465,6 +1469,8 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1, int not07);
 int ymm_get_reg(dynarec_arm_t* dyn, int ninst, int s1, int a, int forwrite, int k1, int k2, int k3);
 // get neon register for a SSE reg, but don't try to synch it if it needed to be created
 int ymm_get_reg_empty(dynarec_arm_t* dyn, int ninst, int s1, int a, int k1, int k2, int k3);
+// mark an ymm upper part has zero (forgetting upper part if needed)
+void ymm_mark_zero(dynarec_arm_t* dyn, int ninst, int a);
 
 
 uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
diff --git a/src/dynarec/dynarec_native_pass.c b/src/dynarec/dynarec_native_pass.c
index 60c37b4b..c748b47d 100644
--- a/src/dynarec/dynarec_native_pass.c
+++ b/src/dynarec/dynarec_native_pass.c
@@ -49,6 +49,7 @@ uintptr_t native_pass(dynarec_native_t* dyn, uintptr_t addr, int alternate, int
     dyn->forward_to = 0;
     dyn->forward_size = 0;
     dyn->forward_ninst = 0;
+    dyn->ymm_zero = 0;
     #if STEP == 0
     memset(&dyn->insts[ninst], 0, sizeof(instruction_native_t));
     #endif