about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
6 files changed, 93 insertions, 33 deletions
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