diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-10-06 18:19:55 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-10-06 12:19:55 +0200 |
| commit | 172df2cd0cade8c591bbff7a7e288bc867c01c9e (patch) | |
| tree | e5b7892ee496f45b8e3f7ad97ad9d457d008c9d9 /src/dynarec/la64 | |
| parent | b395cd7ccc0a3b98b82306a35a2d96a9d42c5d7d (diff) | |
| download | box64-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.c | 14 |
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(); } |