diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 12:12:19 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-22 12:12:19 +0100 |
| commit | 23c9d574d9cc85f60ac0b81a24d50a8e80d93eb0 (patch) | |
| tree | 7bb45a879e0e7ce35764bbd0f1ce141197742273 | |
| parent | 5cc73fdf401a74871ecb1f355660bbfc1dda30c5 (diff) | |
| download | box64-23c9d574d9cc85f60ac0b81a24d50a8e80d93eb0.tar.gz box64-23c9d574d9cc85f60ac0b81a24d50a8e80d93eb0.zip | |
[DYNAREC] Added 64 31 opcode
| -rwxr-xr-x | CMakeLists.txt | 2 | ||||
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 1 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 3 | ||||
| -rw-r--r-- | src/dynarec/dynarec_arm64_64.c | 69 | ||||
| -rw-r--r-- | src/dynarec/dynarec_arm64_f0.c | 3 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.c | 32 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 30 |
7 files changed, 94 insertions, 46 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c12f1efb..f102dd7c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -252,7 +252,7 @@ if(ARM_DYNAREC) "${BOX64_ROOT}/src/dynarec/dynarec_arm64_pass.c" "${BOX64_ROOT}/src/dynarec/dynarec_arm64_00.c" "${BOX64_ROOT}/src/dynarec/dynarec_arm64_0f.c" - #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_64.c" + "${BOX64_ROOT}/src/dynarec/dynarec_arm64_64.c" #"${BOX64_ROOT}/src/dynarec/dynarec_arm64_65.c" "${BOX64_ROOT}/src/dynarec/dynarec_arm64_66.c" "${BOX64_ROOT}/src/dynarec/dynarec_arm64_67.c" diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 1ad5cebb..c94fe57f 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -219,6 +219,7 @@ #define LDRx_REG_UXTW3(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b11, Rm, 0b010, 1, Rn, Rt)) #define LDRw_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10, Rm, 0b011, 0, Rn, Rt)) #define LDRw_REG_LSL2(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10, Rm, 0b011, 1, Rn, Rt)) +#define LDRxw_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b10+rex.w, Rm, 0b011, 0, Rn, Rt)) #define LDRB_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt)) #define LDRH_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt)) diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 938fbaf0..5df9ab1b 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -543,6 +543,9 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } } break; + case 0x64: + addr = dynarec64_64(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); + break; case 0x66: addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); diff --git a/src/dynarec/dynarec_arm64_64.c b/src/dynarec/dynarec_arm64_64.c new file mode 100644 index 00000000..18517106 --- /dev/null +++ b/src/dynarec/dynarec_arm64_64.c @@ -0,0 +1,69 @@ +#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_arm64.h" +#include "dynarec_arm64_private.h" +#include "arm64_printer.h" + +#include "dynarec_arm64_helper.h" +#include "dynarec_arm64_functions.h" + + +uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) +{ + uint8_t opcode = F8; + uint8_t nextop, u8; + uint32_t u32; + int32_t i32, j32; + int16_t i16; + uint16_t u16; + uint8_t gd, ed; + uint8_t wback, wb1, wb2, gb1, gb2; + int fixedaddress; + MAYUSE(u16); + MAYUSE(u8); + MAYUSE(j32); + + while((opcode==0xF2) || (opcode==0xF3)) { + rep = opcode-0xF1; + opcode = F8; + } + // REX prefix before the F0 are ignored + rex.rex = 0; + while(opcode>=0x40 && opcode<=0x4f) { + rex.rex = opcode; + opcode = F8; + } + + switch(opcode) { + + case 0x33: + INST_NAME("XOR Gd, FS:Ed"); + SETFLAGS(X_ALL, SF_SET); + grab_segdata(dyn, addr, ninst, x4, _FS); + nextop = F8; + GETGD; + GETEDO(x4, 0); + emit_xor32(dyn, ninst, rex, gd, ed, x3, x4); + break; + + default: + DEFAULT; + } + return addr; +} + diff --git a/src/dynarec/dynarec_arm64_f0.c b/src/dynarec/dynarec_arm64_f0.c index 226a2b62..c4a0e9bf 100644 --- a/src/dynarec/dynarec_arm64_f0.c +++ b/src/dynarec/dynarec_arm64_f0.c @@ -38,9 +38,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MAYUSE(u8); MAYUSE(j32); - while((opcode==0x2E) || (opcode==0x66)) // ignoring CS: or multiple 0x66 - opcode = F8; - while((opcode==0xF2) || (opcode==0xF3)) { rep = opcode-0xF1; opcode = F8; diff --git a/src/dynarec/dynarec_arm64_helper.c b/src/dynarec/dynarec_arm64_helper.c index c752eb94..27447f7c 100755 --- a/src/dynarec/dynarec_arm64_helper.c +++ b/src/dynarec/dynarec_arm64_helper.c @@ -371,41 +371,21 @@ void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int save SET_NODF(); } -void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg) +void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment) { - MESSAGE(LOG_DUMP, "Get TLSData\n"); int32_t j32; MAYUSE(j32); + MESSAGE(LOG_DUMP, "Get %s Offset\n", (segment==_FS)?"FS":"GS"); int t1 = x1, t2 = x4; if(reg==t1) ++t1; if(reg==t2) ++t2; - LDRx_U12(t1, xEmu, offsetof(x64emu_t, context)); - LDRx_U12(t2, xEmu, offsetof(x64emu_t, segs_serial[_GS])); // complete check here - LDRx_U12(t1, t1, offsetof(box64context_t, sel_serial)); - LDRx_U12(reg, xEmu, offsetof(x64emu_t, segs_offs[_GS])); // no condition LDR - SUBx_REG(t1, t1, t2); - CBZx_MARKSEG(t1); - MOVZw(x1, _GS); - call_c(dyn, ninst, GetSegmentBaseEmu, t2, reg, 1, 0); - MARKSEG; - MESSAGE(LOG_DUMP, "----TLSData\n"); -} - -void grab_fsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg) -{ - int32_t j32; - MAYUSE(j32); - MESSAGE(LOG_DUMP, "Get FS: Offset\n"); - int t1 = x1, t2 = x4; - if(reg==t1) ++t1; - if(reg==t2) ++t2; - LDRx_U12(t2, xEmu, offsetof(x64emu_t, segs_serial[_FS]));// fast check here - LDRx_U12(reg, xEmu, offsetof(x64emu_t, segs_offs[_FS])); + LDRx_U12(t2, xEmu, offsetof(x64emu_t, segs_serial[segment]));// fast check here + LDRx_U12(reg, xEmu, offsetof(x64emu_t, segs_offs[segment])); CBZx_MARKSEG(t2); - MOVZw(x1, _FS); + MOVZw(x1, segment); call_c(dyn, ninst, GetSegmentBaseEmu, t2, reg, 1, 0); MARKSEG; - MESSAGE(LOG_DUMP, "----FS: Offset\n"); + MESSAGE(LOG_DUMP, "----%s Offset\n", (segment==_FS)?"FS":"GS"); } // x87 stuffs diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index e7c8e6ca..785c966c 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -66,7 +66,7 @@ ed = hint; \ } //GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI -#define GETEDW(hint, ret, D) if((nextop&0xC0)==0xC0) {\ +#define GETEDW(hint, ret, D) if(MODREG) { \ ed = xRAX+(nextop&7)+(rex.b<<3); \ MOVxw_REG(ret, ed); \ wback = 0; \ @@ -84,13 +84,13 @@ // Send back wb to either ed or wback #define SBACK(wb) if(wback) {STRxw(wb, wback, fixedaddress);} else {MOVxw_REG(ed, wb);} //GETEDO can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI -#define GETEDO(O) if((nextop&0xC0)==0xC0) { \ - ed = xRAX+(nextop&7)+(rex.b<<3); \ - wback = 0; \ - } else { \ - addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0); \ - LDR_REG_LSL_IMM5(x1, wback, O, 0); \ - ed = x1; \ +#define GETEDO(O, D) if(MODREG) { \ + ed = xRAX+(nextop&7)+(rex.b<<3); \ + wback = 0; \ + } else { \ + addr = geted(dyn, addr, ninst, nextop, &wback, x2, &fixedaddress, 0, 0, rex, 0, D); \ + LDRxw_REG(x1, wback, O); \ + ed = x1; \ } #define WBACKO(O) if(wback) {STR_REG_LSL_IMM5(ed, wback, O, 0);} //FAKEELike GETED, but doesn't get anything @@ -521,8 +521,8 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define dynarec64_00 STEPNAME(dynarec64_00) #define dynarec64_0F STEPNAME(dynarec64_0F) -#define dynarec64_FS STEPNAME(dynarec64_FS) -#define dynarec64_GS STEPNAME(dynarec64_GS) +#define dynarec64_64 STEPNAME(dynarec64_64) +#define dynarec64_65 STEPNAME(dynarec64_65) #define dynarec64_66 STEPNAME(dynarec64_66) #define dynarec64_67 STEPNAME(dynarec64_67) #define dynarec64_D8 STEPNAME(dynarec64_D8) @@ -546,8 +546,7 @@ void* arm64_next(x64emu_t* emu, uintptr_t addr); #define retn_to_epilog STEPNAME(retn_to_epilog_) #define iret_to_epilog STEPNAME(iret_to_epilog_) #define call_c STEPNAME(call_c_) -#define grab_fsdata STEPNAME(grab_fsdata_) -#define grab_tlsdata STEPNAME(grab_tlsdata_) +#define grab_segdata STEPNAME(grab_segdata_) #define emit_cmp8 STEPNAME(emit_cmp8) #define emit_cmp16 STEPNAME(emit_cmp16) #define emit_cmp32 STEPNAME(emit_cmp32) @@ -660,8 +659,7 @@ void ret_to_epilog(dynarec_arm_t* dyn, int ninst); void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n); void iret_to_epilog(dynarec_arm_t* dyn, int ninst); void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg); -//void grab_fsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg); -//void grab_tlsdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg); +void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment); void emit_cmp8(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_cmp16(dynarec_arm_t* dyn, int ninst, int s1, int s2, int s3, int s4, int s5); void emit_cmp32(dynarec_arm_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3, int s4, int s5); @@ -787,8 +785,8 @@ void fpu_popcache(dynarec_arm_t* dyn, int ninst, int s1); uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, int* ok, int* need_epilog); uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); -//uintptr_t dynarec64_FS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); -//uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); +uintptr_t dynarec64_64(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); +//uintptr_t dynarec64_65(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep,int* ok, int* need_epilog); uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); |