diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-03-20 10:34:00 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-03-20 10:34:00 +0100 |
| commit | cc2016bbc9b6a68c730db2982e1060df250c7a97 (patch) | |
| tree | b056981f637b20749047a9bc82e958d5b69e4e50 /src | |
| parent | a68be9117b1d8cc78e9e6ceea5f8236f074983c9 (diff) | |
| download | box64-cc2016bbc9b6a68c730db2982e1060df250c7a97.tar.gz box64-cc2016bbc9b6a68c730db2982e1060df250c7a97.zip | |
[DYNAREC] Added 66 D1/D3 opcodes
Diffstat (limited to 'src')
| -rwxr-xr-x | src/dynarec/arm64_emitter.h | 7 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_00.c | 2 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_66.c | 103 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64_helper.h | 2 |
4 files changed, 107 insertions, 7 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h index 4d8c6ff3..5e72e4d8 100755 --- a/src/dynarec/arm64_emitter.h +++ b/src/dynarec/arm64_emitter.h @@ -210,9 +210,10 @@ #define LDRB_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b00, Rm, 0b011, 0, Rn, Rt)) #define LDRH_REG(Rt, Rn, Rm) EMIT(LDR_REG_gen(0b01, Rm, 0b011, 0, Rn, Rt)) -#define LDRSH_gen(size, op1, opc, imm9, op2, Rn, Rt) ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm9)<<12 | (op2)<<10 | (Rn)<<5 | (Rt)) -#define LDRSHx_U12(Rt, Rn, imm12) EMIT(LD_gen(0b01, 0b00, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt)) -#define LDRSHw_U12(Rt, Rn, imm12) EMIT(LD_gen(0b01, 0b00, 0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt)) +#define LDRSH_gen(size, op1, opc, imm12, Rn, Rt) ((size)<<30 | 0b111<<27 | (op1)<<24 | (opc)<<22 | (imm12)<<10 | (Rn)<<5 | (Rt)) +#define LDRSHx_U12(Rt, Rn, imm12) EMIT(LDRSH_gen(0b01, 0b01, 0b10, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt)) +#define LDRSHw_U12(Rt, Rn, imm12) EMIT(LDRSH_gen(0b01, 0b01, 0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt)) +#define LDRSHxw_U12(Rt, Rn, imm12) EMIT(LDRSH_gen(0b01, 0b01, rex.w?0b10:0b11, ((uint32_t)(imm12>>1))&0xfff, Rn, Rt)) #define LDR_PC_gen(opc, imm19, Rt) ((opc)<<30 | 0b011<<27 | (imm19)<<5 | (Rt)) #define LDRx_literal(Rt, imm19) EMIT(LDR_PC_gen(0b01, ((imm19)>>2)&0x7FFFF, Rt)) diff --git a/src/dynarec/dynarec_arm64_00.c b/src/dynarec/dynarec_arm64_00.c index d0bb204c..fb1424de 100755 --- a/src/dynarec/dynarec_arm64_00.c +++ b/src/dynarec/dynarec_arm64_00.c @@ -283,7 +283,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; case 0x66: - addr = dynarec64_66(dyn, addr, ip, ninst, rex, ok, need_epilog); + addr = dynarec64_66(dyn, addr, ip, ninst, rex, rep, ok, need_epilog); break; case 0x68: diff --git a/src/dynarec/dynarec_arm64_66.c b/src/dynarec/dynarec_arm64_66.c index 3242b169..e2ad11e6 100755 --- a/src/dynarec/dynarec_arm64_66.c +++ b/src/dynarec/dynarec_arm64_66.c @@ -23,7 +23,7 @@ #include "dynarec_arm64_functions.h" -uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog) +uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog) { uint8_t opcode = F8; uint8_t nextop, u8; @@ -34,7 +34,6 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uint8_t gd, ed; uint8_t wback, wb1; int fixedaddress; - int rep; MAYUSE(u16); MAYUSE(u8); MAYUSE(j32); @@ -61,6 +60,106 @@ uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin addr = dynarec64_660F(dyn, addr, ip, ninst, rex, ok, need_epilog); break; + case 0xD1: + case 0xD3: + nextop = F8; + switch((nextop>>3)&7) { + case 0: + if(opcode==0xD1) { + INST_NAME("ROL Ew, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("ROL Ew, CL"); + ANDSw_mask(x2, xRCX, 0, 0b00100); + } + SETFLAGS(X_OF|X_CF, SF_SET); + GETEW(x1, 0); + CALL_(rol16, x1, x3); + EWBACK; + break; + case 1: + if(opcode==0xD1) { + INST_NAME("ROR Ew, 1"); + MOV32w(x2, 1); + } else { + INST_NAME("ROR Ew, CL"); + ANDSw_mask(x2, xRCX, 0, 0b00100); + } + SETFLAGS(X_OF|X_CF, SF_SET); + GETEW(x1, 0); + CALL_(ror16, x1, x3); + EWBACK; + break; + case 2: + if(opcode==0xD1) {INST_NAME("RCL Ew, 1"); } else { INST_NAME("RCL Ew, CL");} + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);} + GETEW(x1, 0); + CALL_(rcl16, x1, x3); + EWBACK; + break; + case 3: + if(opcode==0xD1) {INST_NAME("RCR Ew, 1");} else {INST_NAME("RCR Ew, CL");} + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + if(opcode==0xD1) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);} + GETEW(x1, 0); + CALL_(rcr16, x1, x3); + EWBACK; + break; + case 4: + case 6: + if(opcode==0xD1) { + INST_NAME("SHL Ew, 1"); + MOV32w(x4, 1); + } else { + INST_NAME("SHL Ew, CL"); + ANDSw_mask(x4, xRCX, 0, 0b00100); + } + SETFLAGS(X_ALL, SF_PENDING); + GETEW(x1, 0); + UFLAG_OP12(ed, x4) + LSLw_REG(ed, ed, x4); + EWBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_shl16); + break; + case 5: + if(opcode==0xD1) { + INST_NAME("SHR Ew, 1"); + MOV32w(x4, 1); + } else { + INST_NAME("SHR Ew, CL"); + ANDSw_mask(x4, xRCX, 0, 0b00100); + } + SETFLAGS(X_ALL, SF_PENDING); + GETEW(x1, 0); + UFLAG_OP12(ed, x4) + LSRw_REG(ed, ed, x4); + EWBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_shr16); + break; + case 7: + if(opcode==0xD1) { + INST_NAME("SAR Ew, 1"); + MOV32w(x4, 1); + } else { + INST_NAME("SAR Ew, CL"); + ANDSw_mask(x4, xRCX, 0, 0b00100); + } + SETFLAGS(X_ALL, SF_PENDING); + GETSEW(x1, 0); + UFLAG_OP12(ed, x4) + ASRw_REG(ed, ed, x4); + EWBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_sar16); + break; + } + break; + default: DEFAULT; } diff --git a/src/dynarec/dynarec_arm64_helper.h b/src/dynarec/dynarec_arm64_helper.h index 0c08e5c4..6615598f 100755 --- a/src/dynarec/dynarec_arm64_helper.h +++ b/src/dynarec/dynarec_arm64_helper.h @@ -761,7 +761,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); //uintptr_t dynarec64_FS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); //uintptr_t dynarec64_GS(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); -uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); +uintptr_t dynarec64_66(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int rep, int* ok, int* need_epilog); //uintptr_t dynarec64_67(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); //uintptr_t dynarec64_D8(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); //uintptr_t dynarec64_D9(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog); |