From ebaedca7084932d1d101614dd20dd534804f867e Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sun, 3 Mar 2024 01:26:07 +0800 Subject: [LA64_DYNAREC] Added more opcodes (#1313) * [LA64_DYNAREC] Added F30F 1E NOP opcode * [LA64_DYNAREC] Added E9/EB JMP opcodes --- src/dynarec/la64/dynarec_la64_00.c | 38 +++++++++++++++++++++ src/dynarec/la64/dynarec_la64_f30f.c | 60 ++++++++++++++++++++++++++++++++++ src/dynarec/la64/dynarec_la64_helper.h | 11 ++++++- 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 src/dynarec/la64/dynarec_la64_f30f.c (limited to 'src') diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 7a5eb0f6..9616a1e1 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -103,6 +103,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni i64 = F32S; emit_add32c(dyn, ninst, rex, xRAX, i64, x3, x4, x5, x6); break; + case 0x0F: + switch (rep) { + case 2: + addr = dynarec64_F30F(dyn, addr, ip, ninst, rex, ok, need_epilog); + break; + default: + DEFAULT; + } + break; case 0x28: INST_NAME("SUB Eb, Gb"); SETFLAGS(X_ALL, SF_SET_PENDING); @@ -364,6 +373,35 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } } break; + case 0xE9: + case 0xEB: + BARRIER(BARRIER_MAYBE); + if (opcode == 0xE9) { + INST_NAME("JMP Id"); + i32 = F32S; + } else { + INST_NAME("JMP Ib"); + i32 = F8S; + } + JUMP((uintptr_t)getAlternate((void*)(addr + i32)), 0); + if (dyn->insts[ninst].x64.jmp_insts == -1) { + // out of the block + fpu_purgecache(dyn, ninst, 1, x1, x2, x3); + jump_to_next(dyn, (uintptr_t)getAlternate((void*)(addr + i32)), 0, ninst, rex.is32bits); + } else { + // inside the block + CacheTransform(dyn, ninst, CHECK_CACHE(), x1, x2, x3); + tmp = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address - (dyn->native_size); + MESSAGE(1, "Jump to %d / 0x%x\n", tmp, tmp); + if (tmp == 4) { + NOP(); + } else { + B(tmp); + } + } + *need_epilog = 0; + *ok = 0; + break; case 0xFF: nextop = F8; switch ((nextop >> 3) & 7) { diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c new file mode 100644 index 00000000..107e5f38 --- /dev/null +++ b/src/dynarec/la64/dynarec_la64_f30f.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include + +#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 "bitutils.h" + +#include "la64_printer.h" +#include "dynarec_la64_private.h" +#include "dynarec_la64_functions.h" +#include "dynarec_la64_helper.h" + +uintptr_t dynarec64_F30F(dynarec_la64_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, u8; + uint8_t gd, ed; + uint8_t wback, gback; + uint64_t u64; + int v0, v1; + int q0, q1; + int d0, d1; + int64_t fixedaddress, gdoffset; + int unscaled; + int64_t j64; + + MAYUSE(d0); + MAYUSE(d1); + MAYUSE(q0); + MAYUSE(q1); + MAYUSE(v0); + MAYUSE(v1); + MAYUSE(j64); + + switch (opcode) { + case 0x1E: + INST_NAME("NOP / ENDBR32 / ENDBR64"); + nextop = F8; + FAKEED; + break; + default: + DEFAULT; + } + return addr; +} \ No newline at end of file diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 9bd7ef04..e1088ec9 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -107,6 +107,13 @@ ed = x1; \ } +// FAKEED like GETED, but doesn't get anything +#define FAKEED \ + if (!MODREG) { \ + addr = fakeed(dyn, addr, ninst, nextop); \ + } + + // Write back ed in wback (if wback not 0) #define WBACK \ if (wback) { \ @@ -432,7 +439,8 @@ void* la64_next(x64emu_t* emu, uintptr_t addr); #define native_pass STEPNAME(native_pass) -#define dynarec64_00 STEPNAME(dynarec64_00) +#define dynarec64_00 STEPNAME(dynarec64_00) +#define dynarec64_F30F STEPNAME(dynarec64_F30F) #define geted STEPNAME(geted) #define geted32 STEPNAME(geted32) @@ -519,6 +527,7 @@ void CacheTransform(dynarec_la64_t* dyn, int ninst, int cacheupd, int s1, int s2 #endif uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); +uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); #if STEP < 3 #define PASS3(A) -- cgit 1.4.1