diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-22 17:49:49 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-22 17:49:59 +0000 |
| commit | 1cd9fac9fb941c93fe8f0117cbfb673615862743 (patch) | |
| tree | f6f3b70153f2bbcad77cf4945f659771f20fb642 | |
| parent | f1a2a7cfe917fc69e91a6b68627bd4f7b1a0eaf4 (diff) | |
| download | box64-1cd9fac9fb941c93fe8f0117cbfb673615862743.tar.gz box64-1cd9fac9fb941c93fe8f0117cbfb673615862743.zip | |
[RV64_DYNAREC] Added F2 0F 10 and 11 opcodes
| -rwxr-xr-x | CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f20f.c | 124 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 5 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass3.h | 16 |
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":""); \ } |