diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-16 15:39:40 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-16 15:39:40 +0000 |
| commit | dbd1b977fc5bae2dea51e62399228cfe7c271ac0 (patch) | |
| tree | 8c8b3798f67ba24daeda8517b0895bff961dbf17 /src | |
| parent | 5d14667536418889607a97310f966ce3cb32727b (diff) | |
| download | box64-dbd1b977fc5bae2dea51e62399228cfe7c271ac0.tar.gz box64-dbd1b977fc5bae2dea51e62399228cfe7c271ac0.zip | |
[ARM64_DYNAREC] Added FF /2 CALL, /4 JMP and /6 PUSH opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00.c | 64 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 18 |
2 files changed, 82 insertions, 0 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c index 76202092..e6bea413 100644 --- a/src/dynarec/rv64/dynarec_rv64_00.c +++ b/src/dynarec/rv64/dynarec_rv64_00.c @@ -665,6 +665,70 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni *ok = 0; break; + case 0xFF: + nextop = F8; + switch((nextop>>3)&7) { + case 0: // INC Ed + DEFAULT; + break; + case 1: //DEC Ed + DEFAULT; + break; + case 2: // CALL Ed + INST_NAME("CALL Ed"); + PASS2IF((box64_dynarec_safeflags>1) || + ((ninst && dyn->insts[ninst-1].x64.set_flags) + || ((ninst>1) && dyn->insts[ninst-2].x64.set_flags)), 1) + { + READFLAGS(X_PEND); // that's suspicious + } else { + SETFLAGS(X_ALL, SF_SET); //Hack to put flag in "don't care" state + } + GETEDx(0); + if(box64_dynarec_callret && box64_dynarec_bigblock>1) { + BARRIER(BARRIER_FULL); + } else { + BARRIER(BARRIER_FLOAT); + *need_epilog = 0; + *ok = 0; + } + GETIP_(addr); + // TODO: Add suport for CALLRET optim + /*if(box64_dynarec_callret) { + // Push actual return address + if(addr < (dyn->start+dyn->isize)) { + // there is a next... + j64 = (dyn->insts)?(dyn->insts[ninst].epilog-(dyn->native_size)):0; + ADR_S20(x4, j64); + } else { + j64 = getJumpTableAddress64(addr); + TABLE64(x4, j64); + LDRx_U12(x4, x4, 0); + } + STPx_S7_preindex(x4, xRIP, xSP, -16); + }*/ + PUSH1(xRIP); + jump_to_next(dyn, 0, ed, ninst); + break; + case 4: // JMP Ed + INST_NAME("JMP Ed"); + READFLAGS(X_PEND); + BARRIER(BARRIER_FLOAT); + GETEDx(0); + jump_to_next(dyn, 0, ed, ninst); + *need_epilog = 0; + *ok = 0; + break; + case 6: // Push Ed + INST_NAME("PUSH Ed"); + GETEDx(0); + PUSH1(ed); + break; + + default: + DEFAULT; + } + break; default: DEFAULT; } diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 83e9c8cc..47f59fb7 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -73,6 +73,17 @@ ed = x1; \ } +// GETEDx can use r1 for ed, and r2 for wback. wback is 0 if ed is xEAX..xEDI +#define GETEDx(D) if(MODREG) { \ + ed = xRAX+(nextop&7)+(rex.b<<3); \ + wback = 0; \ + } else { \ + SMREAD() \ + addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, D); \ + LD(x1, wback, fixedaddress); \ + ed = x1; \ + } + // FAKEED like GETED, but doesn't get anything #define FAKEED if(!MODREG) { \ addr = fakeed(dyn, addr, ninst, nextop); \ @@ -330,6 +341,13 @@ #endif #define CLEARIP() dyn->last_ip=0 +#if STEP < 2 +#define PASS2IF(A, B) if(A) +#elif STEP == 2 +#define PASS2IF(A, B) if(A) dyn->insts[ninst].pass2choice = B; if(dyn->insts[ninst].pass2choice == B) +#else +#define PASS2IF(A, B) if(dyn->insts[ninst].pass2choice == B) +#endif #define MODREG ((nextop&0xC0)==0xC0) |