some tiny A64 optimisations
This commit is contained in:
parent
aa430608e7
commit
5a071c4c29
|
@ -324,16 +324,29 @@ void Compiler::Comp_Arithmetic(int op, bool S, ARM64Reg rd, ARM64Reg rn, Op2 op2
|
||||||
UBFX(W2, RCPSR, 29, 1);
|
UBFX(W2, RCPSR, 29, 1);
|
||||||
if (S)
|
if (S)
|
||||||
{
|
{
|
||||||
CVInGPR = true;
|
|
||||||
ADDS(W1, rn, W2);
|
|
||||||
CSET(W2, CC_CS);
|
|
||||||
CSET(W3, CC_VS);
|
|
||||||
if (op2.IsImm)
|
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
|
else
|
||||||
ADDS(rd, W1, op2.Reg.Rm, op2.ToArithOption());
|
{
|
||||||
CSINC(W2, W2, WZR, CC_CC);
|
if (op2.Reg.ShiftAmount > 0)
|
||||||
CSINC(W3, W3, WZR, CC_VC);
|
{
|
||||||
|
MOV(W0, op2.Reg.Rm, op2.ToArithOption());
|
||||||
|
op2 = Op2(W0, ST_LSL, 0);
|
||||||
|
}
|
||||||
|
CMP(W2, 1);
|
||||||
|
ADCS(rd, rn, op2.Reg.Rm);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -346,25 +359,38 @@ void Compiler::Comp_Arithmetic(int op, bool S, ARM64Reg rd, ARM64Reg rn, Op2 op2
|
||||||
break;
|
break;
|
||||||
case 0x6: // SBC
|
case 0x6: // SBC
|
||||||
UBFX(W2, RCPSR, 29, 1);
|
UBFX(W2, RCPSR, 29, 1);
|
||||||
// W1 = -op2 - 1
|
if (S && !op2.IsImm)
|
||||||
if (op2.IsImm)
|
|
||||||
MOVI2R(W1, ~op2.Imm);
|
|
||||||
else
|
|
||||||
ORN(W1, WZR, op2.Reg.Rm, op2.ToArithOption());
|
|
||||||
if (S)
|
|
||||||
{
|
{
|
||||||
CVInGPR = true;
|
if (op2.Reg.ShiftAmount > 0)
|
||||||
ADDS(W1, W2, W1);
|
{
|
||||||
CSET(W2, CC_CS);
|
MOV(W0, op2.Reg.Rm, op2.ToArithOption());
|
||||||
CSET(W3, CC_VS);
|
op2 = Op2(W0, ST_LSL, 0);
|
||||||
ADDS(rd, rn, W1);
|
}
|
||||||
CSINC(W2, W2, WZR, CC_CC);
|
CMP(W2, 1);
|
||||||
CSINC(W3, W3, WZR, CC_VC);
|
SBCS(rd, rn, op2.Reg.Rm);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ADD(W1, W2, W1);
|
// W1 = -op2 - 1
|
||||||
ADD(rd, rn, W1);
|
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;
|
break;
|
||||||
case 0x7: // RSC
|
case 0x7: // RSC
|
||||||
|
@ -533,21 +559,7 @@ void Compiler::A_Comp_ALUMovOp()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// ORR with shifted operand has cycles latency
|
MOV(rd, op2.Reg.Rm, op2.ToArithOption());
|
||||||
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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1607,7 +1607,21 @@ void ARM64XEmitter::BICS(ARM64Reg Rd, ARM64Reg Rn, ARM64Reg Rm, ArithOption Shif
|
||||||
|
|
||||||
void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm, ArithOption Shift)
|
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)
|
void ARM64XEmitter::MOV(ARM64Reg Rd, ARM64Reg Rm)
|
||||||
|
|
|
@ -469,6 +469,8 @@ public:
|
||||||
}
|
}
|
||||||
TypeSpecifier GetType() const { return m_type; }
|
TypeSpecifier GetType() const { return m_type; }
|
||||||
ARM64Reg GetReg() const { return m_destReg; }
|
ARM64Reg GetReg() const { return m_destReg; }
|
||||||
|
ShiftType GetShiftType() const { return m_shifttype; }
|
||||||
|
u32 GetShiftAmount() const { return m_shift; }
|
||||||
u32 GetData() const
|
u32 GetData() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
|
|
Loading…
Reference in New Issue