about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-10-04 16:19:24 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-10-04 16:19:24 +0200
commit333bf19c00bfbd887e012d39494b4e89ba78454f (patch)
treeb032ef5126b97de944ec09ac6704881889f3fc08 /src
parent25599b91b23e8919686a21123939d6deaac44cba (diff)
downloadbox64-333bf19c00bfbd887e012d39494b4e89ba78454f.tar.gz
box64-333bf19c00bfbd887e012d39494b4e89ba78454f.zip
[ARM64_DYNAREC] Worked on CF IRET opcode
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c2
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.c11
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h2
3 files changed, 12 insertions, 3 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index ae8ee1c8..098c3072 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -2491,7 +2491,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("IRET");
             SETFLAGS(X_ALL, SF_SET_NODF);    // Not a hack, EFLAGS are restored
             BARRIER(BARRIER_FLOAT);
-            iret_to_epilog(dyn, ninst, rex.w);
+            iret_to_epilog(dyn, ninst, rex.is32bits, rex.w);
             *need_epilog = 0;
             *ok = 0;
             break;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.c b/src/dynarec/arm64/dynarec_arm64_helper.c
index 7f8c57cd..5e2ed69d 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.c
+++ b/src/dynarec/arm64/dynarec_arm64_helper.c
@@ -693,10 +693,12 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex, int n)
     CLEARIP();
 }
 
-void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
+void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is32bits, int is64bits)
 {
+    int64_t j64;
     //#warning TODO: is64bits
     MAYUSE(ninst);
+    MAYUSE(j64);
     MESSAGE(LOG_DUMP, "IRet to epilog\n");
     SMEND();
     SET_DFNONE(x2);
@@ -719,6 +721,12 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
     ANDx_REG(xFlags, xFlags, x1);
     ORRx_mask(xFlags, xFlags, 1, 0b111111, 0); // xFlags | 0b10
     SET_DFNONE(x1);
+    if(is32bits) {
+        ANDw_mask(x2, x2, 0, 7);   // mask 0xff
+        // check if return segment is 64bits, then restore rsp too
+        CMPSw_U12(x2, 0x23);
+        B_MARKSEG(cEQ);
+    }
     // POP RSP
     if(is64bits) {
         POP1(x3);   //rsp
@@ -732,6 +740,7 @@ void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits)
     STRw_U12(xZR, xEmu, offsetof(x64emu_t, segs_serial[_SS]));
     // set new RSP
     MOVx_REG(xRSP, x3);
+    MARKSEG;
     // Ret....
     MOV64x(x2, (uintptr_t)arm64_epilog);  // epilog on purpose, CS might have changed!
     BR(x2);
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 06e7705b..d3451182 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -1379,7 +1379,7 @@ void jump_to_epilog(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst);
 void jump_to_next(dynarec_arm_t* dyn, uintptr_t ip, int reg, int ninst, int is32bits);
 void ret_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex);
 void retn_to_epilog(dynarec_arm_t* dyn, int ninst, rex_t rex, int n);
-void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is64bits);
+void iret_to_epilog(dynarec_arm_t* dyn, int ninst, int is32bits, int is64bits);
 void call_c(dynarec_arm_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg);
 void call_n(dynarec_arm_t* dyn, int ninst, void* fnc, int w);
 void grab_segdata(dynarec_arm_t* dyn, uintptr_t addr, int ninst, int reg, int segment);