about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-16 16:08:48 +0100
committerptitSeb <sebastien.chev@gmail.com>2021-03-16 16:08:48 +0100
commit1e5bfcdbcde5878cbe19770d5b3183e631e6c795 (patch)
treedec2d502a5e6688cb763ebab51a079f212f2d3a4 /src
parentc1b6cb73027b61b5a511a6221d596f213ea6a328 (diff)
downloadbox64-1e5bfcdbcde5878cbe19770d5b3183e631e6c795.tar.gz
box64-1e5bfcdbcde5878cbe19770d5b3183e631e6c795.zip
[DYNAREC] Added an optimisation with RIP handling
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec_arm64.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_00.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.c6
-rwxr-xr-xsrc/dynarec/dynarec_arm64_helper.h14
-rwxr-xr-xsrc/dynarec/dynarec_arm64_pass.c2
-rwxr-xr-xsrc/dynarec/dynarec_arm64_private.h1
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