diff --git a/docs/USAGE.md b/docs/USAGE.md index 4c593115f9..098645191e 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -171,7 +171,7 @@ Tweak the memory barriers to reduce the performance impact by strong memory emua ### BOX64_DYNACACHE -Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). Not all architecture support DynaCache yet (it will have no effect then). DynaCache write file to home folder, and can grow without limit +Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit. * 0: Disable DynaCache. * 1: Enable DynaCache. @@ -179,7 +179,7 @@ Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defau ### BOX64_DYNACACHE_FOLDER -Set the folder for DynaCache files. Default is in XDG_CACHE_HOME/box64 or, it does not exist in HOME/.cache/box64 +Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set. * XXXX: Use folder XXXX for DynaCache files. diff --git a/docs/box64.pod b/docs/box64.pod index a02c055ee8..45e7336a20 100644 --- a/docs/box64.pod +++ b/docs/box64.pod @@ -383,7 +383,7 @@ Force the use of float/double for x87 emulation. Availble in WowBox64. =item B =I<0|1|2> -Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). Not all architecture support DynaCache yet (it will have no effect then). DynaCache write file to home folder, and can grow without limit +Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit. * 0 : Disable DynaCache. * 1 : Enable DynaCache. @@ -392,7 +392,7 @@ Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defau =item B =I -Set the folder for DynaCache files. Default is in XDG_CACHE_HOME/box64 or, it does not exist in HOME/.cache/box64 +Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set. * XXXX : Use folder XXXX for DynaCache files. diff --git a/docs/gen/usage.json b/docs/gen/usage.json index 3e748a202b..8da1238bc5 100644 --- a/docs/gen/usage.json +++ b/docs/gen/usage.json @@ -803,7 +803,7 @@ }, { "name": "BOX64_DYNACACHE", - "description": "Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). Not all architecture support DynaCache yet (it will have no effect then). DynaCache write file to home folder, and can grow without limit", + "description": "Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit.", "category": "Performance", "wine": false, "options": [ @@ -826,7 +826,7 @@ }, { "name": "BOX64_DYNACACHE_FOLDER", - "description": "Set the folder for DynaCache files. Default is in XDG_CACHE_HOME/box64 or, it does not exist in HOME/.cache/box64", + "description": "Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set.", "category": "Performance", "wine": false, "options": [ diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 2d9b1e6e41..23fd900460 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 bd92555940..4fb7f95ec0 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 acd2203179..9720cf2569 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 9b5400d91d..eb722e42b5 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 7a21b63731..8188e761f2 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 1680fdfe08..877a9fc8a2 100644 --- a/src/tools/env.c +++ b/src/tools/env.c @@ -811,7 +811,7 @@ const char* GetDynacacheFolder(mapping_t* mapping) #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