Merge pull request #9820 from JosJuice/jitarm64-simplify-addex

JitArm64: Simplify addex/subfex
This commit is contained in:
Markus Wick 2021-07-08 13:46:48 +02:00 committed by GitHub
commit a390d3f327
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 84 deletions

View File

@ -265,6 +265,7 @@ protected:
void ComputeCarry(Arm64Gen::ARM64Reg reg); // reg must contain 0 or 1 void ComputeCarry(Arm64Gen::ARM64Reg reg); // reg must contain 0 or 1
void ComputeCarry(bool carry); void ComputeCarry(bool carry);
void ComputeCarry(); void ComputeCarry();
void LoadCarry();
void FlushCarry(); void FlushCarry();
void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32), void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),

View File

@ -75,6 +75,35 @@ void JitArm64::ComputeCarry()
FlushCarry(); FlushCarry();
} }
void JitArm64::LoadCarry()
{
switch (js.carryFlag)
{
case CarryFlag::InPPCState:
{
ARM64Reg WA = gpr.GetReg();
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
CMP(WA, 1);
gpr.Unlock(WA);
break;
}
case CarryFlag::InHostCarry:
{
break;
}
case CarryFlag::ConstantTrue:
{
CMP(ARM64Reg::WZR, ARM64Reg::WZR);
break;
}
case CarryFlag::ConstantFalse:
{
CMN(ARM64Reg::WZR, ARM64Reg::WZR);
break;
}
}
}
void JitArm64::FlushCarry() void JitArm64::FlushCarry()
{ {
switch (js.carryFlag) switch (js.carryFlag)
@ -995,45 +1024,17 @@ void JitArm64::subfex(UGeckoInstruction inst)
{ {
gpr.BindToRegister(d, d == a || d == b); gpr.BindToRegister(d, d == a || d == b);
switch (js.carryFlag) if (js.carryFlag == CarryFlag::ConstantTrue)
{
case CarryFlag::InPPCState:
{
// upload the carry state
ARM64Reg WA = gpr.GetReg();
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
CMP(WA, 1);
gpr.Unlock(WA);
[[fallthrough]];
}
case CarryFlag::InHostCarry:
{
CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a));
ComputeCarry();
break;
}
case CarryFlag::ConstantTrue:
{ {
CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a)); CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
ComputeCarry();
break;
} }
case CarryFlag::ConstantFalse: else
{ {
ARM64Reg WA = gpr.GetReg(); LoadCarry();
CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a));
if (gpr.IsImm(a))
MOVI2R(WA, u32(~gpr.GetImm(a)));
else
MVN(WA, gpr.R(a));
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), WA, gpr.R(b));
gpr.Unlock(WA);
ComputeCarry();
break;
}
} }
ComputeCarry();
} }
if (inst.Rc) if (inst.Rc)
@ -1211,60 +1212,17 @@ void JitArm64::addex(UGeckoInstruction inst)
{ {
gpr.BindToRegister(d, d == a || d == b); gpr.BindToRegister(d, d == a || d == b);
if (js.carryFlag == CarryFlag::ConstantTrue && !gpr.IsImm(a) && !gpr.IsImm(b)) if (js.carryFlag == CarryFlag::ConstantFalse)
{
CMP(ARM64Reg::WZR, ARM64Reg::WZR);
js.carryFlag = CarryFlag::InHostCarry;
}
switch (js.carryFlag)
{
case CarryFlag::InPPCState:
{
// upload the carry state
ARM64Reg WA = gpr.GetReg();
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
CMP(WA, 1);
gpr.Unlock(WA);
[[fallthrough]];
}
case CarryFlag::InHostCarry:
{
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), gpr.R(b));
ComputeCarry();
break;
}
case CarryFlag::ConstantTrue:
{
if (!gpr.IsImm(b))
std::swap(a, b);
ASSERT(gpr.IsImm(b));
ARM64Reg WA = gpr.GetReg();
const u32 imm = gpr.GetImm(b) + 1;
if (imm == 0)
{
if (d != a)
MOV(gpr.R(d), gpr.R(a));
ComputeCarry(true);
}
else
{
CARRY_IF_NEEDED(ADDI2R, ADDSI2R, gpr.R(d), gpr.R(a), imm, WA);
ComputeCarry();
}
gpr.Unlock(WA);
break;
}
case CarryFlag::ConstantFalse:
{ {
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b)); CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
ComputeCarry();
break;
} }
else
{
LoadCarry();
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), gpr.R(b));
} }
ComputeCarry();
} }
if (inst.Rc) if (inst.Rc)