diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-19 16:50:21 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-19 16:50:27 +0100 |
| commit | 10088c6566f4ecb4b1405c977a395fa75d2f72a0 (patch) | |
| tree | bc60f490954f6167269a82d62efa519bcce61122 /src | |
| parent | a2abb4e8b161cd049aa5196e09a63ca2eb5c1f44 (diff) | |
| download | box64-10088c6566f4ecb4b1405c977a395fa75d2f72a0.tar.gz box64-10088c6566f4ecb4b1405c977a395fa75d2f72a0.zip | |
[DYNAREC] Added 0F 80..8F Jcc Id opcodes (and factorised GOCOND macro)
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 90 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_0f.c | 111 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 90 |
3 files changed, 115 insertions, 176 deletions
diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index 01901c10..0646a630 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -293,94 +293,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } \ } - case 0x70: - INST_NAME("JO ib"); - GO( TSTw_mask(xFlags, 0b010101, 0) - , cEQ, cNE, X_OF) - break; - case 0x71: - INST_NAME("JNO ib"); - GO( TSTw_mask(xFlags, 0b010101, 0) - , cNE, cEQ, X_OF) - break; - case 0x72: - INST_NAME("JC ib"); - GO( TSTw_mask(xFlags, 0, 0) - , cEQ, cNE, X_CF) - break; - case 0x73: - INST_NAME("JNC ib"); - GO( TSTw_mask(xFlags, 0, 0) - , cNE, cEQ, X_CF) - break; - case 0x74: - INST_NAME("JZ ib"); - GO( TSTw_mask(xFlags, 0b011010, 0) - , cEQ, cNE, X_ZF) - break; - case 0x75: - INST_NAME("JNZ ib"); - GO( TSTw_mask(xFlags, 0b011010, 0) - , cNE, cEQ, X_ZF) - break; - case 0x76: - INST_NAME("JBE ib"); - GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF)); - TSTw_REG(xFlags, x1) - , cEQ, cNE, X_CF|X_ZF) - break; - case 0x77: - INST_NAME("JNBE ib"); - GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF)); - TSTw_REG(xFlags, x1) - , cNE, cEQ, X_CF|X_ZF) - break; - case 0x78: - INST_NAME("JS ib"); - GO( TSTw_mask(xFlags, 0b011001, 0) // 0X80 - , cEQ, cNE, X_SF) - break; - case 0x79: - INST_NAME("JNS ib"); - GO( TSTw_mask(xFlags, 0b011001, 0) - , cNE, cEQ, X_SF) - break; - case 0x7A: - INST_NAME("JP ib"); - GO( TSTw_mask(xFlags, 0b011110, 0) - , cEQ, cNE, X_PF) - break; - case 0x7B: - INST_NAME("JNP ib"); - GO( TSTw_mask(xFlags, 0b011110, 0) - , cNE, cEQ, X_PF) - break; - case 0x7C: - INST_NAME("JL ib"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - TSTw_mask(x1, 0b010101, 0) - , cEQ, cNE, X_SF|X_OF) - break; - case 0x7D: - INST_NAME("JGE ib"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - TSTw_mask(x1, 0b010101, 0) - , cNE, cEQ, X_SF|X_OF) - break; - case 0x7E: - INST_NAME("JLE ib"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF); - TSTw_mask(x1, 0b010101, 0) - , cEQ, cNE, X_SF|X_OF|X_ZF) - break; - case 0x7F: - INST_NAME("JG ib"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF); - TSTw_mask(x1, 0b010101, 0) - , cNE, cEQ, X_SF|X_OF|X_ZF) - break; + GOCOND(0x70, "J", "ib"); + #undef GO case 0x80: diff --git a/src/dynarec/dynarec_arm64_0f.c b/src/dynarec/dynarec_arm64_0f.c index 5270d981..afc0ce34 100755 --- a/src/dynarec/dynarec_arm64_0f.c +++ b/src/dynarec/dynarec_arm64_0f.c @@ -104,96 +104,31 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin if(!rex.w) {MOVw_REG(gd, gd);} \ } - case 0x40: - INST_NAME("CMOVO Gd, Ed"); - GO( TSTw_mask(xFlags, 0b010101, 0) - , cEQ, cNE, X_OF) - break; - case 0x41: - INST_NAME("CMOVNO Gd, Ed"); - GO( TSTw_mask(xFlags, 0b010101, 0) - , cNE, cEQ, X_OF) - break; - case 0x42: - INST_NAME("CMOVC Gd, Ed"); - GO( TSTw_mask(xFlags, 0, 0) - , cEQ, cNE, X_CF) - break; - case 0x43: - INST_NAME("CMOVNC Gd, Ed"); - GO( TSTw_mask(xFlags, 0, 0) - , cNE, cEQ, X_CF) - break; - case 0x44: - INST_NAME("CMOVZ Gd, Ed"); - GO( TSTw_mask(xFlags, 0b011010, 0) - , cEQ, cNE, X_ZF) - break; - case 0x45: - INST_NAME("CMOVNZ Gd, Ed"); - GO( TSTw_mask(xFlags, 0b011010, 0) - , cNE, cEQ, X_ZF) - break; - case 0x46: - INST_NAME("CMOVBE Gd, Ed"); - GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF)); - TSTw_REG(xFlags, x1) - , cEQ, cNE, X_CF|X_ZF) - break; - case 0x47: - INST_NAME("CMOVNBE Gd, Ed"); - GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF)); - TSTw_REG(xFlags, x1) - , cNE, cEQ, X_CF|X_ZF) - break; - case 0x48: - INST_NAME("CMOVS Gd, Ed"); - GO( TSTw_mask(xFlags, 0b011001, 0) // 0X80 - , cEQ, cNE, X_SF) - break; - case 0x49: - INST_NAME("CMOVNS Gd, Ed"); - GO( TSTw_mask(xFlags, 0b011001, 0) - , cNE, cEQ, X_SF) - break; - case 0x4A: - INST_NAME("CMOVP Gd, Ed"); - GO( TSTw_mask(xFlags, 0b011110, 0) - , cEQ, cNE, X_PF) - break; - case 0x4B: - INST_NAME("CMOVNP Gd, Ed"); - GO( TSTw_mask(xFlags, 0b011110, 0) - , cNE, cEQ, X_PF) - break; - case 0x4C: - INST_NAME("CMOVL Gd, Ed"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - TSTw_mask(x1, 0b010101, 0) - , cEQ, cNE, X_SF|X_OF) - break; - case 0x4D: - INST_NAME("CMOVGE Gd, Ed"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - TSTw_mask(x1, 0b010101, 0) - , cNE, cEQ, X_SF|X_OF) - break; - case 0x4E: - INST_NAME("CMOVLE Gd, Ed"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF); - TSTw_mask(x1, 0b010101, 0) - , cEQ, cNE, X_SF|X_OF|X_ZF) - break; - case 0x4F: - INST_NAME("CMOVG Gd, Ed"); - GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); - ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF); - TSTw_mask(x1, 0b010101, 0) - , cNE, cEQ, X_SF|X_OF|X_ZF) - break; + GOCOND(0x40, "CMOV", "Gd, Ed"); #undef GO + #define GO(GETFLAGS, NO, YES, F) \ + READFLAGS(F); \ + i32_ = F32S; \ + BARRIER(2); \ + JUMP(addr+i32_);\ + GETFLAGS; \ + if(dyn->insts) { \ + if(dyn->insts[ninst].x64.jmp_insts==-1) { \ + /* out of the block */ \ + i32 = dyn->insts[ninst+1].address-(dyn->arm_size); \ + Bcond(NO, i32); \ + jump_to_next(dyn, addr+i32_, 0, ninst); \ + } else { \ + /* inside the block */ \ + i32 = dyn->insts[dyn->insts[ninst].x64.jmp_insts].address-(dyn->arm_size); \ + Bcond(YES, i32); \ + } \ + } + + GOCOND(0x80, "J", "Id"); + #undef GO + case 0xBB: INST_NAME("BTC Ed, Gd"); SETFLAGS(X_CF, SF_SET); diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 69f48f1a..b7ef4a6a 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -781,4 +781,94 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n #define MAYUSE(A) #endif +#define GOCOND(B, T1, T2) \ + case B+0x0: \ + INST_NAME(T1 "O " T2); \ + GO( TSTw_mask(xFlags, 0b010101, 0) \ + , cEQ, cNE, X_OF) \ + break; \ + case B+0x1: \ + INST_NAME(T1 "NO " T2); \ + GO( TSTw_mask(xFlags, 0b010101, 0) \ + , cNE, cEQ, X_OF) \ + break; \ + case B+0x2: \ + INST_NAME(T1 "C " T2); \ + GO( TSTw_mask(xFlags, 0, 0) \ + , cEQ, cNE, X_CF) \ + break; \ + case B+0x3: \ + INST_NAME(T1 "NC " T2); \ + GO( TSTw_mask(xFlags, 0, 0) \ + , cNE, cEQ, X_CF) \ + break; \ + case B+0x4: \ + INST_NAME(T1 "Z " T2); \ + GO( TSTw_mask(xFlags, 0b011010, 0) \ + , cEQ, cNE, X_ZF) \ + break; \ + case B+0x5: \ + INST_NAME(T1 "NZ " T2); \ + GO( TSTw_mask(xFlags, 0b011010, 0) \ + , cNE, cEQ, X_ZF) \ + break; \ + case B+0x6: \ + INST_NAME(T1 "BE " T2); \ + GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF)); \ + TSTw_REG(xFlags, x1) \ + , cEQ, cNE, X_CF|X_ZF) \ + break; \ + case B+0x7: \ + INST_NAME(T1 "NBE " T2); \ + GO( MOV32w(x1, (1<<F_CF)|(1<<F_ZF)); \ + TSTw_REG(xFlags, x1) \ + , cNE, cEQ, X_CF|X_ZF) \ + break; \ + case B+0x8: \ + INST_NAME(T1 "S " T2); \ + GO( TSTw_mask(xFlags, 0b011001, 0) \ + , cEQ, cNE, X_SF) \ + break; \ + case B+0x9: \ + INST_NAME(T1 "NS " T2); \ + GO( TSTw_mask(xFlags, 0b011001, 0) \ + , cNE, cEQ, X_SF) \ + break; \ + case B+0xA: \ + INST_NAME(T1 "P " T2); \ + GO( TSTw_mask(xFlags, 0b011110, 0) \ + , cEQ, cNE, X_PF) \ + break; \ + case B+0xB: \ + INST_NAME(T1 "NP " T2); \ + GO( TSTw_mask(xFlags, 0b011110, 0) \ + , cNE, cEQ, X_PF) \ + break; \ + case B+0xC: \ + INST_NAME(T1 "L " T2); \ + GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); \ + TSTw_mask(x1, 0b010101, 0) \ + , cEQ, cNE, X_SF|X_OF) \ + break; \ + case B+0xD: \ + INST_NAME(T1 "GE " T2); \ + GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); \ + TSTw_mask(x1, 0b010101, 0) \ + , cNE, cEQ, X_SF|X_OF) \ + break; \ + case B+0xE: \ + INST_NAME(T1 "LE " T2); \ + GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); \ + ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF); \ + TSTw_mask(x1, 0b010101, 0) \ + , cEQ, cNE, X_SF|X_OF|X_ZF) \ + break; \ + case B+0xF: \ + INST_NAME(T1 "G " T2); \ + GO( EORw_REG_LSL(x1, xFlags, xFlags, F_OF-F_SF); \ + ORRw_REG_LSL(x1, x1, xFlags, F_OF-F_ZF); \ + TSTw_mask(x1, 0b010101, 0) \ + , cNE, cEQ, X_SF|X_OF|X_ZF) \ + break + #endif //__DYNAREC_ARM64_HELPER_H__ \ No newline at end of file |