diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 34 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 17 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 16 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_pass2.h | 28 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_pass3.h | 29 | ||||
| -rw-r--r-- | src/tools/env.c | 2 |
6 files changed, 93 insertions, 33 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 2d9b1e6e..23fd9004 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -2369,7 +2369,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni #endif } #if STEP < 2 - if (!rex.is32bits && IsNativeCall(addr + i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn)) + if (!rex.is32bits && !dyn->need_reloc && IsNativeCall(addr + i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn)) tmp = dyn->insts[ninst].pass2choice = 3; else tmp = dyn->insts[ninst].pass2choice = i32 ? 0 : 1; @@ -2381,10 +2381,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags to "dont'care" state SKIPTEST(x1); BARRIER(BARRIER_FULL); - if (dyn->last_ip && (addr - dyn->last_ip < 0x800)) { + if (dyn->last_ip && ((addr - dyn->last_ip < 0x800) || (dyn->last_ip - addr < 0x800))) { ADDI_D(x2, xRIP, addr - dyn->last_ip); } else { - MOV64x(x2, addr); + if (dyn->need_reloc) { + TABLE64(x2, addr); + } else { + MOV64x(x2, addr); + } } PUSH1(x2); MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall - 1)), dyn->insts[ninst].retn); @@ -2402,7 +2406,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // x87_purgecache(dyn, ninst, 0, x3, x1, x4); if ((BOX64ENV(log) < 2 && !BOX64ENV(rolling_log)) && dyn->insts[ninst].natcall && tmp) { // GETIP(ip+3+8+8, x7); // read the 0xCC - // FIXME: call_n(dyn, ninst, *(void**)(dyn->insts[ninst].natcall + 2 + 8), tmp); + // FIXME: call_n(dyn, ninst, (void*)(dyn->insts[ninst].natcall + 2 + 8), tmp); POP1(xRIP); // pop the return address dyn->last_ip = addr; } else { @@ -2432,7 +2436,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; case 1: // this is call to next step, so just push the return address to the stack - MOV64x(x2, addr); + if (dyn->need_reloc) { + TABLE64(x2, addr); + } else { + MOV64x(x2, addr); + } PUSH1z(x2); break; default: @@ -2442,7 +2450,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags to "dont'care" state } // regular call - MOV64x(x2, addr); + if (dyn->need_reloc) { + TABLE64(x2, addr); + } else { + MOV64x(x2, addr); + } fpu_purgecache(dyn, ninst, 1, x1, x3, x4); PUSH1z(x2); if (BOX64DRENV(dynarec_callret)) { @@ -2476,7 +2488,12 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // jumps out of current dynablock... MARK; j64 = getJumpTableAddress64(addr); - MOV64x(x4, j64); + if (dyn->need_reloc) { + AddRelocTable64JmpTbl(dyn, ninst, addr, STEP); + TABLE64_(x4, j64); + } else { + MOV64x(x4, j64); + } LD_D(x4, x4, 0); BR(x4); } @@ -2872,7 +2889,8 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // jumps out of current dynablock... MARK; j64 = getJumpTableAddress64(addr); - TABLE64(x4, j64); + if (dyn->need_reloc) AddRelocTable64RetEndBlock(dyn, ninst, addr, STEP); + TABLE64_(x4, j64); LD_D(x4, x4, 0); BR(x4); } diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index bd925559..4fb7f95e 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -102,7 +102,7 @@ uintptr_t geted(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, } else if ((tmp >= -2048) && (tmp <= maxval)) { GETIP(addr + delta, scratch); ADDI_D(ret, xRIP, tmp); - } else if (tmp + addr + delta < 0x100000000LL) { + } else if (tmp + addr + delta < 0x80000000LL && !dyn->need_reloc) { MOV64x(ret, tmp + addr + delta); } else { if (adj) { @@ -533,7 +533,11 @@ static int indirect_lookup(dynarec_la64_t* dyn, int ninst, int is32bits, int s1, if (!is32bits) { SRLI_D(s1, xRIP, 48); BNEZ_safe(s1, (intptr_t)dyn->jmp_next - (intptr_t)dyn->block); - MOV64x(s2, getConst(const_jmptbl48)); + if (dyn->need_reloc) { + TABLE64C(s2, const_jmptbl48); + } else { + MOV64x(s2, getConst(const_jmptbl48)); + } BSTRPICK_D(s1, xRIP, JMPTABL_START2 + JMPTABL_SHIFT2 - 1, JMPTABL_START2); ALSL_D(s2, s1, s2, 3); LD_D(s2, s2, 0); @@ -570,7 +574,8 @@ void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is3 uintptr_t p = getJumpTableAddress64(ip); MAYUSE(p); GETIP_(ip, x3); - TABLE64(x3, p); + if (dyn->need_reloc) AddRelocTable64JmpTbl(dyn, ninst, ip, STEP); + TABLE64_(x3, p); LD_D(x2, x3, 0); dest = x2; } @@ -675,7 +680,11 @@ void iret_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is64bits) // set new RSP MV(xRSP, x3); // Ret.... - MOV64x(x2, getConst(const_epilog)); // epilog on purpose, CS might have changed! + // epilog on purpose, CS might have changed! + if (dyn->need_reloc) + TABLE64C(x2, const_epilog); + else + MOV64x(x2, getConst(const_epilog)); SMEND(); BR(x2); CLEARIP(); diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index acd22031..9720cf25 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -1026,6 +1026,10 @@ #define TABLE64C(A, V) #endif +#ifndef TABLE64_ +#define TABLE64_(A, V) +#endif + #define ARCH_INIT() SMSTART() #define ARCH_RESET() @@ -1039,7 +1043,11 @@ do { \ ssize_t _delta_ip = (ssize_t)(A) - (ssize_t)dyn->last_ip; \ if (!dyn->last_ip) { \ - MOV64x(xRIP, A); \ + if (dyn->need_reloc) { \ + TABLE64(xRIP, (A)); \ + } else { \ + MOV64x(xRIP, (A)); \ + } \ } else if (_delta_ip == 0) { \ } else if (_delta_ip >= -2048 && _delta_ip < 2048) { \ ADDI_D(xRIP, xRIP, _delta_ip); \ @@ -1050,7 +1058,11 @@ MOV32w(scratch, _delta_ip); \ ADD_D(xRIP, xRIP, scratch); \ } else { \ - MOV64x(xRIP, (A)); \ + if (dyn->need_reloc) { \ + TABLE64(xRIP, (A)); \ + } else { \ + MOV64x(xRIP, (A)); \ + } \ } \ } while (0) #define GETIP(A, scratch) \ diff --git a/src/dynarec/la64/dynarec_la64_pass2.h b/src/dynarec/la64/dynarec_la64_pass2.h index 9b5400d9..eb722e42 100644 --- a/src/dynarec/la64/dynarec_la64_pass2.h +++ b/src/dynarec/la64/dynarec_la64_pass2.h @@ -19,15 +19,25 @@ } #define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size; #define INST_NAME(name) -#define TABLE64(A, V) \ - { \ +#define TABLE64(A, V) \ + do { \ + if (dyn->need_reloc && !isTable64(dyn, (V))) \ + AddRelocTable64Addr(dyn, ninst, (V), 2); \ + Table64(dyn, (V), 2); \ + EMIT(0); \ + EMIT(0); \ + } while (0) +#define TABLE64_(A, V) \ + do { \ Table64(dyn, (V), 2); \ EMIT(0); \ EMIT(0); \ - } -#define TABLE64C(A, V) \ - { \ - Table64(dyn, getConst(V), 2); \ - EMIT(0); \ - EMIT(0); \ - } + } while (0) +#define TABLE64C(A, V) \ + do { \ + if (dyn->need_reloc && !isTable64(dyn, getConst(V))) \ + AddRelocTable64Const(dyn, ninst, (V), 2); \ + Table64(dyn, getConst(V), 2); \ + EMIT(0); \ + EMIT(0); \ + } while (0) diff --git a/src/dynarec/la64/dynarec_la64_pass3.h b/src/dynarec/la64/dynarec_la64_pass3.h index 7a21b637..8188e761 100644 --- a/src/dynarec/la64/dynarec_la64_pass3.h +++ b/src/dynarec/la64/dynarec_la64_pass3.h @@ -25,16 +25,27 @@ #define INST_EPILOG #define INST_NAME(name) inst_name_pass3(dyn, ninst, name, rex) #define TABLE64(A, V) \ - { \ + do { \ + if (dyn->need_reloc && !isTable64(dyn, (V))) \ + AddRelocTable64Addr(dyn, ninst, (V), 3); \ int val64offset = Table64(dyn, (V), 3); \ MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); \ PCADDU12I(A, SPLIT20(val64offset)); \ LD_D(A, A, SPLIT12(val64offset)); \ - } -#define TABLE64C(A, V) \ - { \ - int val64offset = Table64(dyn, getConst(V), 3); \ - MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); \ - PCADDU12I(A, SPLIT20(val64offset)); \ - LD_D(A, A, SPLIT12(val64offset)); \ - } + } while (0) +#define TABLE64_(A, V) \ + do { \ + int val64offset = Table64(dyn, (V), 3); \ + MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); \ + PCADDU12I(A, SPLIT20(val64offset)); \ + LD_D(A, A, SPLIT12(val64offset)); \ + } while (0) +#define TABLE64C(A, V) \ + do { \ + if (dyn->need_reloc && !isTable64(dyn, getConst(V))) \ + AddRelocTable64Const(dyn, ninst, (V), 3); \ + int val64offset = Table64(dyn, getConst(V), 3); \ + MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); \ + PCADDU12I(A, SPLIT20(val64offset)); \ + LD_D(A, A, SPLIT12(val64offset)); \ + } while (0) diff --git a/src/tools/env.c b/src/tools/env.c index 1680fdfe..877a9fc8 100644 --- a/src/tools/env.c +++ b/src/tools/env.c @@ -811,7 +811,7 @@ done: #elif defined(RV64) #define ARCH_VERSION SET_VERSION(0, 0, 1) #elif defined(LA64) -#define ARCH_VERSION SET_VERSION(0, 0, 0) +#define ARCH_VERSION SET_VERSION(0, 0, 1) #else #error meh! #endif |