diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-15 22:45:09 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-15 22:45:09 +0000 |
| commit | a3ad297f926b0002bcade8f1648b573310119738 (patch) | |
| tree | 3627f896388dc6231fdd6215fbf287185f6d5065 | |
| parent | 6707640fa383a3fee40db4ed7db539cbe247d968 (diff) | |
| download | box64-a3ad297f926b0002bcade8f1648b573310119738.tar.gz box64-a3ad297f926b0002bcade8f1648b573310119738.zip | |
[RV64_PRINTER] Added C2/RETN and C3/RET opocde, along with fixes to jmp_to_next
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 24 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 138 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 4 |
3 files changed, 151 insertions, 15 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 0adae90a..11d37571 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -218,6 +218,30 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni DEFAULT; } break; + case 0xC2: + INST_NAME("RETN"); + //SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...) + if(box64_dynarec_safeflags) { + READFLAGS(X_PEND); // lets play safe here too + } + BARRIER(BARRIER_FLOAT); + i32 = F16; + retn_to_epilog(dyn, ninst, i32); + *need_epilog = 0; + *ok = 0; + break; + case 0xC3: + INST_NAME("RET"); + // SETFLAGS(X_ALL, SF_SET); // Hack, set all flags (to an unknown state...) + if(box64_dynarec_safeflags) { + READFLAGS(X_PEND); // so instead, force the defered flags, so it's not too slow, and flags are not lost + } + BARRIER(BARRIER_FLOAT); + ret_to_epilog(dyn, ninst); + *need_epilog = 0; + *ok = 0; + break; + case 0xC6: INST_NAME("MOV Eb, Ib"); nextop=F8; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 36800a31..204b891d 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -202,25 +202,31 @@ void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst) TABLE64(x3, tbl); SRLI(x2, xRIP, JMPTABL_START3); SLLI(x2, x2, 3); - LD(x3, x3, x2); - LUI(x4, JMPTABLE_MASK2); // x4 = mask - SRLI(x2, xRIP, JMPTABL_START2); + ADD(x3, x3, x2); + LD(x3, x3, 0); + MOV64x(x4, JMPTABLE_MASK2<<3); // x4 = mask + SRLI(x2, xRIP, JMPTABL_START2-3); AND(x2, x2, x4); - SLLI(x2, x2, 3); - LD(x3, x3, x2); + ADD(x3, x3, x2); + LD(x3, x3, 0); if(JMPTABLE_MASK2!=JMPTABLE_MASK1) { - LUI(x4, JMPTABLE_MASK1); // x4 = mask + MOV64x(x4, JMPTABLE_MASK1<<3); // x4 = mask } - SRLI(x2, xRIP, JMPTABL_START1); + SRLI(x2, xRIP, JMPTABL_START1-3); AND(x2, x2, x4); - SLLI(x2, x2, 3); - LD(x3, x3, x2); - if(JMPTABLE_MASK1!=JMPTABLE_MASK0) { - LUI(x4, JMPTABLE_MASK0); // x4 = mask + ADD(x3, x3, x2); + LD(x3, x3, 0); + if(JMPTABLE_MASK0<2048) { + ANDI(x2, xRIP, JMPTABLE_MASK0); + } else { + if(JMPTABLE_MASK1!=JMPTABLE_MASK0) { + MOV64x(x4, JMPTABLE_MASK0); // x4 = mask + } + AND(x2, xRIP, x4); } - AND(x2, x2, x4); SLLI(x2, x2, 3); - LD(x2, x3, x2); + ADD(x3, x3, x2); + LD(x2, x3, 0); } else { uintptr_t p = getJumpTableAddress64(ip); MAYUSE(p); @@ -239,6 +245,112 @@ void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst) JALR(x2); // save LR... } +void ret_to_epilog(dynarec_rv64_t* dyn, int ninst) +{ + MAYUSE(dyn); MAYUSE(ninst); + MESSAGE(LOG_DUMP, "Ret to epilog\n"); + POP1(xRIP); + MV(x1, xRIP); + SMEND(); + /*if(box64_dynarec_callret) { + // pop the actual return address from RV64 stack + LDPx_S7_offset(x2, x6, xSP, 0); + CBZx(x6, 5*4); + ADDx_U12(xSP, xSP, 16); + SUBx_REG(x6, x6, xRIP); // is it the right address? + CBNZx(x6, 2*4); + BLR(x2); + // not the correct return address, regular jump + }*/ + uintptr_t tbl = getJumpTable64(); + MOV64x(x3, tbl); + SRLI(x2, xRIP, JMPTABL_START3); + SLLI(x2, x2, 3); + ADD(x3, x3, x2); + LD(x3, x3, 0); + MOV64x(x4, JMPTABLE_MASK2<<3); // x4 = mask + SRLI(x2, xRIP, JMPTABL_START2-3); + AND(x2, x2, x4); + ADD(x3, x3, x2); + LD(x3, x3, 0); + if(JMPTABLE_MASK2!=JMPTABLE_MASK1) { + MOV64x(x4, JMPTABLE_MASK1<<3); // x4 = mask + } + SRLI(x2, xRIP, JMPTABL_START1-3); + AND(x2, x2, x4); + ADD(x3, x3, x2); + LD(x3, x3, 0); + if(JMPTABLE_MASK0<2048) { + ANDI(x2, xRIP, JMPTABLE_MASK0); + } else { + if(JMPTABLE_MASK1!=JMPTABLE_MASK0) { + MOV64x(x4, JMPTABLE_MASK0); // x4 = mask + } + AND(x2, xRIP, x4); + } + SLLI(x2, x2, 3); + ADD(x3, x3, x2); + LD(x2, x3, 0); + JALR(x2); // save LR + CLEARIP(); +} + +void retn_to_epilog(dynarec_rv64_t* dyn, int ninst, int n) +{ + MAYUSE(dyn); MAYUSE(ninst); + MESSAGE(LOG_DUMP, "Retn to epilog\n"); + POP1(xRIP); + if(n>0x7ff) { + MOV64x(w1, n); + ADD(xRSP, xRSP, x1); + } else { + ADDI(xRSP, xRSP, n); + } + MV(x1, xRIP); + SMEND(); + /*if(box64_dynarec_callret) { + // pop the actual return address from RV64 stack + LDPx_S7_offset(x2, x6, xSP, 0); + CBZx(x6, 5*4); + ADDx_U12(xSP, xSP, 16); + SUBx_REG(x6, x6, xRIP); // is it the right address? + CBNZx(x6, 2*4); + BLR(x2); + // not the correct return address, regular jump + }*/ + uintptr_t tbl = getJumpTable64(); + MOV64x(x3, tbl); + SRLI(x2, xRIP, JMPTABL_START3); + SLLI(x2, x2, 3); + ADD(x3, x3, x2); + LD(x3, x3, 0); + MOV64x(x4, JMPTABLE_MASK2<<3); // x4 = mask + SRLI(x2, xRIP, JMPTABL_START2-3); + AND(x2, x2, x4); + ADD(x3, x3, x2); + LD(x3, x3, 0); + if(JMPTABLE_MASK2!=JMPTABLE_MASK1) { + MOV64x(x4, JMPTABLE_MASK1<<3); // x4 = mask + } + SRLI(x2, xRIP, JMPTABL_START1-3); + AND(x2, x2, x4); + ADD(x3, x3, x2); + LD(x3, x3, 0); + if(JMPTABLE_MASK0<2048) { + ANDI(x2, xRIP, JMPTABLE_MASK0); + } else { + if(JMPTABLE_MASK1!=JMPTABLE_MASK0) { + MOV64x(x4, JMPTABLE_MASK0); // x4 = mask + } + AND(x2, xRIP, x4); + } + SLLI(x2, x2, 3); + ADD(x3, x3, x2); + LD(x2, x3, 0); + JALR(x2); // save LR + CLEARIP(); +} + void call_c(dynarec_rv64_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int savereg) { MAYUSE(fnc); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index e08b2e49..0795c626 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -494,8 +494,8 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop, // generic x64 helper void jump_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst); void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst); -//void ret_to_epilog(dynarec_rv64_t* dyn, int ninst); -//void retn_to_epilog(dynarec_rv64_t* dyn, int ninst, int n); +void ret_to_epilog(dynarec_rv64_t* dyn, int ninst); +void retn_to_epilog(dynarec_rv64_t* dyn, int ninst, int n); //void iret_to_epilog(dynarec_rv64_t* dyn, int ninst, int is64bits); void call_c(dynarec_rv64_t* dyn, int ninst, void* fnc, int reg, int ret, int saveflags, int save_reg); void call_n(dynarec_rv64_t* dyn, int ninst, void* fnc, int w); |