about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-22 17:49:49 +0000
committerptitSeb <sebastien.chev@gmail.com>2023-03-22 17:49:59 +0000
commit1cd9fac9fb941c93fe8f0117cbfb673615862743 (patch)
treef6f3b70153f2bbcad77cf4945f659771f20fb642
parentf1a2a7cfe917fc69e91a6b68627bd4f7b1a0eaf4 (diff)
downloadbox64-1cd9fac9fb941c93fe8f0117cbfb673615862743.tar.gz
box64-1cd9fac9fb941c93fe8f0117cbfb673615862743.zip
[RV64_DYNAREC] Added F2 0F 10 and 11 opcodes
-rwxr-xr-xCMakeLists.txt2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_f20f.c124
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h5
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass3.h16
6 files changed, 149 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9a8806f3..d8b0354c 100755
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -626,7 +626,7 @@ if(RV64_DYNAREC)
     "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_660f.c"
     #"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_6664.c"
     #"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_66f0.c"
-    #"${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_f20f.c"
+    "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_f20f.c"
     "${BOX64_ROOT}/src/dynarec/rv64/dynarec_rv64_f30f.c"
     )
 endif()
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index 726f9edb..c0416ceb 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -111,6 +111,9 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             case 0:
                 addr = dynarec64_0F(dyn, addr, ip, ninst, rex, ok, need_epilog);
                 break;
+            case 1:
+                addr = dynarec64_F20F(dyn, addr, ip, ninst, rex, ok, need_epilog);
+                break;
             case 2:
                 addr = dynarec64_F30F(dyn, addr, ip, ninst, rex, ok, need_epilog);
                 break;
diff --git a/src/dynarec/rv64/dynarec_rv64_f20f.c b/src/dynarec/rv64/dynarec_rv64_f20f.c
new file mode 100644
index 00000000..b6bc6086
--- /dev/null
+++ b/src/dynarec/rv64/dynarec_rv64_f20f.c
@@ -0,0 +1,124 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <pthread.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 "rv64_printer.h"
+#include "dynarec_rv64_private.h"
+#include "dynarec_rv64_functions.h"
+#include "dynarec_rv64_helper.h"
+
+uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
+{
+    (void)ip; (void)need_epilog;
+
+    uint8_t opcode = F8;
+    uint8_t nextop;
+    uint8_t gd, ed;
+    uint8_t wback;
+    uint8_t u8;
+    uint64_t u64, j64;
+    int v0, v1;
+    int q0;
+    int d0, d1;
+    int64_t fixedaddress;
+    int unscaled;
+
+    MAYUSE(d0);
+    MAYUSE(d1);
+    MAYUSE(q0);
+    MAYUSE(v0);
+    MAYUSE(v1);
+
+    switch(opcode) {
+
+        case 0x10:
+            INST_NAME("MOVSD Gx, Ex");
+            nextop = F8;
+            GETG;
+            if(MODREG) {
+                ed = (nextop&7)+ (rex.b<<3);
+                v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
+                d0 = sse_get_reg(dyn, ninst, x1, ed, 0);
+                FMVD(v0, d0);
+            } else {
+                SMREAD();
+                v0 = sse_get_reg_empty(dyn, ninst, x1, gd, 0);
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                FLD(v0, ed, fixedaddress);
+                // reset upper part
+                SD(xZR, xEmu, offsetof(x64emu_t, xmm[gd])+8);
+            }
+            break;
+        case 0x11:
+            INST_NAME("MOVSD Ex, Gx");
+            nextop = F8;
+            GETG;
+            v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
+            if(MODREG) {
+                ed = (nextop&7)+ (rex.b<<3);
+                d0 = sse_get_reg(dyn, ninst, x1, ed, 0);
+                FMVD(d0, v0);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                FSD(v0, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
+
+        case 0x38:  // these are some more SSSE4.2+ opcodes
+            opcode = F8;
+            switch(opcode) {
+
+                case 0xF0:
+                    INST_NAME("(unsupported) CRC32 Gd, Eb)");
+                    nextop = F8;
+                    addr = fakeed(dyn, addr, ninst, nextop);
+                    SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+                    GETIP(ip);
+                    STORE_XEMU_CALL();
+                    CALL(native_ud, -1);
+                    LOAD_XEMU_CALL();
+                    jump_to_epilog(dyn, 0, xRIP, ninst);
+                    *need_epilog = 0;
+                    *ok = 0;
+                    break;
+                case 0xF1:
+                    INST_NAME("(unsupported) CRC32 Gd, Ed)");
+                    nextop = F8;
+                    addr = fakeed(dyn, addr, ninst, nextop);
+                    SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
+                    GETIP(ip);
+                    STORE_XEMU_CALL();
+                    CALL(native_ud, -1);
+                    LOAD_XEMU_CALL();
+                    jump_to_epilog(dyn, 0, xRIP, ninst);
+                    *need_epilog = 0;
+                    *ok = 0;
+                    break;
+
+                default:
+                    DEFAULT;
+            }
+            break;
+
+
+        default:
+            DEFAULT;
+    }
+    return addr;
+}
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index f402cf45..86533a16 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -1113,7 +1113,7 @@ int sse_get_reg_empty(dynarec_rv64_t* dyn, int ninst, int s1, int a, int single)
         return dyn->e.ssecache[a].reg;
     }
     dyn->e.ssecache[a].reg = fpu_get_reg_xmm(dyn, single?EXT_CACHE_SS:EXT_CACHE_SD, a);
-    dyn->e.ssecache[a].single = 1; // it will be write...
+    dyn->e.ssecache[a].single = single;
     return dyn->e.ssecache[a].reg;
 }
 // forget ext register for a SSE reg, create the entry if needed
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index fbb61e73..39bbc507 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -269,6 +269,9 @@
     BEQZ(s, 8);                     \
     SUB(r, xZR, r);                 \
 
+// Generic get GD, but reg value in gd (R_RAX is not added)
+#define GETG        gd = ((nextop&0x38)>>3)+(rex.r<<3)
+
 // CALL will use x6 for the call address. Return value can be put in ret (unless ret is -1)
 // R0 will not be pushed/popd if ret is -2
 #define CALL(F, ret) call_c(dyn, ninst, F, x6, ret, 1, 0)
@@ -916,7 +919,7 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 //uintptr_t dynarec64_6664(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int seg, int* ok, int* need_epilog);
 //uintptr_t dynarec64_66F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog);
-//uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
+uintptr_t dynarec64_F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog);
 
 #if STEP < 2
diff --git a/src/dynarec/rv64/dynarec_rv64_pass3.h b/src/dynarec/rv64/dynarec_rv64_pass3.h
index dac190cd..9c9fac54 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass3.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass3.h
@@ -53,6 +53,22 @@
             dynarec_log(LOG_NONE, ", jmp=out");                                         \
         if(dyn->last_ip)                                                                \
             dynarec_log(LOG_NONE, ", last_ip=%p", (void*)dyn->last_ip);                 \
+        for(int ii=0; ii<24; ++ii) {            \
+            switch(dyn->insts[ninst].e.extcache[ii].t) {    \
+                case EXT_CACHE_ST_D: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].e.extcache[ii].t, dyn->insts[ninst].e.extcache[ii].n)); break;  \
+                case EXT_CACHE_ST_F: dynarec_log(LOG_NONE, " S%d:%s", ii, getCacheName(dyn->insts[ninst].e.extcache[ii].t, dyn->insts[ninst].e.extcache[ii].n)); break;  \
+                case EXT_CACHE_MM: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].e.extcache[ii].t, dyn->insts[ninst].e.extcache[ii].n)); break;    \
+                case EXT_CACHE_SS: dynarec_log(LOG_NONE, " S%d:%s", ii, getCacheName(dyn->insts[ninst].e.extcache[ii].t, dyn->insts[ninst].e.extcache[ii].n)); break;  \
+                case EXT_CACHE_SD: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].e.extcache[ii].t, dyn->insts[ninst].e.extcache[ii].n)); break;  \
+                case EXT_CACHE_SCR: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].e.extcache[ii].t, dyn->insts[ninst].e.extcache[ii].n)); break;   \
+                case EXT_CACHE_NONE:           \
+                default:    break;              \
+            }                                   \
+        }                                       \
+        if(dyn->e.stack || dyn->insts[ninst].e.stack_next || dyn->insts[ninst].e.x87stack)     \
+            dynarec_log(LOG_NONE, " X87:%d/%d(+%d/-%d)%d", dyn->e.stack, dyn->insts[ninst].e.stack_next, dyn->insts[ninst].e.stack_push, dyn->insts[ninst].e.stack_pop, dyn->insts[ninst].e.x87stack); \
+        if(dyn->insts[ninst].e.combined1 || dyn->insts[ninst].e.combined2)                     \
+            dynarec_log(LOG_NONE, " %s:%d/%d", dyn->insts[ninst].e.swapped?"SWP":"CMB", dyn->insts[ninst].e.combined1, dyn->insts[ninst].e.combined2);   \
         dynarec_log(LOG_NONE, "%s\n", (box64_dynarec_dump>1)?"\e[m":"");                \
     }