diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-07-21 14:59:40 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-07-21 08:59:40 +0200 |
| commit | 8271d37539068bb5fd9ab5b32d4aee2c0b52aae8 (patch) | |
| tree | cbdbc348b47d648bbaab0f8aae37b54a377f8b20 | |
| parent | 206e3cd5616089b8dd7d569e9537a84c7363c299 (diff) | |
| download | box64-8271d37539068bb5fd9ab5b32d4aee2c0b52aae8.tar.gz box64-8271d37539068bb5fd9ab5b32d4aee2c0b52aae8.zip | |
[DYNACACHE]LA64] Enabled dynacache for LA64 (#2836)
* [DYNACACHE]LA64] Enabled dynacache for LA64 * review
| -rw-r--r-- | docs/USAGE.md | 4 | ||||
| -rw-r--r-- | docs/box64.pod | 4 | ||||
| -rw-r--r-- | docs/gen/usage.json | 4 | ||||
| -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 |
9 files changed, 99 insertions, 39 deletions
diff --git a/docs/USAGE.md b/docs/USAGE.md index 4c593115..09864519 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 a02c055e..45e7336a 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<BOX64_DYNACACHE> =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<BOX64_DYNACACHE_FOLDER> =I<XXXX> -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 3e748a20..8da1238b 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 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 |