JitArm64_Integer: addex - Optimize InPPCState case for 0

Same optimization we did for subfex. Skip loading the carry flag into a
temporary register first when we're dealing with zero.

Before:
0x394bd3b8   ldrb   w24, [x29, #0x2f4]
0x2a1803f9   mov    w25, w24

After:
0x394bd3b9   ldrb   w25, [x29, #0x2f4]
This commit is contained in:
Sintendo 2024-12-28 21:41:48 +01:00
parent 7410bc2025
commit ad7dba5413

View File

@ -1468,40 +1468,51 @@ void JitArm64::addex(UGeckoInstruction inst)
if (gpr.IsImm(a) && (mex || gpr.IsImm(b))) if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
{ {
u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b); const u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b);
const u32 imm = i + j;
gpr.BindToRegister(d, false); const bool is_zero = imm == 0;
const bool is_all_ones = imm == 0xFFFFFFFF;
switch (js.carryFlag) switch (js.carryFlag)
{ {
case CarryFlag::InPPCState: case CarryFlag::InPPCState:
{ {
auto WA = gpr.GetScopedReg(); gpr.BindToRegister(d, false);
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca)); ARM64Reg RD = gpr.R(d);
ADDI2R(gpr.R(d), WA, i + j, gpr.R(d)); if (is_zero)
{
LDRB(IndexType::Unsigned, RD, PPC_REG, PPCSTATE_OFF(xer_ca));
}
else
{
auto WA = gpr.GetScopedReg();
LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca));
ADDI2R(RD, WA, imm, RD);
}
break; break;
} }
case CarryFlag::InHostCarry: case CarryFlag::InHostCarry:
{ {
gpr.BindToRegister(d, false);
ARM64Reg RD = gpr.R(d); ARM64Reg RD = gpr.R(d);
MOVI2R(RD, i + j); MOVI2R(RD, imm);
ADC(RD, RD, ARM64Reg::WZR); ADC(RD, RD, ARM64Reg::WZR);
break; break;
} }
case CarryFlag::ConstantTrue: case CarryFlag::ConstantTrue:
{ {
gpr.SetImmediate(d, i + j + 1); gpr.SetImmediate(d, imm + 1);
break; break;
} }
case CarryFlag::ConstantFalse: case CarryFlag::ConstantFalse:
{ {
gpr.SetImmediate(d, i + j); gpr.SetImmediate(d, imm);
break; break;
} }
} }
const bool must_have_carry = Interpreter::Helper_Carry(i, j); const bool must_have_carry = Interpreter::Helper_Carry(i, j);
const bool might_have_carry = (i + j) == 0xFFFFFFFF; const bool might_have_carry = is_all_ones;
if (must_have_carry) if (must_have_carry)
{ {