diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-10-07 22:57:47 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-07 16:57:47 +0200 |
| commit | 4c69bcd97aff691b464f01ebed057cfcb912612b (patch) | |
| tree | 3dbf5c2aad18598a6306d5b3ed9e324f66a593d8 /src/dynarec/la64 | |
| parent | 05aac0879e415b99225d731e154bc5d6535c1d15 (diff) | |
| download | box64-4c69bcd97aff691b464f01ebed057cfcb912612b.tar.gz box64-4c69bcd97aff691b464f01ebed057cfcb912612b.zip | |
[DYNAREC] Optimized CALL/RET RAS for out of dynablock jumps (#1909)
Diffstat (limited to 'src/dynarec/la64')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 3003829f..3e6c0f99 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -2030,10 +2030,10 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ADDI_D(x4, x4, j64 & 0xfff); MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64 >> 2); } else { - MESSAGE(LOG_NONE, "\tCALLRET set return to Jmptable(%p)\n", (void*)addr); - j64 = getJumpTableAddress64(addr); - TABLE64(x4, j64); - LD_D(x4, x4, 0); + j64 = (dyn->insts)?(GETMARK-(dyn->native_size)):0; + PCADDU12I(x4, ((j64 + 0x800) >> 12) & 0xfffff); + ADDI_D(x4, x4, j64 & 0xfff); + MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2); } ADDI_D(xSP, xSP, -16); ST_D(x4, xSP, 0); @@ -2047,6 +2047,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni else j64 = addr+i32; jump_to_next(dyn, j64, 0, ninst, rex.is32bits); + if(box64_dynarec_callret && addr >= (dyn->start + dyn->isize)) { + // jumps out of current dynablock... + MARK; + j64 = getJumpTableAddress64(addr); + TABLE64(x4, j64); + LD_D(x4, x4, 0); + BR(x4); + } break; } break; @@ -2371,10 +2379,10 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ADDI_D(x4, x4, j64 & 0xfff); MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64 >> 2); } else { - MESSAGE(LOG_NONE, "\tCALLRET set return to Jmptable(%p)\n", (void*)addr); - j64 = getJumpTableAddress64(addr); - TABLE64(x4, j64); - LD_D(x4, x4, 0); + j64 = (dyn->insts)?(GETMARK-(dyn->native_size)):0; + PCADDU12I(x4, ((j64 + 0x800) >> 12) & 0xfffff); + ADDI_D(x4, x4, j64 & 0xfff); + MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j64>>2); } ADDI_D(xSP, xSP, -16); ST_D(x4, xSP, 0); @@ -2382,6 +2390,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } PUSH1z(xRIP); jump_to_next(dyn, 0, ed, ninst, rex.is32bits); + if(box64_dynarec_callret && addr >= (dyn->start + dyn->isize)) { + // jumps out of current dynablock... + MARK; + j64 = getJumpTableAddress64(addr); + TABLE64(x4, j64); + LD_D(x4, x4, 0); + BR(x4); + } break; case 4: // JMP Ed INST_NAME("JMP Ed"); |