diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index f10bca3cf3d..4187e9f3468 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -1042,14 +1042,6 @@ void Jit64::subfic(UGeckoInstruction inst) JITDISABLE(bJITIntegerOff); int a = inst.RA, d = inst.RD, imm = inst.SIMM_16; - if (gpr.IsImm(a)) - { - u32 i = imm, j = gpr.Imm32(a); - gpr.SetImmediate32(d, i - j); - FinalizeCarry(j == 0 || (i > j - 1)); - return; - } - RCOpArg Ra = gpr.Use(a, RCMode::Read); RCX64Reg Rd = gpr.Bind(d, RCMode::Write); RegCache::Realize(Ra, Rd); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index fe5a401b6a9..b36d35b2063 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1381,44 +1381,34 @@ void JitArm64::subfic(UGeckoInstruction inst) int a = inst.RA, d = inst.RD; s32 imm = inst.SIMM_16; - if (gpr.IsImm(a)) - { - u32 a_imm = gpr.GetImm(a); + const bool will_read = d == a; + gpr.BindToRegister(d, will_read); + ARM64Reg RD = gpr.R(d); - gpr.SetImmediate(d, imm - a_imm); - ComputeCarry(a_imm == 0 || Interpreter::Helper_Carry(imm, 0u - a_imm)); + if (imm == -1) + { + // d = -1 - a = ~a + MVN(RD, gpr.R(a)); + // CA is always set in this case + ComputeCarry(true); } else { - const bool will_read = d == a; - gpr.BindToRegister(d, will_read); - ARM64Reg RD = gpr.R(d); + const bool is_zero = imm == 0; - if (imm == -1) + // d = imm - a { - // d = -1 - a = ~a - MVN(RD, gpr.R(a)); - // CA is always set in this case - ComputeCarry(true); - } - else - { - const bool is_zero = imm == 0; - - // d = imm - a + Arm64GPRCache::ScopedARM64Reg WA(ARM64Reg::WZR); + if (!is_zero) { - Arm64GPRCache::ScopedARM64Reg WA(ARM64Reg::WZR); - if (!is_zero) - { - WA = will_read ? gpr.GetScopedReg() : Arm64GPRCache::ScopedARM64Reg(RD); - MOVI2R(WA, imm); - } - - CARRY_IF_NEEDED(SUB, SUBS, RD, WA, gpr.R(a)); + WA = will_read ? gpr.GetScopedReg() : Arm64GPRCache::ScopedARM64Reg(RD); + MOVI2R(WA, imm); } - ComputeCarry(); + CARRY_IF_NEEDED(SUB, SUBS, RD, WA, gpr.R(a)); } + + ComputeCarry(); } } diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp index f794af1653c..1f652667967 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp @@ -33,6 +33,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc { case 7: // mulli return EvaluateMulImm(inst); + case 8: // subfic + return EvaluateSubImmCarry(inst); case 12: // addic case 13: // addic. return EvaluateAddImmCarry(inst); @@ -73,6 +75,19 @@ ConstantPropagationResult ConstantPropagation::EvaluateMulImm(UGeckoInstruction return ConstantPropagationResult(inst.RD, m_gpr_values[inst.RA] * inst.SIMM_16); } +ConstantPropagationResult ConstantPropagation::EvaluateSubImmCarry(UGeckoInstruction inst) const +{ + if (!HasGPR(inst.RA)) + return {}; + + const u32 a = GetGPR(inst.RA); + const u32 imm = s32(inst.SIMM_16); + + ConstantPropagationResult result(inst.RD, imm - a); + result.carry = imm >= a; + return result; +} + ConstantPropagationResult ConstantPropagation::EvaluateAddImm(UGeckoInstruction inst) const { const s32 immediate = inst.OPCD & 1 ? inst.SIMM_16 << 16 : inst.SIMM_16; diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h index 7b4759c0aeb..50b1de58ae5 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h @@ -78,6 +78,7 @@ public: private: ConstantPropagationResult EvaluateMulImm(UGeckoInstruction inst) const; + ConstantPropagationResult EvaluateSubImmCarry(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateAddImm(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateAddImmCarry(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateRlwinmxRlwnmx(UGeckoInstruction inst, u32 shift) const;