about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-07-21 14:59:40 +0800
committerGitHub <noreply@github.com>2025-07-21 08:59:40 +0200
commit8271d37539068bb5fd9ab5b32d4aee2c0b52aae8 (patch)
treecbdbc348b47d648bbaab0f8aae37b54a377f8b20
parent206e3cd5616089b8dd7d569e9537a84c7363c299 (diff)
downloadbox64-8271d37539068bb5fd9ab5b32d4aee2c0b52aae8.tar.gz
box64-8271d37539068bb5fd9ab5b32d4aee2c0b52aae8.zip
[DYNACACHE]LA64] Enabled dynacache for LA64 (#2836)
* [DYNACACHE]LA64] Enabled dynacache for LA64

* review
-rw-r--r--docs/USAGE.md4
-rw-r--r--docs/box64.pod4
-rw-r--r--docs/gen/usage.json4
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c34
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.c17
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h16
-rw-r--r--src/dynarec/la64/dynarec_la64_pass2.h28
-rw-r--r--src/dynarec/la64/dynarec_la64_pass3.h29
-rw-r--r--src/tools/env.c2
9 files changed, 99 insertions, 39 deletions
diff --git a/docs/USAGE.md b/docs/USAGE.md
index 4c593115..09864519 100644
--- a/docs/USAGE.md
+++ b/docs/USAGE.md
@@ -171,7 +171,7 @@ Tweak the memory barriers to reduce the performance impact by strong memory emua
 
 ### BOX64_DYNACACHE
 
-Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). Not all architecture support DynaCache yet (it will have no effect then). DynaCache write file to home folder, and can grow without limit
+Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit.
 
  * 0: Disable DynaCache. 
  * 1: Enable DynaCache. 
@@ -179,7 +179,7 @@ Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defau
 
 ### BOX64_DYNACACHE_FOLDER
 
-Set the folder for DynaCache files. Default is in XDG_CACHE_HOME/box64 or, it does not exist in HOME/.cache/box64
+Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set.
 
  * XXXX: Use folder XXXX for DynaCache files. 
 
diff --git a/docs/box64.pod b/docs/box64.pod
index a02c055e..45e7336a 100644
--- a/docs/box64.pod
+++ b/docs/box64.pod
@@ -383,7 +383,7 @@ Force the use of float/double for x87 emulation. Availble in WowBox64.
 
 =item B<BOX64_DYNACACHE> =I<0|1|2>
 
-Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). Not all architecture support DynaCache yet (it will have no effect then). DynaCache write file to home folder, and can grow without limit
+Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit.
 
  * 0 : Disable DynaCache. 
  * 1 : Enable DynaCache. 
@@ -392,7 +392,7 @@ Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defau
 
 =item B<BOX64_DYNACACHE_FOLDER> =I<XXXX>
 
-Set the folder for DynaCache files. Default is in XDG_CACHE_HOME/box64 or, it does not exist in HOME/.cache/box64
+Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set.
 
  * XXXX : Use folder XXXX for DynaCache files. 
 
diff --git a/docs/gen/usage.json b/docs/gen/usage.json
index 3e748a20..8da1238b 100644
--- a/docs/gen/usage.json
+++ b/docs/gen/usage.json
@@ -803,7 +803,7 @@
   },
   {
     "name": "BOX64_DYNACACHE",
-    "description": "Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). Not all architecture support DynaCache yet (it will have no effect then). DynaCache write file to home folder, and can grow without limit",
+    "description": "Enable/disable the Dynamic Recompiler Cache (a.k.a DynaCache). This option defaults to 2 (to read cache if present but not generate any). DynaCache write file to home folder by default, and can grow without limit.",
     "category": "Performance",
     "wine": false,
     "options": [
@@ -826,7 +826,7 @@
   },
   {
     "name": "BOX64_DYNACACHE_FOLDER",
-    "description": "Set the folder for DynaCache files. Default is in XDG_CACHE_HOME/box64 or, it does not exist in HOME/.cache/box64",
+    "description": "Set the folder for DynaCache files. Default is $XDG_CACHE_HOME/box64 or $HOME/.cache/box64 if $XDG_CACHE_HOME is not set.",
     "category": "Performance",
     "wine": false,
     "options": [
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 2d9b1e6e..23fd9004 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -2369,7 +2369,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
 #endif
             }
 #if STEP < 2
-            if (!rex.is32bits && IsNativeCall(addr + i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
+            if (!rex.is32bits && !dyn->need_reloc && IsNativeCall(addr + i32, rex.is32bits, &dyn->insts[ninst].natcall, &dyn->insts[ninst].retn))
                 tmp = dyn->insts[ninst].pass2choice = 3;
             else
                 tmp = dyn->insts[ninst].pass2choice = i32 ? 0 : 1;
@@ -2381,10 +2381,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags to "dont'care" state
                     SKIPTEST(x1);
                     BARRIER(BARRIER_FULL);
-                    if (dyn->last_ip && (addr - dyn->last_ip < 0x800)) {
+                    if (dyn->last_ip && ((addr - dyn->last_ip < 0x800) || (dyn->last_ip - addr < 0x800))) {
                         ADDI_D(x2, xRIP, addr - dyn->last_ip);
                     } else {
-                        MOV64x(x2, addr);
+                        if (dyn->need_reloc) {
+                            TABLE64(x2, addr);
+                        } else {
+                            MOV64x(x2, addr);
+                        }
                     }
                     PUSH1(x2);
                     MESSAGE(LOG_DUMP, "Native Call to %s (retn=%d)\n", GetNativeName(GetNativeFnc(dyn->insts[ninst].natcall - 1)), dyn->insts[ninst].retn);
@@ -2402,7 +2406,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     //     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, x7); // read the 0xCC
-                        // FIXME: call_n(dyn, ninst, *(void**)(dyn->insts[ninst].natcall + 2 + 8), tmp);
+                        // FIXME: call_n(dyn, ninst, (void*)(dyn->insts[ninst].natcall + 2 + 8), tmp);
                         POP1(xRIP); // pop the return address
                         dyn->last_ip = addr;
                     } else {
@@ -2432,7 +2436,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     break;
                 case 1:
                     // this is call to next step, so just push the return address to the stack
-                    MOV64x(x2, addr);
+                    if (dyn->need_reloc) {
+                        TABLE64(x2, addr);
+                    } else {
+                        MOV64x(x2, addr);
+                    }
                     PUSH1z(x2);
                     break;
                 default:
@@ -2442,7 +2450,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         SETFLAGS(X_ALL, SF_SET_NODF, NAT_FLAGS_NOFUSION); // Hack to set flags to "dont'care" state
                     }
                     // regular call
-                    MOV64x(x2, addr);
+                    if (dyn->need_reloc) {
+                        TABLE64(x2, addr);
+                    } else {
+                        MOV64x(x2, addr);
+                    }
                     fpu_purgecache(dyn, ninst, 1, x1, x3, x4);
                     PUSH1z(x2);
                     if (BOX64DRENV(dynarec_callret)) {
@@ -2476,7 +2488,12 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         // jumps out of current dynablock...
                         MARK;
                         j64 = getJumpTableAddress64(addr);
-                        MOV64x(x4, j64);
+                        if (dyn->need_reloc) {
+                            AddRelocTable64JmpTbl(dyn, ninst, addr, STEP);
+                            TABLE64_(x4, j64);
+                        } else {
+                            MOV64x(x4, j64);
+                        }
                         LD_D(x4, x4, 0);
                         BR(x4);
                     }
@@ -2872,7 +2889,8 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         // jumps out of current dynablock...
                         MARK;
                         j64 = getJumpTableAddress64(addr);
-                        TABLE64(x4, j64);
+                        if (dyn->need_reloc) AddRelocTable64RetEndBlock(dyn, ninst, addr, STEP);
+                        TABLE64_(x4, j64);
                         LD_D(x4, x4, 0);
                         BR(x4);
                     }
diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c
index bd925559..4fb7f95e 100644
--- a/src/dynarec/la64/dynarec_la64_helper.c
+++ b/src/dynarec/la64/dynarec_la64_helper.c
@@ -102,7 +102,7 @@ uintptr_t geted(dynarec_la64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
             } else if ((tmp >= -2048) && (tmp <= maxval)) {
                 GETIP(addr + delta, scratch);
                 ADDI_D(ret, xRIP, tmp);
-            } else if (tmp + addr + delta < 0x100000000LL) {
+            } else if (tmp + addr + delta < 0x80000000LL && !dyn->need_reloc) {
                 MOV64x(ret, tmp + addr + delta);
             } else {
                 if (adj) {
@@ -533,7 +533,11 @@ static int indirect_lookup(dynarec_la64_t* dyn, int ninst, int is32bits, int s1,
     if (!is32bits) {
         SRLI_D(s1, xRIP, 48);
         BNEZ_safe(s1, (intptr_t)dyn->jmp_next - (intptr_t)dyn->block);
-        MOV64x(s2, getConst(const_jmptbl48));
+        if (dyn->need_reloc) {
+            TABLE64C(s2, const_jmptbl48);
+        } else {
+            MOV64x(s2, getConst(const_jmptbl48));
+        }
         BSTRPICK_D(s1, xRIP, JMPTABL_START2 + JMPTABL_SHIFT2 - 1, JMPTABL_START2);
         ALSL_D(s2, s1, s2, 3);
         LD_D(s2, s2, 0);
@@ -570,7 +574,8 @@ void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is3
         uintptr_t p = getJumpTableAddress64(ip);
         MAYUSE(p);
         GETIP_(ip, x3);
-        TABLE64(x3, p);
+        if (dyn->need_reloc) AddRelocTable64JmpTbl(dyn, ninst, ip, STEP);
+        TABLE64_(x3, p);
         LD_D(x2, x3, 0);
         dest = x2;
     }
@@ -675,7 +680,11 @@ void iret_to_epilog(dynarec_la64_t* dyn, uintptr_t ip, int ninst, int is64bits)
     // set new RSP
     MV(xRSP, x3);
     // Ret....
-    MOV64x(x2, getConst(const_epilog)); // epilog on purpose, CS might have changed!
+    // epilog on purpose, CS might have changed!
+    if (dyn->need_reloc)
+        TABLE64C(x2, const_epilog);
+    else
+        MOV64x(x2, getConst(const_epilog));
     SMEND();
     BR(x2);
     CLEARIP();
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index acd22031..9720cf25 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -1026,6 +1026,10 @@
 #define TABLE64C(A, V)
 #endif
 
+#ifndef TABLE64_
+#define TABLE64_(A, V)
+#endif
+
 #define ARCH_INIT() SMSTART()
 
 #define ARCH_RESET()
@@ -1039,7 +1043,11 @@
     do {                                                          \
         ssize_t _delta_ip = (ssize_t)(A) - (ssize_t)dyn->last_ip; \
         if (!dyn->last_ip) {                                      \
-            MOV64x(xRIP, A);                                      \
+            if (dyn->need_reloc) {                                \
+                TABLE64(xRIP, (A));                               \
+            } else {                                              \
+                MOV64x(xRIP, (A));                                \
+            }                                                     \
         } else if (_delta_ip == 0) {                              \
         } else if (_delta_ip >= -2048 && _delta_ip < 2048) {      \
             ADDI_D(xRIP, xRIP, _delta_ip);                        \
@@ -1050,7 +1058,11 @@
             MOV32w(scratch, _delta_ip);                           \
             ADD_D(xRIP, xRIP, scratch);                           \
         } else {                                                  \
-            MOV64x(xRIP, (A));                                    \
+            if (dyn->need_reloc) {                                \
+                TABLE64(xRIP, (A));                               \
+            } else {                                              \
+                MOV64x(xRIP, (A));                                \
+            }                                                     \
         }                                                         \
     } while (0)
 #define GETIP(A, scratch) \
diff --git a/src/dynarec/la64/dynarec_la64_pass2.h b/src/dynarec/la64/dynarec_la64_pass2.h
index 9b5400d9..eb722e42 100644
--- a/src/dynarec/la64/dynarec_la64_pass2.h
+++ b/src/dynarec/la64/dynarec_la64_pass2.h
@@ -19,15 +19,25 @@
     }
 #define INST_EPILOG dyn->insts[ninst].epilog = dyn->native_size;
 #define INST_NAME(name)
-#define TABLE64(A, V)         \
-    {                         \
+#define TABLE64(A, V)                                \
+    do {                                             \
+        if (dyn->need_reloc && !isTable64(dyn, (V))) \
+            AddRelocTable64Addr(dyn, ninst, (V), 2); \
+        Table64(dyn, (V), 2);                        \
+        EMIT(0);                                     \
+        EMIT(0);                                     \
+    } while (0)
+#define TABLE64_(A, V)        \
+    do {                      \
         Table64(dyn, (V), 2); \
         EMIT(0);              \
         EMIT(0);              \
-    }
-#define TABLE64C(A, V)                \
-    {                                 \
-        Table64(dyn, getConst(V), 2); \
-        EMIT(0);                      \
-        EMIT(0);                      \
-    }
+    } while (0)
+#define TABLE64C(A, V)                                       \
+    do {                                                     \
+        if (dyn->need_reloc && !isTable64(dyn, getConst(V))) \
+            AddRelocTable64Const(dyn, ninst, (V), 2);        \
+        Table64(dyn, getConst(V), 2);                        \
+        EMIT(0);                                             \
+        EMIT(0);                                             \
+    } while (0)
diff --git a/src/dynarec/la64/dynarec_la64_pass3.h b/src/dynarec/la64/dynarec_la64_pass3.h
index 7a21b637..8188e761 100644
--- a/src/dynarec/la64/dynarec_la64_pass3.h
+++ b/src/dynarec/la64/dynarec_la64_pass3.h
@@ -25,16 +25,27 @@
 #define INST_EPILOG
 #define INST_NAME(name) inst_name_pass3(dyn, ninst, name, rex)
 #define TABLE64(A, V)                                 \
-    {                                                 \
+    do {                                              \
+        if (dyn->need_reloc && !isTable64(dyn, (V)))  \
+            AddRelocTable64Addr(dyn, ninst, (V), 3);  \
         int val64offset = Table64(dyn, (V), 3);       \
         MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V)); \
         PCADDU12I(A, SPLIT20(val64offset));           \
         LD_D(A, A, SPLIT12(val64offset));             \
-    }
-#define TABLE64C(A, V)                                  \
-    {                                                   \
-        int val64offset = Table64(dyn, getConst(V), 3); \
-        MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V));   \
-        PCADDU12I(A, SPLIT20(val64offset));             \
-        LD_D(A, A, SPLIT12(val64offset));               \
-    }
+    } while (0)
+#define TABLE64_(A, V)                                \
+    do {                                              \
+        int val64offset = Table64(dyn, (V), 3);       \
+        MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V)); \
+        PCADDU12I(A, SPLIT20(val64offset));           \
+        LD_D(A, A, SPLIT12(val64offset));             \
+    } while (0)
+#define TABLE64C(A, V)                                       \
+    do {                                                     \
+        if (dyn->need_reloc && !isTable64(dyn, getConst(V))) \
+            AddRelocTable64Const(dyn, ninst, (V), 3);        \
+        int val64offset = Table64(dyn, getConst(V), 3);      \
+        MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V));        \
+        PCADDU12I(A, SPLIT20(val64offset));                  \
+        LD_D(A, A, SPLIT12(val64offset));                    \
+    } while (0)
diff --git a/src/tools/env.c b/src/tools/env.c
index 1680fdfe..877a9fc8 100644
--- a/src/tools/env.c
+++ b/src/tools/env.c
@@ -811,7 +811,7 @@ done:
 #elif defined(RV64)
 #define ARCH_VERSION SET_VERSION(0, 0, 1)
 #elif defined(LA64)
-#define ARCH_VERSION SET_VERSION(0, 0, 0)
+#define ARCH_VERSION SET_VERSION(0, 0, 1)
 #else
 #error meh!
 #endif