about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-30 15:47:19 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-30 15:47:19 +0200
commitfa591589c7432e1425f3b6bd6b77f255221bfb67 (patch)
tree3355c682c1e53c6a1e94c7632aa5fc4896232d56 /src
parentf0ea459c57b401718d5024c6907a67dce38457c4 (diff)
downloadbox64-fa591589c7432e1425f3b6bd6b77f255221bfb67.tar.gz
box64-fa591589c7432e1425f3b6bd6b77f255221bfb67.zip
[ARM64_DYNAREC] Added AVX.66.0F3A 18 opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx.c2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c89
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c1
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h7
-rw-r--r--src/emu/x64runavx660f3a.c2
5 files changed, 99 insertions, 2 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx.c b/src/dynarec/arm64/dynarec_arm64_avx.c
index 53ff0cf5..3150580d 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx.c
@@ -51,6 +51,8 @@ uintptr_t dynarec64_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 
     if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_NONE))
         addr = dynarec64_AVX_0F(dyn, addr, ip, ninst, vex, ok, need_epilog);
+    else if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_66))
+        addr = dynarec64_AVX_66_0F3A(dyn, addr, ip, ninst, vex, ok, need_epilog);
     else {DEFAULT;}
 
     if(*ok==-1) {
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c
new file mode 100644
index 00000000..b2c2f8b3
--- /dev/null
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f3a.c
@@ -0,0 +1,89 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <errno.h>
+
+#include "debug.h"
+#include "box64context.h"
+#include "dynarec.h"
+#include "emu/x64emu_private.h"
+#include "emu/x64run_private.h"
+#include "x64run.h"
+#include "x64emu.h"
+#include "box64stack.h"
+#include "callback.h"
+#include "emu/x64run_private.h"
+#include "x64trace.h"
+#include "dynarec_native.h"
+#include "my_cpuid.h"
+#include "emu/x87emu_private.h"
+#include "emu/x64shaext.h"
+
+#include "arm64_printer.h"
+#include "dynarec_arm64_private.h"
+#include "dynarec_arm64_functions.h"
+#include "dynarec_arm64_helper.h"
+
+uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog)
+{
+    (void)ip; (void)need_epilog;
+
+    uint8_t opcode = F8;
+    uint8_t nextop, u8;
+    uint8_t gd, ed;
+    uint8_t wback, wb1, wb2;
+    uint8_t eb1, eb2, gb1, gb2;
+    int32_t i32, i32_;
+    int cacheupd = 0;
+    int v0, v1, v2;
+    int q0, q1, q2;
+    int d0, d1, d2;
+    int s0;
+    uint64_t tmp64u;
+    int64_t j64;
+    int64_t fixedaddress;
+    int unscaled;
+    MAYUSE(wb1);
+    MAYUSE(wb2);
+    MAYUSE(eb1);
+    MAYUSE(eb2);
+    MAYUSE(gb1);
+    MAYUSE(gb2);
+    MAYUSE(q0);
+    MAYUSE(q1);
+    MAYUSE(d0);
+    MAYUSE(d1);
+    MAYUSE(s0);
+    MAYUSE(j64);
+    MAYUSE(cacheupd);
+
+    rex_t rex = vex.rex;
+
+    switch(opcode) {
+
+        case 0x18:
+            INST_NAME("VINSERTF128 Gx, Ex, imm8");
+            nextop = F8;
+            if(MODREG) {
+                v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 0);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, &unscaled, 0xfff<<4, 15, rex, NULL, 0, 1);
+                v1 = -1; // to avoid a warning
+            }
+            u8 = F8;
+            GETGX(v0, 1);
+            GETVX(v2, 0);
+            GETGY_VY(q0, 1, q2, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);
+            if(MODREG)
+                VMOVQ((u8&1)?q0:v0, v1);
+            else
+                VLD128((u8&1)?q0:v0, ed, fixedaddress);
+            if(v0!=v2)
+                VMOVQ((u8&1)?v0:q0, (u8&1)?v2:q2);
+            break;
+
+        default:
+            DEFAULT;
+    }
+    return addr;
+}
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index 3d23bd00..e2e0f1e0 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -110,7 +110,6 @@ static int internal_mark_ymm(dynarec_arm_t* dyn, int t, int ymm, int reg)
                 dyn->n.neoncache[reg].t=t;
             return reg;
         }
-        return -1;
     } else {
         // found a slot!
         dyn->n.neoncache[reg].t=t;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index fc06d358..53abb9b5 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -457,6 +457,11 @@
 #define GETVX_empty(a)                  \
     a = sse_get_reg_empty(dyn, ninst, x1, vex.v)
 
+#define GETGY_VY(a, w1, b, w2, k1, k2)                      \
+    if(w2) b = ymm_get_reg(dyn, ninst, x1, vex.v, w2, gd, k1, k2); \
+    a = ymm_get_reg(dyn, ninst, x1, gd, vex.v, w1, k1, k2); \
+    if(!w2) b = ymm_get_reg(dyn, ninst, x1, vex.v, w2, gd, k1, k2)
+
 #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)
@@ -1031,6 +1036,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr);
 #define dynarec64_F30F     STEPNAME(dynarec64_F30F)
 #define dynarec64_AVX      STEPNAME(dynarec64_AVX)
 #define dynarec64_AVX_0F   STEPNAME(dynarec64_AVX_0F)
+#define dynarec64_AVX_66_0F3A   STEPNAME(dynarec64_AVX_66_0F3A)
 
 #define geted           STEPNAME(geted)
 #define geted32         STEPNAME(geted32)
@@ -1448,6 +1454,7 @@ uintptr_t dynarec64_F20F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
 uintptr_t dynarec64_F30F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 uintptr_t dynarec64_AVX(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog);
 uintptr_t dynarec64_AVX_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog);
+uintptr_t dynarec64_AVX_66_0F3A(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, vex_t vex, int* ok, int* need_epilog);
 
 #if STEP < 2
 #define PASS2(A)
diff --git a/src/emu/x64runavx660f3a.c b/src/emu/x64runavx660f3a.c
index eca2dff0..2b112c4d 100644
--- a/src/emu/x64runavx660f3a.c
+++ b/src/emu/x64runavx660f3a.c
@@ -518,7 +518,7 @@ uintptr_t RunAVX_660F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
             ED->dword[0] = GX->ud[tmp8u&3];
             if(MODREG) ED->dword[1] = 0;
             break;
-        case 0x18:  /* VINSERTF128 Gx, Ex, imm8 */
+        case 0x18:  /* VINSERTF128 Gx, Vx, Ex, imm8 */
             nextop = F8;
             GETEX(1);
             GETGX;