diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-06-27 15:17:06 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-06-27 09:17:06 +0200 |
| commit | f6bb7310bb3fed9d4a5b7456c5b0860bb753ec54 (patch) | |
| tree | 12cbf5d9a96a64fe95cffd80d47ece63a772f820 | |
| parent | d57416f4fb2b75a573e9731c1b33d0c9a1bea234 (diff) | |
| download | box64-f6bb7310bb3fed9d4a5b7456c5b0860bb753ec54.tar.gz box64-f6bb7310bb3fed9d4a5b7456c5b0860bb753ec54.zip | |
[LA64_DYNAREC] Optimized GETIP macro (#2781)
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 24 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 4 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_66.c | 4 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.c | 14 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 52 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_private.h | 2 |
6 files changed, 49 insertions, 51 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 1fd49564..9f229883 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -669,7 +669,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state } - GETIP(ip); + GETIP(ip, x7); STORE_XEMU_CALL(); CALL(const_native_priv, -1); LOAD_XEMU_CALL(); @@ -685,7 +685,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state } - GETIP(ip); + GETIP(ip, x7); STORE_XEMU_CALL(); CALL(const_native_priv, -1); LOAD_XEMU_CALL(); @@ -1979,7 +1979,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // FIXME: Even the basic support of isSimpleWrapper is disabled for now. - GETIP(ip + 1); // read the 0xCC + GETIP(ip + 1, x7); // read the 0xCC STORE_XEMU_CALL(); ADDI_D(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip CALL_S(const_int3, -1); @@ -2000,7 +2000,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MOV32w(x2, offsetof(box64context_t, signals[SIGTRAP])); LDX_D(x3, x1, x2); BEQZ_MARK(x3); - GETIP(addr); + GETIP(addr, x7); STORE_XEMU_CALL(); CALL(const_native_int3, -1); LOAD_XEMU_CALL(); @@ -2017,7 +2017,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("INT 29/2c/2d"); // lets do nothing MESSAGE(LOG_INFO, "INT 29/2c/2d Windows interruption\n"); - GETIP(ip); // priviledged instruction, IP not updated + GETIP(ip, x7); // priviledged instruction, IP not updated STORE_XEMU_CALL(); MOV32w(x1, u8); CALL(const_native_int, -1); @@ -2026,7 +2026,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("32bits SYSCALL"); NOTEST(x1); SMEND(); - GETIP(addr); + GETIP(addr, x7); STORE_XEMU_CALL(); CALL_S(const_x86syscall, -1); LOAD_XEMU_CALL(); @@ -2044,7 +2044,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state } - GETIP(addr); + GETIP(addr, x7); STORE_XEMU_CALL(); CALL(const_native_int3, -1); LOAD_XEMU_CALL(); @@ -2058,7 +2058,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state } - GETIP(ip); // priviledged instruction, IP not updated + GETIP(ip, x7); // priviledged instruction, IP not updated STORE_XEMU_CALL(); CALL(const_native_priv, -1); LOAD_XEMU_CALL(); @@ -2401,12 +2401,12 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni // // return value will be on the stack, so the stack depth needs to be updated // 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); // read the 0xCC + // GETIP(ip+3+8+8, x7); // read the 0xCC // FIXME: call_n(dyn, ninst, *(void**)(dyn->insts[ninst].natcall + 2 + 8), tmp); POP1(xRIP); // pop the return address dyn->last_ip = addr; } else { - GETIP_(dyn->insts[ninst].natcall); // read the 0xCC already + GETIP_(dyn->insts[ninst].natcall, x7); // read the 0xCC already STORE_XEMU_CALL(); ADDI_D(x1, xEmu, (uint32_t)offsetof(x64emu_t, ip)); // setup addr as &emu->ip CALL_S(const_int3, -1); @@ -2535,7 +2535,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state } - GETIP(ip); + GETIP(ip, x7); STORE_XEMU_CALL(); CALL(const_native_priv, -1); LOAD_XEMU_CALL(); @@ -2855,7 +2855,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni *need_epilog = 0; *ok = 0; } - GETIP_(addr); + GETIP_(addr, x7); if (BOX64DRENV(dynarec_callret)) { SET_HASCALLRET(); // Push actual return address diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index a8601aa7..2d009170 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -86,7 +86,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("SYSCALL"); NOTEST(x1); SMEND(); - GETIP(addr); + GETIP(addr, x7); STORE_XEMU_CALL(); CALL_S(const_x64syscall, -1); LOAD_XEMU_CALL(); @@ -105,7 +105,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags in "don't care" state } - GETIP(ip); + GETIP(ip, x7); STORE_XEMU_CALL(); CALL(const_native_ud, -1); LOAD_XEMU_CALL(); diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c index b4d1e50d..109683d3 100644 --- a/src/dynarec/la64/dynarec_la64_66.c +++ b/src/dynarec/la64/dynarec_la64_66.c @@ -968,7 +968,7 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni OR(x2, x2, x7); if(BOX64ENV(dynarec_div0)) { BNE_MARK3(ed, xZR); - GETIP_(ip); + GETIP_(ip, x6); STORE_XEMU_CALL(); CALL(const_native_div0, -1); CLEARIP(); @@ -989,7 +989,7 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETSEW(x1, 0); if (BOX64ENV(dynarec_div0)) { BNE_MARK3(ed, xZR); - GETIP_(ip); + GETIP_(ip, x7); STORE_XEMU_CALL(); CALL(const_native_div0, -1); CLEARIP(); diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c index ddc51082..6efc7bfb 100644 --- a/src/dynarec/la64/dynarec_la64_helper.c +++ b/src/dynarec/la64/dynarec_la64_helper.c @@ -94,13 +94,13 @@ uintptr_t geted(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, ret = xRIP; *fixaddress = tmp + adj; } else if (i12 && (tmp >= -2048) && (tmp <= maxval)) { - GETIP(addr + delta); + GETIP(addr + delta, scratch); ret = xRIP; *fixaddress = tmp; } else if (adj && (tmp + adj >= -2048) && (tmp + adj <= maxval)) { ADDI_D(ret, xRIP, tmp + adj); } else if ((tmp >= -2048) && (tmp <= maxval)) { - GETIP(addr + delta); + GETIP(addr + delta, scratch); ADDI_D(ret, xRIP, tmp); } else if (tmp + addr + delta < 0x100000000LL) { MOV64x(ret, tmp + addr + delta); @@ -109,7 +109,7 @@ uintptr_t geted(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, MOV64x(ret, tmp + adj); } else { MOV64x(ret, tmp); - GETIP(addr + delta); + GETIP(addr + delta, scratch); } ADD_D(ret, ret, xRIP); } @@ -400,7 +400,7 @@ uintptr_t geted32(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop uint32_t tmp = F32; // no need to zero up, as we did it below la64_move32(dyn, ninst, ret, tmp, 0); - GETIP(addr + delta); + GETIP(addr + delta, scratch); ADD_W(ret, ret, xRIP); ZEROUP(ret); switch (lock) { @@ -500,7 +500,7 @@ void jump_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst) MV(xRIP, reg); } } else { - GETIP_(ip); + GETIP_(ip, x2); } TABLE64C(x2, const_epilog); SMEND(); @@ -519,7 +519,7 @@ void jump_to_epilog_fast(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst) MV(xRIP, reg); } } else { - GETIP_(ip); + GETIP_(ip, x2); } TABLE64C(x2, const_epilog_fast); SMEND(); @@ -569,8 +569,8 @@ void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is3 NOTEST(x2); uintptr_t p = getJumpTableAddress64(ip); MAYUSE(p); + GETIP_(ip, x3); TABLE64(x3, p); - GETIP_(ip); LD_D(x2, x3, 0); dest = x2; } diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index b75e1f84..48387125 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -1031,34 +1031,32 @@ #define ARCH_RESET() #if STEP < 2 -#define GETIP(A) TABLE64(0, 0) -#define GETIP_(A) TABLE64(0, 0) +#define GETIP(A, scratch) +#define GETIP_(A, scratch) #else -// put value in the Table64 even if not using it for now to avoid difference between Step2 and Step3. Needs to be optimized later... -#define GETIP(A) \ - if (dyn->last_ip && ((A) - dyn->last_ip) < 2048) { \ - uint64_t _delta_ip = (A) - dyn->last_ip; \ - dyn->last_ip += _delta_ip; \ - if (_delta_ip) { \ - ADDI_D(xRIP, xRIP, _delta_ip); \ - } \ - } else { \ - dyn->last_ip = (A); \ - if (dyn->last_ip < 0xffffffff) { \ - MOV64x(xRIP, dyn->last_ip); \ - } else \ - TABLE64(xRIP, dyn->last_ip); \ - } -#define GETIP_(A) \ - if (dyn->last_ip && ((A) - dyn->last_ip) < 2048) { \ - int64_t _delta_ip = (A) - dyn->last_ip; \ - if (_delta_ip) { ADDI_D(xRIP, xRIP, _delta_ip); } \ - } else { \ - if ((A) < 0xffffffff) { \ - MOV64x(xRIP, (A)); \ - } else \ - TABLE64(xRIP, (A)); \ - } + +#define GETIP_(A, scratch) \ + do { \ + ssize_t _delta_ip = (ssize_t)(A) - (ssize_t)dyn->last_ip; \ + if (!dyn->last_ip) { \ + MOV64x(xRIP, A); \ + } else if (_delta_ip == 0) { \ + } else if (_delta_ip >= -2048 && _delta_ip < 2048) { \ + ADDI_D(xRIP, xRIP, _delta_ip); \ + } else if (_delta_ip < 0 && _delta_ip >= -0xffffffff) { \ + MOV32w(scratch, -_delta_ip); \ + SUB_D(xRIP, xRIP, scratch); \ + } else if (_delta_ip > 0 && _delta_ip <= 0xffffffff) { \ + MOV32w(scratch, _delta_ip); \ + ADD_D(xRIP, xRIP, scratch); \ + } else { \ + MOV64x(xRIP, (A)); \ + } \ + } while (0) +#define GETIP(A, scratch) \ + GETIP_(A, scratch); \ + dyn->last_ip = (A); + #endif #define CLEARIP() dyn->last_ip = 0 diff --git a/src/dynarec/la64/dynarec_la64_private.h b/src/dynarec/la64/dynarec_la64_private.h index 5b25edb9..27aac66d 100644 --- a/src/dynarec/la64/dynarec_la64_private.h +++ b/src/dynarec/la64/dynarec_la64_private.h @@ -185,7 +185,7 @@ int Table64(dynarec_la64_t *dyn, uint64_t val, int pass); // add a value to tab void CreateJmpNext(void* addr, void* next); #define GO_TRACE(A, B, s0) \ - GETIP(addr); \ + GETIP(addr, s0); \ MV(A1, xRIP); \ STORE_XEMU_CALL(); \ MOV64x(A2, B); \ |