diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-11 15:55:14 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-11 15:55:14 +0100 |
| commit | 02e7400ef06f33521089c847fd8b2358589a370b (patch) | |
| tree | 6df0e28466da0a52386f68ffa0543d0462116e49 /src | |
| parent | 6d6f29b6e17e2932448b024182bb147b0fb7939d (diff) | |
| download | box64-02e7400ef06f33521089c847fd8b2358589a370b.tar.gz box64-02e7400ef06f33521089c847fd8b2358589a370b.zip | |
[ARM64_DYNAREC] Reorganised D0/D2 opcodes and Added shl8c emitter use
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 228 |
1 files changed, 132 insertions, 96 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 6760a583..73e086f1 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -2087,123 +2087,53 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin *ok = 0; break; case 0xD0: - case 0xD2: // TODO: Jump if CL is 0 nextop = F8; switch((nextop>>3)&7) { case 0: - if(opcode==0xD0) { - INST_NAME("ROL Eb, 1"); - SETFLAGS(X_OF|X_CF, SF_SUBSET); - GETEB(x1, 0); - emit_rol8c(dyn, ninst, ed, 1, x4, x5); - EBBACK; - } else { - INST_NAME("ROL Eb, CL"); - SETFLAGS(X_OF|X_CF, SF_SUBSET); - UFLAG_IF { - TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f - } - ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007 - MOV32w(x4, 8); - SUBx_REG(x2, x4, x2); - GETEB(x1, 0); - UFLAG_IF { - B_NEXT(cEQ); - } - ORRw_REG_LSL(ed, ed, ed, 8); - LSRw_REG(ed, ed, x2); - EBBACK; - UFLAG_IF { // calculate flags directly - CMPSw_U12(x2, 7); - B_MARK(cNE); - LSRxw(x3, ed, 7); - ADDxw_REG(x3, x3, ed); - BFIw(xFlags, x3, F_OF, 1); - MARK; - BFIw(xFlags, ed, F_CF, 1); - UFLAG_DF(x2, d_none); - } - } + INST_NAME("ROL Eb, 1"); + SETFLAGS(X_OF|X_CF, SF_SUBSET); + GETEB(x1, 0); + emit_rol8c(dyn, ninst, ed, 1, x4, x5); + EBBACK; break; case 1: - if(opcode==0xD0) { - INST_NAME("ROR Eb, 1"); - MOV32w(x2, 1); - SETFLAGS(X_OF|X_CF, SF_SUBSET); - GETEB(x1, 0); - emit_ror8c(dyn, ninst, ed, 1, x4, x5); - EBBACK; - } else { - INST_NAME("ROR Eb, CL"); - SETFLAGS(X_OF|X_CF, SF_SUBSET); - UFLAG_IF { - TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f - } - ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007 - GETEB(x1, 0); - UFLAG_IF { - B_NEXT(cEQ); - } - ORRw_REG_LSL(ed, ed, ed, 8); - LSRw_REG(ed, ed, x2); - EBBACK; - UFLAG_IF { // calculate flags directly - CMPSw_U12(x2, 1); - B_MARK(cNE); - LSRxw(x2, ed, 6); // x2 = d>>30 - EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1)) - BFIw(xFlags, x2, F_OF, 1); - MARK; - BFXILw(xFlags, ed, 7, 1); - UFLAG_DF(x2, d_none); - } - } + INST_NAME("ROR Eb, 1"); + SETFLAGS(X_OF|X_CF, SF_SUBSET); + GETEB(x1, 0); + emit_ror8c(dyn, ninst, ed, 1, x4, x5); + EBBACK; break; case 2: - if(opcode==0xD0) {INST_NAME("RCL Eb, 1");} else {INST_NAME("RCL Eb, CL");} + INST_NAME("RCL Eb, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); SETFLAGS(X_OF|X_CF, SF_SET); - if(opcode==0xD0) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);} + MOV32w(x2, 1); GETEB(x1, 0); CALL_(rcl8, x1, x3); EBBACK; break; case 3: - if(opcode==0xD0) {INST_NAME("RCR Eb, 1");} else {INST_NAME("RCR Eb, CL");} + INST_NAME("RCR Eb, 1"); MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); SETFLAGS(X_OF|X_CF, SF_SET); - if(opcode==0xD0) {MOV32w(x2, 1);} else {ANDSw_mask(x2, xRCX, 0, 0b00100);} + MOV32w(x2, 1); GETEB(x1, 0); CALL_(rcr8, x1, x3); EBBACK; break; case 4: case 6: - if(opcode==0xD0) { - INST_NAME("SHL Eb, 1"); - MOV32w(x2, 1); - } else { - INST_NAME("SHL Eb, CL"); - ANDSw_mask(x2, xRCX, 0, 0b00100); - } - SETFLAGS(X_ALL, SF_PENDING); + INST_NAME("SHL Eb, 1"); + SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined GETEB(x1, 0); - UFLAG_OP12(ed, x2) - LSLw_REG(ed, ed, x2); + emit_shl8c(dyn, ninst, ed, 1, x3, x4); EBBACK; - UFLAG_RES(ed); - UFLAG_DF(x3, d_shl8); break; case 5: - if(opcode==0xD0) { - INST_NAME("SHR Eb, 1"); - MOV32w(x2, 1); - } else { - INST_NAME("SHR Eb, CL"); - ANDSw_mask(x2, xRCX, 0, 0b00100); - } + INST_NAME("SHR Eb, 1"); + MOV32w(x2, 1); SETFLAGS(X_ALL, SF_PENDING); GETEB(x1, 0); UFLAG_OP12(ed, x2); @@ -2213,13 +2143,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin UFLAG_DF(x3, d_shr8); break; case 7: - if(opcode==0xD0) { - INST_NAME("SAR Eb, 1"); - MOV32w(x2, 1); - } else { - INST_NAME("SAR Eb, CL"); - ANDSw_mask(x2, xRCX, 0, 0b00100); - } + INST_NAME("SAR Eb, 1"); + MOV32w(x2, 1); SETFLAGS(X_ALL, SF_PENDING); GETSEB(x1, 0); UFLAG_OP12(ed, x2) @@ -2291,6 +2216,117 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin break; } break; + case 0xD2: // TODO: Jump if CL is 0 + nextop = F8; + switch((nextop>>3)&7) { + case 0: + INST_NAME("ROL Eb, CL"); + SETFLAGS(X_OF|X_CF, SF_SUBSET); + UFLAG_IF { + TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f + } + ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007 + MOV32w(x4, 8); + SUBx_REG(x2, x4, x2); + GETEB(x1, 0); + UFLAG_IF { + B_NEXT(cEQ); + } + ORRw_REG_LSL(ed, ed, ed, 8); + LSRw_REG(ed, ed, x2); + EBBACK; + UFLAG_IF { // calculate flags directly + CMPSw_U12(x2, 7); + B_MARK(cNE); + LSRxw(x3, ed, 7); + ADDxw_REG(x3, x3, ed); + BFIw(xFlags, x3, F_OF, 1); + MARK; + BFIw(xFlags, ed, F_CF, 1); + UFLAG_DF(x2, d_none); + } + break; + case 1: + INST_NAME("ROR Eb, CL"); + SETFLAGS(X_OF|X_CF, SF_SUBSET); + UFLAG_IF { + TSTw_mask(xRCX, 0, 0b00100); //mask=0x00000001f + } + ANDw_mask(x2, xRCX, 0, 0b00010); //mask=0x000000007 + GETEB(x1, 0); + UFLAG_IF { + B_NEXT(cEQ); + } + ORRw_REG_LSL(ed, ed, ed, 8); + LSRw_REG(ed, ed, x2); + EBBACK; + UFLAG_IF { // calculate flags directly + CMPSw_U12(x2, 1); + B_MARK(cNE); + LSRxw(x2, ed, 6); // x2 = d>>30 + EORw_REG_LSR(x2, x2, x2, 1); // x2 = ((d>>30) ^ ((d>>30)>>1)) + BFIw(xFlags, x2, F_OF, 1); + MARK; + BFXILw(xFlags, ed, 7, 1); + UFLAG_DF(x2, d_none); + } + break; + case 2: + INST_NAME("RCL Eb, CL"); + MESSAGE(LOG_DUMP, "Need Optimization\n"); + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + ANDSw_mask(x2, xRCX, 0, 0b00100); + GETEB(x1, 0); + CALL_(rcl8, x1, x3); + EBBACK; + break; + case 3: + INST_NAME("RCR Eb, CL"); + MESSAGE(LOG_DUMP, "Need Optimization\n"); + READFLAGS(X_CF); + SETFLAGS(X_OF|X_CF, SF_SET); + ANDSw_mask(x2, xRCX, 0, 0b00100); + GETEB(x1, 0); + CALL_(rcr8, x1, x3); + EBBACK; + break; + case 4: + case 6: + INST_NAME("SHL Eb, CL"); + ANDSw_mask(x2, xRCX, 0, 0b00100); + SETFLAGS(X_ALL, SF_PENDING); + GETEB(x1, 0); + UFLAG_OP12(ed, x2) + LSLw_REG(ed, ed, x2); + EBBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_shl8); + break; + case 5: + INST_NAME("SHR Eb, CL"); + ANDSw_mask(x2, xRCX, 0, 0b00100); + SETFLAGS(X_ALL, SF_PENDING); + GETEB(x1, 0); + UFLAG_OP12(ed, x2); + LSRw_REG(ed, ed, x2); + EBBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_shr8); + break; + case 7: + INST_NAME("SAR Eb, CL"); + ANDSw_mask(x2, xRCX, 0, 0b00100); + SETFLAGS(X_ALL, SF_PENDING); + GETSEB(x1, 0); + UFLAG_OP12(ed, x2) + ASRw_REG(ed, ed, x2); + EBBACK; + UFLAG_RES(ed); + UFLAG_DF(x3, d_sar8); + break; + } + break; case 0xD3: nextop = F8; switch((nextop>>3)&7) { |