about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-27 09:53:49 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-27 09:53:49 +0200
commitaaed0364bdef43b6c83cfe647a341b84227c742e (patch)
tree1b13190706a0115996a8398181bb1ae8256a69d6 /src
parent9e0139f3c3245b309b8ca1e7856fd27df3a99630 (diff)
downloadbox64-aaed0364bdef43b6c83cfe647a341b84227c742e.tar.gz
box64-aaed0364bdef43b6c83cfe647a341b84227c742e.zip
[INTERPRETER] Added avx (66 0F 3A) 44 opcode
Diffstat (limited to 'src')
-rw-r--r--src/emu/x64run.c18
-rw-r--r--src/emu/x64run_private.h5
-rw-r--r--src/emu/x64runavx.c4
-rw-r--r--src/emu/x64runavx0f.c6
-rw-r--r--src/emu/x64runavx660f3a.c92
-rw-r--r--src/emu/x64runavxf20f.c65
-rw-r--r--src/emu/x64runavxf30f.c5
7 files changed, 181 insertions, 14 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index ef2f550a..7ae7f55e 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -31,20 +31,20 @@ int my_setcontext(x64emu_t* emu, void* ucp);
 static const char* avx_prefix_string(uint16_t p)
 {
     switch(p) {
-        case 0: return "0";
-        case 1: return "66";
-        case 2: return "F3";
-        case 3: return "F2";
+        case VEX_P_NONE: return "0";
+        case VEX_P_66: return "66";
+        case VEX_P_F2: return "F2";
+        case VEX_P_F3: return "F3";
         default: return "??";
     }
 }
 static const char* avx_map_string(uint16_t m)
 {
     switch(m) {
-        case 0: return "0";
-        case 1: return "0F";
-        case 2: return "0F38";
-        case 3: return "0F3A";
+        case VEX_M_NONE: return "0";
+        case VEX_M_0F: return "0F";
+        case VEX_M_OF38: return "0F38";
+        case VEX_M_0F3A: return "0F3A";
         default: return "??";
     }
 }
@@ -1391,7 +1391,7 @@ x64emurun:
                     unimp = 1;
                 #else
                 if(!(addr = RunAVX(emu, vex, addr, &step))) {
-                    printf_log(LOG_NONE, "Unimplemented AVX opcode prefix %s map %s ", avx_prefix_string(vex.p), avx_prefix_string(vex.m));
+                    printf_log(LOG_NONE, "Unimplemented AVX opcode prefix %s map %s ", avx_prefix_string(vex.p), avx_map_string(vex.m));
                     unimp = 1;
                     goto fini;
                 }
diff --git a/src/emu/x64run_private.h b/src/emu/x64run_private.h
index d739506b..e14d3945 100644
--- a/src/emu/x64run_private.h
+++ b/src/emu/x64run_private.h
@@ -175,8 +175,9 @@ uintptr_t RunF30F(x64emu_t *emu, rex_t rex, uintptr_t addr);
 uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step);
 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_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);
 uintptr_t Test64(x64test_t *test, rex_t rex, int seg, uintptr_t addr);
@@ -208,7 +209,9 @@ uintptr_t TestF30F(x64test_t *test, rex_t rex, uintptr_t addr);
 uintptr_t TestAVX(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 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_F3OF3A(x64test_t *test, vex_t vex, uintptr_t addr, int *step);
 
 
 void x64Syscall(x64emu_t *emu);
diff --git a/src/emu/x64runavx.c b/src/emu/x64runavx.c
index 3afd2b66..53027fc2 100644
--- a/src/emu/x64runavx.c
+++ b/src/emu/x64runavx.c
@@ -55,8 +55,12 @@ uintptr_t RunAVX(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
         return RunAVX_0F(emu, vex, addr, step);
     if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_66))
         return RunAVX_660F(emu, vex, addr, step);
+    if( (vex.m==VEX_M_0F) && (vex.p==VEX_P_F2))
+        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_0F3A) && (vex.p==VEX_P_66))
+        return RunAVX_660F3A(emu, vex, addr, step);
 
     return 0;
 }
diff --git a/src/emu/x64runavx0f.c b/src/emu/x64runavx0f.c
index c2f76348..d7313074 100644
--- a/src/emu/x64runavx0f.c
+++ b/src/emu/x64runavx0f.c
@@ -45,14 +45,16 @@ uintptr_t RunAVX_0F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     uint64_t tmp64u, tmp64u2;
     int64_t tmp64s;
     reg64_t *oped, *opgd;
-    sse_regs_t *opex, *opgx, eax1;
-    mmx87_regs_t *opem, *opgm, eam1;
+    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 0x77:
diff --git a/src/emu/x64runavx660f3a.c b/src/emu/x64runavx660f3a.c
new file mode 100644
index 00000000..3f0d4170
--- /dev/null
+++ b/src/emu/x64runavx660f3a.c
@@ -0,0 +1,92 @@
+#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"
+
+static __int128_t pclmul_helper(uint64_t X, uint64_t Y)
+{
+    __int128 result = 0;
+    __int128 op2 = Y;
+    for (int i=0; i<64; ++i)
+        if(X&(1LL<<i))
+            result ^= (op2<<i);
+
+    return result;
+}
+
+#ifdef TEST_INTERPRETER
+uintptr_t TestAVX_660F3A(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
+#else
+uintptr_t RunAVX_660F3A(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 0x44:    /* VPCLMULQDQ Gx, Vx, Ex, imm8 */
+            nextop = F8;
+            GETGX;
+            GETEX(1);
+            GETVX;
+            GETGY;
+            tmp8u = F8;
+            GX->u128 = pclmul_helper(VX->q[tmp8u&1], EX->q[(tmp8u>>4)&1]);
+            if(vex.l) {
+                GETVY;
+                GETEY;
+                GY->u128 = pclmul_helper(VY->q[tmp8u&1], EY->q[(tmp8u>>4)&1]);
+            } else
+                GY->q[0] = GY->q[1] = 0;
+            break;
+
+        default:
+            return 0;
+    }
+    return addr;
+}
diff --git a/src/emu/x64runavxf20f.c b/src/emu/x64runavxf20f.c
new file mode 100644
index 00000000..6048aeb9
--- /dev/null
+++ b/src/emu/x64runavxf20f.c
@@ -0,0 +1,65 @@
+#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_F20F(x64test_t *test, vex_t vex, uintptr_t addr, int *step)
+#else
+uintptr_t RunAVX_F20F(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) {
+
+        default:
+            return 0;
+    }
+    return addr;
+}
diff --git a/src/emu/x64runavxf30f.c b/src/emu/x64runavxf30f.c
index 8e3b964d..bfee9b13 100644
--- a/src/emu/x64runavxf30f.c
+++ b/src/emu/x64runavxf30f.c
@@ -45,8 +45,8 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
     uint64_t tmp64u, tmp64u2;
     int64_t tmp64s;
     reg64_t *oped, *opgd;
-    sse_regs_t *opex, *opgx, eax1;
-    sse_regs_t *opey, *opgy, eay1;
+    sse_regs_t *opex, *opgx, *opvx, eax1;
+    sse_regs_t *opey, *opgy, *opvy, eay1;
 
 
 #ifdef TEST_INTERPRETER
@@ -72,6 +72,7 @@ uintptr_t RunAVX_F30F(x64emu_t *emu, vex_t vex, uintptr_t addr, int *step)
                     memset(GY, 0, 16);
             }
             break;
+
         default:
             return 0;
     }