about summary refs log tree commit diff stats
path: root/src/dynarec/la64
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-10-06 18:19:55 +0800
committerGitHub <noreply@github.com>2024-10-06 12:19:55 +0200
commit172df2cd0cade8c591bbff7a7e288bc867c01c9e (patch)
treee5b7892ee496f45b8e3f7ad97ad9d457d008c9d9 /src/dynarec/la64
parentb395cd7ccc0a3b98b82306a35a2d96a9d42c5d7d (diff)
downloadbox64-172df2cd0cade8c591bbff7a7e288bc867c01c9e.tar.gz
box64-172df2cd0cade8c591bbff7a7e288bc867c01c9e.zip
[DYNAREC] Tweaking indirect jumps for CALL/RET to use the return address stack (#1907)
Diffstat (limited to 'src/dynarec/la64')
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.c14
1 files changed, 7 insertions, 7 deletions
diff --git a/src/dynarec/la64/dynarec_la64_helper.c b/src/dynarec/la64/dynarec_la64_helper.c
index 1d23f10a..b33445f3 100644
--- a/src/dynarec/la64/dynarec_la64_helper.c
+++ b/src/dynarec/la64/dynarec_la64_helper.c
@@ -571,7 +571,7 @@ void jump_to_next(dynarec_la64_t* dyn, uintptr_t ip, int reg, int ninst, int is3
 // MOVx(x3, 15);    no access to PC reg
 #endif
     SMEND();
-    JIRL(xRA, x2, 0x0); // save LR...
+    JIRL((dyn->insts[ninst].x64.has_callret ? xRA : xZR), x2, 0x0); // save LR...
 }
 
 void ret_to_epilog(dynarec_la64_t* dyn, int ninst, rex_t rex)
@@ -584,11 +584,11 @@ void ret_to_epilog(dynarec_la64_t* dyn, int ninst, rex_t rex)
     SMEND();
     if (box64_dynarec_callret) {
         // pop the actual return address from RV64 stack
-        LD_D(x2, xSP, 0);     // native addr
+        LD_D(xRA, xSP, 0);     // native addr
         LD_D(x6, xSP, 8);     // x86 addr
         ADDI_D(xSP, xSP, 16); // pop
         BNE(x6, xRIP, 2 * 4); // is it the right address?
-        BR(x2);
+        BR(xRA);
         // not the correct return address, regular jump, but purge the stack first, it's unsync now...
         ADDI_D(xSP, xSavedSP, -16);
     }
@@ -609,7 +609,7 @@ void ret_to_epilog(dynarec_la64_t* dyn, int ninst, rex_t rex)
     BSTRPICK_D(x2, xRIP, JMPTABL_START0 + JMPTABL_SHIFT0 - 1, JMPTABL_START0);
     ALSL_D(x3, x2, x3, 3);
     LD_D(x2, x3, 0);
-    BR(x2); // save LR
+    BR(x2);
     CLEARIP();
 }
 
@@ -629,11 +629,11 @@ void retn_to_epilog(dynarec_la64_t* dyn, int ninst, rex_t rex, int n)
     SMEND();
     if (box64_dynarec_callret) {
         // pop the actual return address from RV64 stack
-        LD_D(x2, xSP, 0);     // native addr
+        LD_D(xRA, xSP, 0);     // native addr
         LD_D(x6, xSP, 8);     // x86 addr
         ADDI_D(xSP, xSP, 16); // pop
         BNE(x6, xRIP, 2 * 4); // is it the right address?
-        BR(x2);
+        BR(xRA);
         // not the correct return address, regular jump, but purge the stack first, it's unsync now...
         ADDI_D(xSP, xSavedSP, -16);
     }
@@ -654,7 +654,7 @@ void retn_to_epilog(dynarec_la64_t* dyn, int ninst, rex_t rex, int n)
     BSTRPICK_D(x2, xRIP, JMPTABL_START0 + JMPTABL_SHIFT0 - 1, JMPTABL_START0);
     ALSL_D(x3, x2, x3, 3);
     LD_D(x2, x3, 0);
-    BR(x2); // save LR
+    BR(x2);
     CLEARIP();
 }