diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-06-19 22:19:57 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-19 16:19:57 +0200 |
| commit | 58f4cc352e2690e9c29ad5dc82ae7ec7df1d2d02 (patch) | |
| tree | 88e3f33485035e32480823002639f2ad8254caac | |
| parent | b840606105dd9ca42efe309d1305c89d8ab533bc (diff) | |
| download | box64-58f4cc352e2690e9c29ad5dc82ae7ec7df1d2d02.tar.gz box64-58f4cc352e2690e9c29ad5dc82ae7ec7df1d2d02.zip | |
[DYNACACHE][RV64] More work on internal reloc (#2759)
| -rw-r--r-- | src/dynarec/dynarec_next.h | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_consts.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_consts.h | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 20 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 7 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass2.h | 6 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_pass3.h | 7 | ||||
| -rw-r--r-- | src/dynarec/rv64/rv64_emitter.h | 122 |
9 files changed, 95 insertions, 78 deletions
diff --git a/src/dynarec/dynarec_next.h b/src/dynarec/dynarec_next.h index 9c3411d1..ded0800d 100644 --- a/src/dynarec/dynarec_next.h +++ b/src/dynarec/dynarec_next.h @@ -19,9 +19,11 @@ void la64_epilog(void) EXPORTDYN; void rv64_next(void) EXPORTDYN; void rv64_prolog(x64emu_t* emu, void* addr) EXPORTDYN; void rv64_epilog(void) EXPORTDYN; +void rv64_epilog_fast(void) EXPORTDYN; #define native_next rv64_next #define native_prolog rv64_prolog #define native_epilog rv64_epilog +#define native_epilog_fast rv64_epilog_fast #else #error Unsupported architecture #endif diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 502f8b46..5eb2196e 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -481,7 +481,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int INST_NAME("INT 3"); if (!BOX64ENV(ignoreint3)) { // check if TRAP signal is handled - TABLE64(x1, (uintptr_t)my_context); + TABLE64C(x1, const_context); MOV32w(x2, offsetof(box64context_t, signals[SIGTRAP])); ADD(x2, x2, x1); LD(x3, x2, 0); diff --git a/src/dynarec/rv64/dynarec_rv64_consts.c b/src/dynarec/rv64/dynarec_rv64_consts.c index 4dc44ade..05784fb9 100644 --- a/src/dynarec/rv64/dynarec_rv64_consts.c +++ b/src/dynarec/rv64/dynarec_rv64_consts.c @@ -22,6 +22,7 @@ #include "emu/x64compstrings.h" #include "x64test.h" #include "dynarec/dynarec_next.h" +#include "bitutils.h" #ifndef HAVE_TRACE void PrintTrace() {} @@ -126,10 +127,13 @@ uintptr_t getConst(rv64_consts_t which) case const_x64test_step: return (uintptr_t)x64test_step; case const_printtrace: return (uintptr_t)PrintTrace; case const_epilog: return (uintptr_t)native_epilog; + case const_epilog_fast: return (uintptr_t)native_epilog_fast; case const_jmptbl32: return getJumpTable32(); case const_jmptbl48: return getJumpTable48(); case const_jmptbl64: return getJumpTable64(); case const_context: return (uintptr_t)my_context; + case const_lead0tab: return (uintptr_t)lead0tab; + case const_deBruijn64tab: return (uintptr_t)deBruijn64tab; case const_last: dynarec_log(LOG_NONE, "Warning, const last used\n"); return 0; diff --git a/src/dynarec/rv64/dynarec_rv64_consts.h b/src/dynarec/rv64/dynarec_rv64_consts.h index 03973b3b..55933b0c 100644 --- a/src/dynarec/rv64/dynarec_rv64_consts.h +++ b/src/dynarec/rv64/dynarec_rv64_consts.h @@ -98,10 +98,13 @@ typedef enum rv64_consts_s { const_x64test_step, const_printtrace, const_epilog, + const_epilog_fast, const_jmptbl32, const_jmptbl48, const_jmptbl64, const_context, + const_lead0tab, + const_deBruijn64tab, const_last } rv64_consts_t; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index f051f208..9f2645b5 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -557,7 +557,7 @@ void jump_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst) } else { GETIP_(ip, x2); } - TABLE64(x2, (uintptr_t)rv64_epilog); + TABLE64C(x2, const_epilog); SMEND(); BR(x2); } @@ -576,7 +576,7 @@ void jump_to_epilog_fast(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst) } else { GETIP_(ip, x2); } - TABLE64(x2, (uintptr_t)rv64_epilog_fast); + TABLE64C(x2, const_epilog_fast); SMEND(); BR(x2); } @@ -591,13 +591,11 @@ static int indirect_lookup(dynarec_rv64_t* dyn, int ninst, int is32bits, int s1, if (!is32bits) { SRLI(s1, xRIP, 48); BNEZ_safe(s1, (intptr_t)dyn->jmp_next - (intptr_t)dyn->block); - uintptr_t tbl = getJumpTable48(); - MOV64x(s2, tbl); + MOV64x(s2, getConst(const_jmptbl48)); TH_EXTU(s1, xRIP, JMPTABL_START2 + JMPTABL_SHIFT2 - 1, JMPTABL_START2); TH_LRD(s2, s2, s1, 3); } else { - uintptr_t tbl = getJumpTable32(); - TABLE64(s2, tbl); + TABLE64C(s2, const_jmptbl32); } TH_EXTU(s1, xRIP, JMPTABL_START1 + JMPTABL_SHIFT1 - 1, JMPTABL_START1); TH_LRD(s2, s2, s1, 3); @@ -607,14 +605,12 @@ static int indirect_lookup(dynarec_rv64_t* dyn, int ninst, int is32bits, int s1, if (!is32bits) { SRLI(s1, xRIP, 48); BNEZ_safe(s1, (intptr_t)dyn->jmp_next - (intptr_t)dyn->block); - uintptr_t tbl = getJumpTable48(); - MOV64x(s2, tbl); + MOV64x(s2, getConst(const_jmptbl48)); SRLI(s1, xRIP, JMPTABL_START2); ADDSL(s2, s2, s1, 3, s1); LD(s2, s2, 0); } else { - uintptr_t tbl = getJumpTable32(); - TABLE64(s2, tbl); + TABLE64C(s2, const_jmptbl32); } MOV64x(x4, JMPTABLE_MASK1 << 3); SRLI(s1, xRIP, JMPTABL_START1 - 3); @@ -759,7 +755,7 @@ void iret_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int ninst, int is64bits) // set new RSP MV(xRSP, x3); // Ret.... - MOV64x(x2, (uintptr_t)rv64_epilog); // epilog on purpose, CS might have changed! + MOV64x(x2, getConst(const_epilog)); // epilog on purpose, CS might have changed! SMEND(); BR(x2); CLEARIP(); @@ -787,7 +783,7 @@ void call_c(dynarec_rv64_t* dyn, int ninst, rv64_consts_t fnc, int reg, int ret, STORE_REG(RAX); SD(xRIP, xEmu, offsetof(x64emu_t, ip)); } - TABLE64(reg, getConst(fnc)); + TABLE64C(reg, fnc); MV(A0, xEmu); if (arg1) MV(A1, arg1); if (arg2) MV(A2, arg2); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 8635d242..361e104f 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1149,6 +1149,9 @@ #ifndef FTABLE64 #define FTABLE64(A, V) #endif +#ifndef TABLE64C +#define TABLE64C(A, V) +#endif #define ARCH_INIT() \ SMSTART(); \ @@ -1212,10 +1215,6 @@ } while (0) #endif -void rv64_epilog(void); -void rv64_epilog_fast(void); -void* rv64_next(void); - #ifndef STEPNAME #define STEPNAME3(N, M) N##M #define STEPNAME2(N, M) STEPNAME3(N, M) diff --git a/src/dynarec/rv64/dynarec_rv64_pass2.h b/src/dynarec/rv64/dynarec_rv64_pass2.h index 2a535598..7466f426 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass2.h +++ b/src/dynarec/rv64/dynarec_rv64_pass2.h @@ -38,3 +38,9 @@ EMIT(0); \ EMIT(0); \ } +#define TABLE64C(A, V) \ + { \ + Table64(dyn, getConst(V), 2); \ + EMIT(0); \ + EMIT(0); \ + } diff --git a/src/dynarec/rv64/dynarec_rv64_pass3.h b/src/dynarec/rv64/dynarec_rv64_pass3.h index 41858199..9a08a57e 100644 --- a/src/dynarec/rv64/dynarec_rv64_pass3.h +++ b/src/dynarec/rv64/dynarec_rv64_pass3.h @@ -44,6 +44,13 @@ AUIPC(x1, SPLIT20(val64offset)); \ FLD(A, x1, SPLIT12(val64offset)); \ } +#define TABLE64C(A, V) \ + { \ + int val64offset = Table64(dyn, getConst(V), 3); \ + MESSAGE(LOG_DUMP, " Table64: 0x%lx\n", (V)); \ + AUIPC(A, SPLIT20(val64offset)); \ + LD(A, A, SPLIT12(val64offset)); \ + } #define DEFAULT_VECTOR \ if (BOX64ENV(dynarec_log) >= LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing) == 2) { \ diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h index cb8d0c39..cb91b7e6 100644 --- a/src/dynarec/rv64/rv64_emitter.h +++ b/src/dynarec/rv64/rv64_emitter.h @@ -893,52 +893,52 @@ // Count leading zero bits in word #define CLZW(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, 0b0011011)) // Count leading zero bits -#define CLZxw(rd, rs, x, s1, s2, s3) \ - if (cpuext.zbb) { \ - if (x) \ - CLZ(rd, rs); \ - else \ - CLZW(rd, rs); \ - } else if (cpuext.xtheadbb) { \ - if (x) { \ - TH_FF1(rd, rs); \ - } else { \ - ZEXTW2(rd, rs); \ - TH_FF1(rd, rd); \ - SUBI(rd, rd, 32); \ - } \ - } else { \ - if (rs != rd) \ - u8 = rd; \ - else \ - u8 = s1; \ - ADDI(u8, xZR, x ? 63 : 31); \ - if (x) { \ - MV(s2, rs); \ - SRLI(s3, s2, 32); \ - BEQZ(s3, 4 + 2 * 4); \ - SUBI(u8, u8, 32); \ - MV(s2, s3); \ - } else { \ - ZEXTW2(s2, rs); \ - } \ - SRLI(s3, s2, 16); \ - BEQZ(s3, 4 + 2 * 4); \ - SUBI(u8, u8, 16); \ - MV(s2, s3); \ - SRLI(s3, s2, 8); \ - BEQZ(s3, 4 + 2 * 4); \ - SUBI(u8, u8, 8); \ - MV(s2, s3); \ - SRLI(s3, s2, 4); \ - BEQZ(s3, 4 + 2 * 4); \ - SUBI(u8, u8, 4); \ - MV(s2, s3); \ - ANDI(s2, s2, 0b1111); \ - TABLE64(s3, (uintptr_t)&lead0tab); \ - ADD(s3, s3, s2); \ - LBU(s2, s3, 0); \ - SUB(rd, u8, s2); \ +#define CLZxw(rd, rs, x, s1, s2, s3) \ + if (cpuext.zbb) { \ + if (x) \ + CLZ(rd, rs); \ + else \ + CLZW(rd, rs); \ + } else if (cpuext.xtheadbb) { \ + if (x) { \ + TH_FF1(rd, rs); \ + } else { \ + ZEXTW2(rd, rs); \ + TH_FF1(rd, rd); \ + SUBI(rd, rd, 32); \ + } \ + } else { \ + if (rs != rd) \ + u8 = rd; \ + else \ + u8 = s1; \ + ADDI(u8, xZR, x ? 63 : 31); \ + if (x) { \ + MV(s2, rs); \ + SRLI(s3, s2, 32); \ + BEQZ(s3, 4 + 2 * 4); \ + SUBI(u8, u8, 32); \ + MV(s2, s3); \ + } else { \ + ZEXTW2(s2, rs); \ + } \ + SRLI(s3, s2, 16); \ + BEQZ(s3, 4 + 2 * 4); \ + SUBI(u8, u8, 16); \ + MV(s2, s3); \ + SRLI(s3, s2, 8); \ + BEQZ(s3, 4 + 2 * 4); \ + SUBI(u8, u8, 8); \ + MV(s2, s3); \ + SRLI(s3, s2, 4); \ + BEQZ(s3, 4 + 2 * 4); \ + SUBI(u8, u8, 4); \ + MV(s2, s3); \ + ANDI(s2, s2, 0b1111); \ + TABLE64C(s3, const_lead0tab); \ + ADD(s3, s3, s2); \ + LBU(s2, s3, 0); \ + SUB(rd, u8, s2); \ } // Count trailing zero bits @@ -948,21 +948,21 @@ // Count trailing zero bits // BEWARE: You should take care of the all zeros situation yourself, // and clear the high 32bit when x is 1. -#define CTZxw(rd, rs, x, s1, s2) \ - if (cpuext.zbb) { \ - if (x) \ - CTZ(rd, rs); \ - else \ - CTZW(rd, rs); \ - } else { \ - NEG(s2, rs); \ - AND(s2, s2, rs); \ - TABLE64(s1, 0x03f79d71b4ca8b09ULL); \ - MUL(s2, s2, s1); \ - SRLI(s2, s2, 64 - 6); \ - TABLE64(s1, (uintptr_t) & deBruijn64tab); \ - ADD(s1, s1, s2); \ - LBU(rd, s1, 0); \ +#define CTZxw(rd, rs, x, s1, s2) \ + if (cpuext.zbb) { \ + if (x) \ + CTZ(rd, rs); \ + else \ + CTZW(rd, rs); \ + } else { \ + NEG(s2, rs); \ + AND(s2, s2, rs); \ + TABLE64(s1, 0x03f79d71b4ca8b09ULL); \ + MUL(s2, s2, s1); \ + SRLI(s2, s2, 64 - 6); \ + TABLE64C(s1, const_deBruijn64tab); \ + ADD(s1, s1, s2); \ + LBU(rd, s1, 0); \ } // Count set bits |