Merge pull request #9820 from JosJuice/jitarm64-simplify-addex
JitArm64: Simplify addex/subfex
This commit is contained in:
commit
a390d3f327
|
@ -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),
|
||||||
|
|
|
@ -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:
|
|
||||||
{
|
|
||||||
ARM64Reg WA = gpr.GetReg();
|
|
||||||
|
|
||||||
if (gpr.IsImm(a))
|
|
||||||
MOVI2R(WA, u32(~gpr.GetImm(a)));
|
|
||||||
else
|
else
|
||||||
MVN(WA, gpr.R(a));
|
{
|
||||||
|
LoadCarry();
|
||||||
|
CARRY_IF_NEEDED(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a));
|
||||||
|
}
|
||||||
|
|
||||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), WA, gpr.R(b));
|
|
||||||
|
|
||||||
gpr.Unlock(WA);
|
|
||||||
ComputeCarry();
|
ComputeCarry();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
CARRY_IF_NEEDED(ADDI2R, ADDSI2R, gpr.R(d), gpr.R(a), imm, WA);
|
LoadCarry();
|
||||||
ComputeCarry();
|
CARRY_IF_NEEDED(ADC, ADCS, gpr.R(d), gpr.R(a), gpr.R(b));
|
||||||
}
|
}
|
||||||
gpr.Unlock(WA);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case CarryFlag::ConstantFalse:
|
|
||||||
{
|
|
||||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
|
|
||||||
ComputeCarry();
|
ComputeCarry();
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst.Rc)
|
if (inst.Rc)
|
||||||
|
|
Loading…
Reference in New Issue