diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/ARMJIT_A64/ARMJIT_ALU.cpp | 88 | ||||
-rw-r--r-- | src/dolphin/Arm64Emitter.cpp | 16 | ||||
-rw-r--r-- | src/dolphin/Arm64Emitter.h | 2 |
3 files changed, 67 insertions, 39 deletions
diff --git a/src/ARMJIT_A64/ARMJIT_ALU.cpp b/src/ARMJIT_A64/ARMJIT_ALU.cpp index 6f1f99c..1bd427f 100644 --- a/src/ARMJIT_A64/ARMJIT_ALU.cpp +++ b/src/ARMJIT_A64/ARMJIT_ALU.cpp @@ -324,16 +324,29 @@ void Compiler::Comp_Arithmetic(int op, bool S, ARM64Reg rd, ARM64Reg rn, Op2 op2 UBFX(W2, RCPSR, 29, 1); if (S) { - CVInGPR = true; - ADDS(W1, rn, W2); - CSET(W2, CC_CS); - CSET(W3, CC_VS); if (op2.IsImm) - ADDSI2R(rd, W1, op2.Imm, W0); + { + CVInGPR = true; + ADDS(W1, rn, W2); + CSET(W2, CC_CS); + CSET(W3, CC_VS); + if (op2.IsImm) + ADDSI2R(rd, W1, op2.Imm, W0); + else + ADDS(rd, W1, op2.Reg.Rm, op2.ToArithOption()); + CSINC(W2, W2, WZR, CC_CC); + CSINC(W3, W3, WZR, CC_VC); + } else - ADDS(rd, W1, op2.Reg.Rm, op2.ToArithOption()); - CSINC(W2, W2, WZR, CC_CC); - CSINC(W3, W3, WZR, CC_VC); + { + if (op2.Reg.ShiftAmount > 0) + { + MOV(W0, op2.Reg.Rm, op2.ToArithOption()); + op2 = Op2(W0, ST_LSL, 0); + } + CMP(W2, 1); + ADCS(rd, rn, op2.Reg.Rm); + } } else { @@ -346,25 +359,38 @@ void Compiler::Comp_Arithmetic(int op, bool S, ARM64Reg rd, ARM64Reg rn, Op2 op2 break; case 0x6: // SBC UBFX(W2, RCPSR, 29, 1); - // W1 = -op2 - 1 - if (op2.IsImm) - MOVI2R(W1, ~op2.Imm); - else - ORN(W1, WZR, op2.Reg.Rm, op2.ToArithOption()); - if (S) + if (S && !op2.IsImm) { - CVInGPR = true; - ADDS(W1, W2, W1); - CSET(W2, CC_CS); - CSET(W3, CC_VS); - ADDS(rd, rn, W1); - CSINC(W2, W2, WZR, CC_CC); - CSINC(W3, W3, WZR, CC_VC); + if (op2.Reg.ShiftAmount > 0) + { + MOV(W0, op2.Reg.Rm, op2.ToArithOption()); + op2 = Op2(W0, ST_LSL, 0); + } + CMP(W2, 1); + SBCS(rd, rn, op2.Reg.Rm); } else { - ADD(W1, W2, W1); - ADD(rd, rn, W1); + // W1 = -op2 - 1 + if (op2.IsImm) + MOVI2R(W1, ~op2.Imm); + else + ORN(W1, WZR, op2.Reg.Rm, op2.ToArithOption()); + if (S) + { + CVInGPR = true; + ADDS(W1, W2, W1); + CSET(W2, CC_CS); + CSET(W3, CC_VS); + ADDS(rd, rn, W1); + CSINC(W2, W2, WZR, CC_CC); + CSINC(W3, W3, WZR, CC_VC); + } + else + { + ADD(W1, W2, W1); + ADD(rd, rn, W1); + } } break; case 0x7: // RSC @@ -533,21 +559,7 @@ void Compiler::A_Comp_ALUMovOp() } else { - // ORR with shifted operand has cycles latency - if (op2.Reg.ShiftAmount > 0) - { - switch (op2.Reg.ShiftType) - { - case ST_LSL: LSL(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; - case ST_LSR: LSR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; - case ST_ASR: ASR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; - case ST_ROR: ROR(rd, op2.Reg.Rm, op2.Reg.ShiftAmount); break; - } - } - else - { - MOV(rd, op2.Reg.Rm, op2.ToArithOption()); - } + MOV(rd, op2.Reg.Rm, op2.ToArithOption()); } } diff --git a/src/dolphin/Arm64Emitter.cpp b/src/dolphin/Arm64Emitter.cpp index 408411c..47e97b1 100644 --- a/src/dolphin/Arm64Emitter.cpp +++ b/src/dolphin/Arm64Emitter.cpp @@ -1607,7 +1607,21 @@ void ARM64XEmitter::BICS(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ArithOption Shif void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm, ArithOption Shift) { - ORR(Rd, Is64Bit(Rd) ? ZR : WZR, Rm, Shift); + if (Shift.GetType() == ArithOption::TYPE_SHIFTEDREG) + { + switch (Shift.GetShiftType()) + { + case ST_LSL: LSL(Rd, Rm, Shift.GetShiftAmount()); break; + case ST_LSR: LSR(Rd, Rm, Shift.GetShiftAmount()); break; + case ST_ASR: ASR(Rd, Rm, Shift.GetShiftAmount()); break; + case ST_ROR: ROR(Rd, Rm, Shift.GetShiftAmount()); break; + default: ASSERT_MSG(DYNA_REC, false, "Invalid shift type"); break; + } + } + else + { + ORR(Rd, Is64Bit(Rd) ? ZR : WZR, Rm, Shift); + } } void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm) diff --git a/src/dolphin/Arm64Emitter.h b/src/dolphin/Arm64Emitter.h index 3da3912..0b066de 100644 --- a/src/dolphin/Arm64Emitter.h +++ b/src/dolphin/Arm64Emitter.h @@ -469,6 +469,8 @@ public: } TypeSpecifier GetType() const { return m_type; } ARM64Reg GetReg() const { return m_destReg; } + ShiftType GetShiftType() const { return m_shifttype; } + u32 GetShiftAmount() const { return m_shift; } u32 GetData() const { switch (m_type) |