about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-27 10:23:56 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-27 10:23:56 +0200
commit10200d7b5529b9c6fc4f2f8e59997ee15d4028af (patch)
tree854ae3723e8e618491591a00d556953a773dad7e /src
parent1eab6a0c8e40341f7cabc02f8106cd159b1dcf99 (diff)
downloadbox64-10200d7b5529b9c6fc4f2f8e59997ee15d4028af.tar.gz
box64-10200d7b5529b9c6fc4f2f8e59997ee15d4028af.zip
[INTERPRETER] Added avx (66 0F 38) 00 opcode
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run.c2
-rw-r--r--src/emu/x64run_private.h4
-rw-r--r--src/emu/x64runavx.c2
-rw-r--r--src/emu/x64runavx660f38.c97
4 files changed, 103 insertions, 2 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 7ae7f55e..35b84a48 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -43,7 +43,7 @@ static const char* avx_map_string(uint16_t m)
     switch(m) {
         case VEX_M_NONE: return "0";
         case VEX_M_0F: return "0F";
-        case VEX_M_OF38: return "0F38";
+        case VEX_M_0F38: return "0F38";
         case VEX_M_0F3A: return "0F3A";
         default: return "??";
     }
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index e14d3945..d33d39ae 100644
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -27,7 +27,7 @@ typedef struct rex_s {
 #define VEX_P_F2    3
 #define VEX_M_NONE  0
 #define VEX_M_0F    1
-#define VEX_M_OF38  2
+#define VEX_M_0F38  2
 #define VEX_M_0F3A  3
 typedef struct vex_s {
     rex_t       rex;
@@ -177,6 +177,7 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
 uintptr_t RunAVX_660F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
 uintptr_t RunAVX_F20F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
 uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
+uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
 uintptr_t RunAVX_660F3A(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
 
 uintptr_t Test0F(x64test_t *test, rex_t rex, uintptr_t addr, int *step);
@@ -211,6 +212,7 @@ uintptr_t TestAVX_OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 uintptr_t TestAVX_66OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 uintptr_t TestAVX_F2OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 uintptr_t TestAVX_F3OF(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
+uintptr_t TestAVX_F3OF38(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 uintptr_t TestAVX_F3OF3A(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 
 
diff --git a/src/emu/x64runavx.c b/src/emu/x64runavx.c
index 53027fc2..f51203a2 100644
--- a/src/emu/x64runavx.c
+++ b/src/emu/x64runavx.c
@@ -59,6 +59,8 @@ uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
         return RunAVX_F20F(emu, vex, addr, step);
     if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F3))
         return RunAVX_F30F(emu, vex, addr, step);
+    if( (vex.m==VEX_M_0F38) && (vex.p==VEX_P_66))
+        return RunAVX_660F38(emu, vex, addr, step);
     if( (vex.m==VEX_M_0F3A) && (vex.p==VEX_P_66))
         return RunAVX_660F3A(emu, vex, addr, step);
 
diff --git a/src/emu/x64runavx660f38.c b/src/emu/x64runavx660f38.c
new file mode 100644
index 00000000..f77253ba
--- /dev/null
+++ b/src/emu/x64runavx660f38.c
@@ -0,0 +1,97 @@
+#define _GNU_SOURCE
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <fenv.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "debug.h"
+#include "box64stack.h"
+#include "x64emu.h"
+#include "x64run.h"
+#include "x64emu_private.h"
+#include "x64run_private.h"
+#include "x64primop.h"
+#include "x64trace.h"
+#include "x87emu_private.h"
+#include "box64context.h"
+#include "my_cpuid.h"
+#include "bridge.h"
+#include "signals.h"
+#include "x64shaext.h"
+#ifdef DYNAREC
+#include "custommem.h"
+#include "../dynarec/native_lock.h"
+#endif
+
+#include "modrm.h"
+
+#ifdef TEST_INTERPRETER
+uintptr_t TestAVX_660F38(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
+#else
+uintptr_t RunAVX_660F38(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
+#endif
+{
+    uint8_t opcode;
+    uint8_t nextop;
+    uint8_t tmp8u;
+    int8_t tmp8s;
+    int32_t tmp32s, tmp32s2;
+    uint32_t tmp32u, tmp32u2;
+    uint64_t tmp64u, tmp64u2;
+    int64_t tmp64s;
+    reg64_t *oped, *opgd;
+    sse_regs_t *opex, *opgx, *opvx, eax1;
+    sse_regs_t *opey, *opgy, *opvy, eay1;
+
+
+#ifdef TEST_INTERPRETER
+    x64emu_t *emu = test->emu;
+#endif
+    opcode = F8;
+
+    rex_t rex = vex.rex;
+
+    switch(opcode) {
+        case 0x00:  /* VPSHUFB Gx, Vx, Ex */
+            nextop = F8;
+            GETEX(0);
+            GETGX;
+            GETVX;
+            GETGY;
+            GETVY;
+            if(VX==GX) {
+                eax1 = *VX;
+                VX = &eax1;
+            }
+            for (int i=0; i<16; ++i) {
+                if(EX->ub[i]&128)
+                    GX->ub[i] = 0;
+                else
+                    GX->ub[i] = VX->ub[EX->ub[i]&15];
+            }
+            if(vex.l) {
+                GETEY;
+                if(VY==GY) {
+                    eay1 = *VY;
+                    VY = &eay1;
+                }
+                for (int i=0; i<16; ++i) {
+                    if(EX->ub[i]&128)
+                        GY->ub[i] = 0;
+                    else
+                        GY->ub[i] = VY->ub[EY->ub[i]&15];
+                }
+            } else
+                GY->q[0] = GY->q[1] = 0;
+            break;
+
+        default:
+            return 0;
+    }
+    return addr;
+}