From ad7dba541353d532f0299f6442e8ca59a9040695 Mon Sep 17 00:00:00 2001 From: Sintendo <3380580+Sintendo@users.noreply.github.com> Date: Sat, 28 Dec 2024 21:41:48 +0100 Subject: [PATCH] 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] --- .../PowerPC/JitArm64/JitArm64_Integer.cpp | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index b2193faf36..eb742ac1dd 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1468,40 +1468,51 @@ void JitArm64::addex(UGeckoInstruction inst) if (gpr.IsImm(a) && (mex || gpr.IsImm(b))) { - u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b); - - gpr.BindToRegister(d, false); + const u32 i = gpr.GetImm(a), j = mex ? -1 : gpr.GetImm(b); + const u32 imm = i + j; + const bool is_zero = imm == 0; + const bool is_all_ones = imm == 0xFFFFFFFF; switch (js.carryFlag) { case CarryFlag::InPPCState: { - auto WA = gpr.GetScopedReg(); - LDRB(IndexType::Unsigned, WA, PPC_REG, PPCSTATE_OFF(xer_ca)); - ADDI2R(gpr.R(d), WA, i + j, gpr.R(d)); + gpr.BindToRegister(d, false); + ARM64Reg RD = 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; } case CarryFlag::InHostCarry: { + gpr.BindToRegister(d, false); ARM64Reg RD = gpr.R(d); - MOVI2R(RD, i + j); + MOVI2R(RD, imm); ADC(RD, RD, ARM64Reg::WZR); break; } case CarryFlag::ConstantTrue: { - gpr.SetImmediate(d, i + j + 1); + gpr.SetImmediate(d, imm + 1); break; } case CarryFlag::ConstantFalse: { - gpr.SetImmediate(d, i + j); + gpr.SetImmediate(d, imm); break; } } 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) {