about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-06-19 22:19:57 +0800
committerGitHub <noreply@github.com>2025-06-19 16:19:57 +0200
commit58f4cc352e2690e9c29ad5dc82ae7ec7df1d2d02 (patch)
tree88e3f33485035e32480823002639f2ad8254caac
parentb840606105dd9ca42efe309d1305c89d8ab533bc (diff)
downloadbox64-58f4cc352e2690e9c29ad5dc82ae7ec7df1d2d02.tar.gz
box64-58f4cc352e2690e9c29ad5dc82ae7ec7df1d2d02.zip
[DYNACACHE][RV64] More work on internal reloc (#2759)
-rw-r--r--src/dynarec/dynarec_next.h2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00_3.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_consts.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_consts.h3
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c20
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h7
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass2.h6
-rw-r--r--src/dynarec/rv64/dynarec_rv64_pass3.h7
-rw-r--r--src/dynarec/rv64/rv64_emitter.h122
9 files changed, 95 insertions, 78 deletions
diff --git a/src/dynarec/dynarec_next.h b/src/dynarec/dynarec_next.h
index 9c3411d1..ded0800d 100644
--- a/src/dynarec/dynarec_next.h
+++ b/src/dynarec/dynarec_next.h
@@ -19,9 +19,11 @@ void la64_epilog(void) EXPORTDYN;
 void rv64_next(void) EXPORTDYN;
 void rv64_prolog(x64emu_t* emu, void* addr) EXPORTDYN;
 void rv64_epilog(void) EXPORTDYN;
+void rv64_epilog_fast(void) EXPORTDYN;
 #define native_next         rv64_next
 #define native_prolog       rv64_prolog
 #define native_epilog       rv64_epilog
+#define native_epilog_fast  rv64_epilog_fast
 #else
 #error Unsupported architecture
 #endif
diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c
index 502f8b46..5eb2196e 100644
--- a/src/dynarec/rv64/dynarec_rv64_00_3.c
+++ b/src/dynarec/rv64/dynarec_rv64_00_3.c
@@ -481,7 +481,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 INST_NAME("INT 3");
                 if (!BOX64ENV(ignoreint3)) {
                     // check if TRAP signal is handled
-                    TABLE64(x1, (uintptr_t)my_context);
+                    TABLE64C(x1, const_context);
                     MOV32w(x2, offsetof(box64context_t, signals[SIGTRAP]));
                     ADD(x2, x2, x1);
                     LD(x3, x2, 0);
diff --git a/src/dynarec/rv64/dynarec_rv64_consts.c b/src/dynarec/rv64/dynarec_rv64_consts.c
index 4dc44ade..05784fb9 100644
--- a/src/dynarec/rv64/dynarec_rv64_consts.c
+++ b/src/dynarec/rv64/dynarec_rv64_consts.c
@@ -22,6 +22,7 @@
 #include "emu/x64compstrings.h"
 #include "x64test.h"
 #include "dynarec/dynarec_next.h"
+#include "bitutils.h"
 
 #ifndef HAVE_TRACE
 void PrintTrace() {}
@@ -126,10 +127,13 @@ uintptr_t getConst(rv64_consts_t which)
         case const_x64test_step: return (uintptr_t)x64test_step;
         case const_printtrace: return (uintptr_t)PrintTrace;
         case const_epilog: return (uintptr_t)native_epilog;
+        case const_epilog_fast: return (uintptr_t)native_epilog_fast;
         case const_jmptbl32: return getJumpTable32();
         case const_jmptbl48: return getJumpTable48();
         case const_jmptbl64: return getJumpTable64();
         case const_context: return (uintptr_t)my_context;
+        case const_lead0tab: return (uintptr_t)lead0tab;
+        case const_deBruijn64tab: return (uintptr_t)deBruijn64tab;
 
         case const_last: dynarec_log(LOG_NONE, "Warning, const last used\n");
             return 0;
diff --git a/src/dynarec/rv64/dynarec_rv64_consts.h b/src/dynarec/rv64/dynarec_rv64_consts.h
index 03973b3b..55933b0c 100644
--- a/src/dynarec/rv64/dynarec_rv64_consts.h
+++ b/src/dynarec/rv64/dynarec_rv64_consts.h
@@ -98,10 +98,13 @@ typedef enum rv64_consts_s {
     const_x64test_step,
     const_printtrace,
     const_epilog,
+    const_epilog_fast,
     const_jmptbl32,
     const_jmptbl48,
     const_jmptbl64,
     const_context,
+    const_lead0tab,
+    const_deBruijn64tab,
 
     const_last
 } rv64_consts_t;
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index f051f208..9f2645b5 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -557,7 +557,7 @@ void jump_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
     } else {
         GETIP_(ip, x2);
     }
-    TABLE64(x2, (uintptr_t)rv64_epilog);
+    TABLE64C(x2, const_epilog);
     SMEND();
     BR(x2);
 }
@@ -576,7 +576,7 @@ void jump_to_epilog_fast(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
     } else {
         GETIP_(ip, x2);
     }
-    TABLE64(x2, (uintptr_t)rv64_epilog_fast);
+    TABLE64C(x2, const_epilog_fast);
     SMEND();
     BR(x2);
 }
@@ -591,13 +591,11 @@ static int indirect_lookup(dynarec_rv64_t* dyn, int ninst, int is32bits, int s1,
         if (!is32bits) {
             SRLI(s1, xRIP, 48);
             BNEZ_safe(s1, (intptr_t)dyn->jmp_next - (intptr_t)dyn->block);
-            uintptr_t tbl = getJumpTable48();
-            MOV64x(s2, tbl);
+            MOV64x(s2, getConst(const_jmptbl48));
             TH_EXTU(s1, xRIP, JMPTABL_START2 + JMPTABL_SHIFT2 - 1, JMPTABL_START2);
             TH_LRD(s2, s2, s1, 3);
         } else {
-            uintptr_t tbl = getJumpTable32();
-            TABLE64(s2, tbl);
+            TABLE64C(s2, const_jmptbl32);
         }
         TH_EXTU(s1, xRIP, JMPTABL_START1 + JMPTABL_SHIFT1 - 1, JMPTABL_START1);
         TH_LRD(s2, s2, s1, 3);
@@ -607,14 +605,12 @@ static int indirect_lookup(dynarec_rv64_t* dyn, int ninst, int is32bits, int s1,
         if (!is32bits) {
             SRLI(s1, xRIP, 48);
             BNEZ_safe(s1, (intptr_t)dyn->jmp_next - (intptr_t)dyn->block);
-            uintptr_t tbl = getJumpTable48();
-            MOV64x(s2, tbl);
+            MOV64x(s2, getConst(const_jmptbl48));
             SRLI(s1, xRIP, JMPTABL_START2);
             ADDSL(s2, s2, s1, 3, s1);
             LD(s2, s2, 0);
         } else {
-            uintptr_t tbl = getJumpTable32();
-            TABLE64(s2, tbl);
+            TABLE64C(s2, const_jmptbl32);
         }
         MOV64x(x4, JMPTABLE_MASK1 << 3);
         SRLI(s1, xRIP, JMPTABL_START1 - 3);
@@ -759,7 +755,7 @@ void iret_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int ninst, int is64bits)
     // set new RSP
     MV(xRSP, x3);
     // Ret....
-    MOV64x(x2, (uintptr_t)rv64_epilog); // epilog on purpose, CS might have changed!
+    MOV64x(x2, getConst(const_epilog)); // epilog on purpose, CS might have changed!
     SMEND();
     BR(x2);
     CLEARIP();
@@ -787,7 +783,7 @@ void call_c(dynarec_rv64_t* dyn, int ninst, rv64_consts_t fnc, int reg, int ret,
         STORE_REG(RAX);
         SD(xRIP, xEmu, offsetof(x64emu_t, ip));
     }
-    TABLE64(reg, getConst(fnc));
+    TABLE64C(reg, fnc);
     MV(A0, xEmu);
     if (arg1) MV(A1, arg1);
     if (arg2) MV(A2, arg2);
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 8635d242..361e104f 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -1149,6 +1149,9 @@
 #ifndef FTABLE64
 #define FTABLE64(A, V)
 #endif
+#ifndef TABLE64C
+#define TABLE64C(A, V)
+#endif
 
 #define ARCH_INIT() \
     SMSTART();      \
@@ -1212,10 +1215,6 @@
     } while (0)
 #endif
 
-void rv64_epilog(void);
-void rv64_epilog_fast(void);
-void* rv64_next(void);
-
 #ifndef STEPNAME
 #define STEPNAME3(N, M) N##M
 #define STEPNAME2(N, M) STEPNAME3(N, M)
diff --git a/src/dynarec/rv64/dynarec_rv64_pass2.h b/src/dynarec/rv64/dynarec_rv64_pass2.h
index 2a535598..7466f426 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass2.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass2.h
@@ -38,3 +38,9 @@
         EMIT(0);                     \
         EMIT(0);                     \
     }
+#define TABLE64C(A, V)                \
+    {                                 \
+        Table64(dyn, getConst(V), 2); \
+        EMIT(0);                      \
+        EMIT(0);                      \
+    }
diff --git a/src/dynarec/rv64/dynarec_rv64_pass3.h b/src/dynarec/rv64/dynarec_rv64_pass3.h
index 41858199..9a08a57e 100644
--- a/src/dynarec/rv64/dynarec_rv64_pass3.h
+++ b/src/dynarec/rv64/dynarec_rv64_pass3.h
@@ -44,6 +44,13 @@
         AUIPC(x1, SPLIT20(val64offset));            \
         FLD(A, x1, SPLIT12(val64offset));           \
     }
+#define TABLE64C(A, V)                                  \
+    {                                                   \
+        int val64offset = Table64(dyn, getConst(V), 3); \
+        MESSAGE(LOG_DUMP, "  Table64: 0x%lx\n", (V));   \
+        AUIPC(A, SPLIT20(val64offset));                 \
+        LD(A, A, SPLIT12(val64offset));                 \
+    }
 
 #define DEFAULT_VECTOR                                                                                                                  \
     if (BOX64ENV(dynarec_log) >= LOG_INFO || dyn->need_dump || BOX64ENV(dynarec_missing) == 2) {                                        \
diff --git a/src/dynarec/rv64/rv64_emitter.h b/src/dynarec/rv64/rv64_emitter.h
index cb8d0c39..cb91b7e6 100644
--- a/src/dynarec/rv64/rv64_emitter.h
+++ b/src/dynarec/rv64/rv64_emitter.h
@@ -893,52 +893,52 @@
 // Count leading zero bits in word
 #define CLZW(rd, rs) EMIT(R_type(0b0110000, 0b00000, rs, 0b001, rd, 0b0011011))
 // Count leading zero bits
-#define CLZxw(rd, rs, x, s1, s2, s3)       \
-    if (cpuext.zbb) {                      \
-        if (x)                             \
-            CLZ(rd, rs);                   \
-        else                               \
-            CLZW(rd, rs);                  \
-    } else if (cpuext.xtheadbb) {          \
-        if (x) {                           \
-            TH_FF1(rd, rs);                \
-        } else {                           \
-            ZEXTW2(rd, rs);                \
-            TH_FF1(rd, rd);                \
-            SUBI(rd, rd, 32);              \
-        }                                  \
-    } else {                               \
-        if (rs != rd)                      \
-            u8 = rd;                       \
-        else                               \
-            u8 = s1;                       \
-        ADDI(u8, xZR, x ? 63 : 31);        \
-        if (x) {                           \
-            MV(s2, rs);                    \
-            SRLI(s3, s2, 32);              \
-            BEQZ(s3, 4 + 2 * 4);           \
-            SUBI(u8, u8, 32);              \
-            MV(s2, s3);                    \
-        } else {                           \
-            ZEXTW2(s2, rs);                \
-        }                                  \
-        SRLI(s3, s2, 16);                  \
-        BEQZ(s3, 4 + 2 * 4);               \
-        SUBI(u8, u8, 16);                  \
-        MV(s2, s3);                        \
-        SRLI(s3, s2, 8);                   \
-        BEQZ(s3, 4 + 2 * 4);               \
-        SUBI(u8, u8, 8);                   \
-        MV(s2, s3);                        \
-        SRLI(s3, s2, 4);                   \
-        BEQZ(s3, 4 + 2 * 4);               \
-        SUBI(u8, u8, 4);                   \
-        MV(s2, s3);                        \
-        ANDI(s2, s2, 0b1111);              \
-        TABLE64(s3, (uintptr_t)&lead0tab); \
-        ADD(s3, s3, s2);                   \
-        LBU(s2, s3, 0);                    \
-        SUB(rd, u8, s2);                   \
+#define CLZxw(rd, rs, x, s1, s2, s3)  \
+    if (cpuext.zbb) {                 \
+        if (x)                        \
+            CLZ(rd, rs);              \
+        else                          \
+            CLZW(rd, rs);             \
+    } else if (cpuext.xtheadbb) {     \
+        if (x) {                      \
+            TH_FF1(rd, rs);           \
+        } else {                      \
+            ZEXTW2(rd, rs);           \
+            TH_FF1(rd, rd);           \
+            SUBI(rd, rd, 32);         \
+        }                             \
+    } else {                          \
+        if (rs != rd)                 \
+            u8 = rd;                  \
+        else                          \
+            u8 = s1;                  \
+        ADDI(u8, xZR, x ? 63 : 31);   \
+        if (x) {                      \
+            MV(s2, rs);               \
+            SRLI(s3, s2, 32);         \
+            BEQZ(s3, 4 + 2 * 4);      \
+            SUBI(u8, u8, 32);         \
+            MV(s2, s3);               \
+        } else {                      \
+            ZEXTW2(s2, rs);           \
+        }                             \
+        SRLI(s3, s2, 16);             \
+        BEQZ(s3, 4 + 2 * 4);          \
+        SUBI(u8, u8, 16);             \
+        MV(s2, s3);                   \
+        SRLI(s3, s2, 8);              \
+        BEQZ(s3, 4 + 2 * 4);          \
+        SUBI(u8, u8, 8);              \
+        MV(s2, s3);                   \
+        SRLI(s3, s2, 4);              \
+        BEQZ(s3, 4 + 2 * 4);          \
+        SUBI(u8, u8, 4);              \
+        MV(s2, s3);                   \
+        ANDI(s2, s2, 0b1111);         \
+        TABLE64C(s3, const_lead0tab); \
+        ADD(s3, s3, s2);              \
+        LBU(s2, s3, 0);               \
+        SUB(rd, u8, s2);              \
     }
 
 // Count trailing zero bits
@@ -948,21 +948,21 @@
 // Count trailing zero bits
 // BEWARE: You should take care of the all zeros situation yourself,
 //         and clear the high 32bit when x is 1.
-#define CTZxw(rd, rs, x, s1, s2)                  \
-    if (cpuext.zbb) {                             \
-        if (x)                                    \
-            CTZ(rd, rs);                          \
-        else                                      \
-            CTZW(rd, rs);                         \
-    } else {                                      \
-        NEG(s2, rs);                              \
-        AND(s2, s2, rs);                          \
-        TABLE64(s1, 0x03f79d71b4ca8b09ULL);       \
-        MUL(s2, s2, s1);                          \
-        SRLI(s2, s2, 64 - 6);                     \
-        TABLE64(s1, (uintptr_t) & deBruijn64tab); \
-        ADD(s1, s1, s2);                          \
-        LBU(rd, s1, 0);                           \
+#define CTZxw(rd, rs, x, s1, s2)            \
+    if (cpuext.zbb) {                       \
+        if (x)                              \
+            CTZ(rd, rs);                    \
+        else                                \
+            CTZW(rd, rs);                   \
+    } else {                                \
+        NEG(s2, rs);                        \
+        AND(s2, s2, rs);                    \
+        TABLE64(s1, 0x03f79d71b4ca8b09ULL); \
+        MUL(s2, s2, s1);                    \
+        SRLI(s2, s2, 64 - 6);               \
+        TABLE64C(s1, const_deBruijn64tab);  \
+        ADD(s1, s1, s2);                    \
+        LBU(rd, s1, 0);                     \
     }
 
 // Count set bits