mirror of
https://github.com/ptitSeb/box86.git
synced 2025-05-08 21:08:57 +08:00
[DYNAREC] More fixes to CALLRET=1
This commit is contained in:
parent
984da28f40
commit
a9c50ef238
@ -13,7 +13,7 @@ arm_epilog:
|
||||
// restore stack pointer
|
||||
ldr sp, [r0, #(8*4+2*4)]
|
||||
pop {r4, r5}
|
||||
str r5, [r0, #(8*4+2*4)] // put back old value
|
||||
str r4, [r0, #(8*4+2*4)] // put back old value
|
||||
//restore all used register
|
||||
vpop {d8-d15}
|
||||
pop {r4-r12, pc}
|
||||
@ -26,7 +26,7 @@ arm_epilog_fast:
|
||||
// restore stack pointer
|
||||
ldr sp, [r0, #(8*4+2*4)]
|
||||
pop {r4, r5}
|
||||
str r5, [r0, #(8*4+2*4)] // put back old value
|
||||
str r4, [r0, #(8*4+2*4)] // put back old value
|
||||
//restore all used register
|
||||
vpop {d8-d15}
|
||||
pop {r4-r12, pc}
|
||||
|
@ -12,8 +12,8 @@ arm_prolog:
|
||||
push {r4-r12, lr}
|
||||
vpush {d8-d15}
|
||||
// save Sp and setup stack for optionnal callret
|
||||
ldr r5, [r0, #(8*4+2*4)] // grab old value of xSPSave
|
||||
mov r4, #0
|
||||
ldr r4, [r0, #(8*4+2*4)] // grab old value of xSPSave
|
||||
mov r5, #0
|
||||
push {r4-r5}
|
||||
str sp, [r0, #(8*4+2*4)]
|
||||
//setup emu -> register
|
||||
|
@ -2337,7 +2337,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
// Push actual return address
|
||||
if(addr < (dyn->start+dyn->isize)) {
|
||||
// there is a next...
|
||||
j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0;
|
||||
j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)-8):0;
|
||||
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j32>>2);
|
||||
ADR(c__, x14, j32);
|
||||
} else {
|
||||
@ -2346,7 +2346,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV32(x14, j32);
|
||||
LDR_IMM9(x14, x14, 0);
|
||||
}
|
||||
STMDB(xSP, (1<<x2)|(1<<x14));
|
||||
PUSH(xSP, (1<<x2)|(1<<x14));
|
||||
} else {
|
||||
*need_epilog = 0;
|
||||
*ok = 0;
|
||||
@ -3002,7 +3002,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
// Push actual return address
|
||||
if(addr < (dyn->start+dyn->isize)) {
|
||||
// there is a next...
|
||||
j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0;
|
||||
j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)-8):0;
|
||||
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j32>>2);
|
||||
ADR(c__, x3, j32);
|
||||
} else {
|
||||
@ -3011,7 +3011,7 @@ uintptr_t dynarec00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV32(x3, j32);
|
||||
LDR_IMM9(x3, x3, 0);
|
||||
}
|
||||
STMDB(xSP, (1<<x2)|(1<<x3));
|
||||
PUSH(xSP, (1<<x2)|(1<<x3));
|
||||
}
|
||||
PUSH1(x2);
|
||||
jump_to_next(dyn, 0, ed, ninst);
|
||||
|
@ -365,7 +365,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
{
|
||||
READFLAGS(X_PEND); // that's suspicious
|
||||
} else {
|
||||
SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state
|
||||
SETFLAGS(X_ALL, SF_SET_NODF); //Hack to put flag in "don't care" state
|
||||
}
|
||||
if(MODREG) { // reg
|
||||
MOV_REG(xEIP, xEAX+(nextop&7));
|
||||
@ -387,7 +387,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
// Push actual return address
|
||||
if(addr < (dyn->start+dyn->isize)) {
|
||||
// there is a next...
|
||||
j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)):0;
|
||||
j32 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->arm_size)-8):0;
|
||||
MESSAGE(LOG_NONE, "\tCALLRET set return to +%di\n", j32>>2);
|
||||
ADR(c__, x3, j32);
|
||||
} else {
|
||||
@ -396,7 +396,7 @@ uintptr_t dynarecFS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst,
|
||||
MOV32(x3, j32);
|
||||
LDR_IMM9(x3, x3, 0);
|
||||
}
|
||||
STMDB(xSP, (1<<x2)|(1<<x3));
|
||||
PUSH(xSP, (1<<x2)|(1<<x3));
|
||||
}
|
||||
PUSH1(x2);
|
||||
jump_to_next(dyn, 0, xEIP, ninst);
|
||||
|
@ -293,12 +293,13 @@ void ret_to_epilog(dynarec_arm_t* dyn, int ninst)
|
||||
SMEND();
|
||||
if(box86_dynarec_callret) {
|
||||
// pop the actual return address for ARM stack
|
||||
LDM(xSP, (1<<x2)|(1<<x3));
|
||||
CMPS_REG_LSL_IMM5(x3, xEIP, 0); // is it the right address?
|
||||
BXcond(cEQ, x2);
|
||||
POP(xSP, (1<<x2)|(1<<x3));
|
||||
CMPS_REG_LSL_IMM5(x2, xEIP, 0); // is it the right address?
|
||||
BXcond(cEQ, x3);
|
||||
// not the correct return address, regular jump, but purge the stack first, it's unsync now...
|
||||
CMPS_IMM8(x2, 0); // that was already the top of the stack...
|
||||
CMPS_IMM8(x3, 0); // that was already the top of the stack...
|
||||
LDR_IMM9_COND(cNE, xSP, xEmu, offsetof(x86emu_t, xSPSave)); // load pointer only if not already on top
|
||||
SUB_COND_IMM8(cEQ, xSP, xSP, 8); // unpop
|
||||
}
|
||||
MOV32(x2, getJumpTable());
|
||||
MOV_REG_LSR_IMM5(x3, xEIP, JMPTABL_SHIFT);
|
||||
@ -325,12 +326,13 @@ void retn_to_epilog(dynarec_arm_t* dyn, int ninst, int n)
|
||||
SMEND();
|
||||
if(box86_dynarec_callret) {
|
||||
// pop the actual return address for ARM stack
|
||||
LDM(xSP, (1<<x2)|(1<<x3));
|
||||
CMPS_REG_LSL_IMM5(x3, xEIP, 0); // is it the right address?
|
||||
BXcond(cEQ, x2);
|
||||
POP(xSP, (1<<x2)|(1<<x3));
|
||||
CMPS_REG_LSL_IMM5(x2, xEIP, 0); // is it the right address?
|
||||
BXcond(cEQ, x3);
|
||||
// not the correct return address, regular jump, but purge the stack first, it's unsync now...
|
||||
CMPS_IMM8(x2, 0); // that was already the top of the stack...
|
||||
CMPS_IMM8(x3, 0); // that was already the top of the stack...
|
||||
LDR_IMM9_COND(cNE, xSP, xEmu, offsetof(x86emu_t, xSPSave));
|
||||
SUB_COND_IMM8(cEQ, xSP, xSP, 8); // unpop
|
||||
}
|
||||
MOV32(x2, getJumpTable());
|
||||
MOV_REG_LSR_IMM5(x3, xEIP, JMPTABL_SHIFT);
|
||||
|
Loading…
x
Reference in New Issue
Block a user