diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-16 16:08:48 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-16 16:08:48 +0100 |
| commit | 1e5bfcdbcde5878cbe19770d5b3183e631e6c795 (patch) | |
| tree | dec2d502a5e6688cb763ebab51a079f212f2d3a4 /src | |
| parent | c1b6cb73027b61b5a511a6221d596f213ea6a328 (diff) | |
| download | box64-1e5bfcdbcde5878cbe19770d5b3183e631e6c795.tar.gz box64-1e5bfcdbcde5878cbe19770d5b3183e631e6c795.zip | |
[DYNAREC] Added an optimisation with RIP handling
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.c | 6 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 14 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_pass.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_private.h | 1 |
6 files changed, 22 insertions, 5 deletions
diff --git a/src/dynarec/dynarec_arm64.c b/src/dynarec/dynarec_arm64.c index 9918f4a5..79082ce0 100755 --- a/src/dynarec/dynarec_arm64.c +++ b/src/dynarec/dynarec_arm64.c @@ -305,7 +305,7 @@ instsize_t* addInst(instsize_t* insts, size_t* size, size_t* cap, int x64_size, return insts; } -// add a value to etable64 (if needed) and gives back the imm19 to use in LDR_literal +// add a value to table64 (if needed) and gives back the imm19 to use in LDR_literal int Table64(dynarec_arm_t *dyn, uint64_t val) { // find the value if already present diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 26040089..3f5e8b85 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -206,7 +206,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin // calling a native function x87_forget(dyn, ninst, x3, x4, 0); sse_purge07cache(dyn, ninst, x3); - TABLE64(xRIP, dyn->insts[ninst].natcall); // read the 0xCC already + GETIP(dyn->insts[ninst].natcall); // read the 0xCC already STORE_XEMU_MINIMUM(xRIP); CALL_S(x64Int3, -1); LOAD_XEMU_MINIMUM(xRIP); diff --git a/src/dynarec/dynarec_arm64_helper.c b/src/dynarec/dynarec_arm64_helper.c index 014bca70..f6b7ed71 100755 --- a/src/dynarec/dynarec_arm64_helper.c +++ b/src/dynarec/dynarec_arm64_helper.c @@ -63,7 +63,7 @@ uintptr_t geted(dynarec_arm_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, u } else if((nextop&7)==5) { uint64_t tmp = F32S64; MOV64x(ret, tmp); - TABLE64(xRIP, addr+delta); + GETIP(addr+delta); ADDx_REG(ret, ret, xRIP); } else { ret = xRAX+(nextop&7)+(rex.b<<3); @@ -225,7 +225,7 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst) MOVx(xRIP, reg); } } else { - TABLE64(xRIP, ip); + GETIP(ip); } TABLE64(x2, (uintptr_t)arm64_epilog); BR(x2); @@ -251,7 +251,7 @@ void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst) } else { uintptr_t p = getJumpTableAddress64(ip); TABLE64(x2, p); - TABLE64(xRIP, ip); + GETIP(ip); LDRx_U12(x3, x2, 0); } MOVx(x1, xRIP); diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 68021614..3d947a5c 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -426,6 +426,20 @@ #endif #if STEP < 2 +#define GETIP(A) +#else +#define GETIP(A) \ + if(dyn->last_ip && (A-dyn->last_ip)<0x1000) { \ + uint64_t delta = A-dyn->last_ip; \ + dyn->last_ip += delta; \ + ADDx_U12(xRIP, xRIP, delta); \ + } else { \ + dyn->last_ip = A; \ + TABLE64(xRIP, dyn->last_ip); \ + } +#endif + +#if STEP < 2 #define PASS2IF(A, B) if(A) #elif STEP == 2 #define PASS2IF(A, B) if(A) dyn->insts[ninst].pass2choice = B; if(dyn->insts[ninst].pass2choice == B) diff --git a/src/dynarec/dynarec_arm64_pass.c b/src/dynarec/dynarec_arm64_pass.c index 4e78a3c7..09d09b30 100755 --- a/src/dynarec/dynarec_arm64_pass.c +++ b/src/dynarec/dynarec_arm64_pass.c @@ -35,6 +35,7 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr) // Clean up (because there are multiple passes) dyn->state_flags = 0; dyn->dfnone = 0; + dyn->last_ip = ip; // RIP is always set at start of block! fpu_reset(dyn, ninst); // ok, go now INIT; @@ -42,6 +43,7 @@ void arm_pass(dynarec_arm_t* dyn, uintptr_t addr) if(dyn->insts && (ninst>dyn->size)) {dynarec_log(LOG_NONE, "Warning, too many inst treated (%d / %d)\n",ninst, dyn->size);} ip = addr; if(dyn->insts && (dyn->insts[ninst].x64.barrier==1)) { + dyn->last_ip = 0; NEW_BARRIER_INST; } NEW_INST; diff --git a/src/dynarec/dynarec_arm64_private.h b/src/dynarec/dynarec_arm64_private.h index cb81b101..413e7edf 100755 --- a/src/dynarec/dynarec_arm64_private.h +++ b/src/dynarec/dynarec_arm64_private.h @@ -30,6 +30,7 @@ typedef struct dynarec_arm_s { uintptr_t arm_start; // start of the arm code int arm_size; // size of emitted arm code int state_flags;// actual state for on-demand flags + uintptr_t last_ip; // last set IP in RIP (or NULL if unclean state) int8_t x87cache[8];// cache status for the 8 x87 register behind the fpu stack int8_t x87reg[8]; // reg used for x87cache entry int8_t mmxcache[8];// cache status for the 8 MMX registers |