mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
JitArm64: Simplify addex/subfex
Some of the code used when the carry flag is known to be a constant value is really not much better than just setting the carry flag and then using the normal code, and with how rarely this code runs, it isn't well tested either. Might as well get rid of some of this code and simplify things.
This commit is contained in:
parent
503c62ec00
commit
752c4898b1
@ -263,6 +263,7 @@ protected:
|
||||
void ComputeCarry(Arm64Gen::ARM64Reg reg); // reg must contain 0 or 1
|
||||
void ComputeCarry(bool carry);
|
||||
void ComputeCarry();
|
||||
void LoadCarry();
|
||||
void FlushCarry();
|
||||
|
||||
void reg_imm(u32 d, u32 a, u32 value, u32 (*do_op)(u32, u32),
|
||||
|
@ -76,6 +76,35 @@ void JitArm64::ComputeCarry()
|
||||
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()
|
||||
{
|
||||
switch (js.carryFlag)
|
||||
@ -996,45 +1025,17 @@ void JitArm64::subfex(UGeckoInstruction inst)
|
||||
{
|
||||
gpr.BindToRegister(d, d == a || d == b);
|
||||
|
||||
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(SBC, SBCS, gpr.R(d), gpr.R(b), gpr.R(a));
|
||||
ComputeCarry();
|
||||
break;
|
||||
}
|
||||
case CarryFlag::ConstantTrue:
|
||||
if (js.carryFlag == CarryFlag::ConstantTrue)
|
||||
{
|
||||
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
|
||||
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();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.Rc)
|
||||
@ -1213,60 +1214,17 @@ void JitArm64::addex(UGeckoInstruction inst)
|
||||
{
|
||||
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);
|
||||
CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b));
|
||||
}
|
||||
else
|
||||
{
|
||||
CARRY_IF_NEEDED(ADDI2R, ADDSI2R, gpr.R(d), gpr.R(a), imm, WA);
|
||||
ComputeCarry();
|
||||
LoadCarry();
|
||||
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();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inst.Rc)
|
||||
|
Loading…
Reference in New Issue
Block a user