diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-10-04 16:19:24 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-10-04 16:19:24 +0200 |
| commit | 333bf19c00bfbd887e012d39494b4e89ba78454f (patch) | |
| tree | b032ef5126b97de944ec09ac6704881889f3fc08 | |
| parent | 25599b91b23e8919686a21123939d6deaac44cba (diff) | |
| download | box64-333bf19c00bfbd887e012d39494b4e89ba78454f.tar.gz box64-333bf19c00bfbd887e012d39494b4e89ba78454f.zip | |
[ARM64_DYNAREC] Worked on CF IRET opcode
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 2 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.c | 11 | ||||
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_helper.h | 2 |
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); |