diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index ce53909f8d..c8aea9863e 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -260,25 +260,18 @@ void Jit64::regimmop(int d, int a, bool binary, u32 value, Operation doop, if (a || binary || carry) { carry &= js.op->wantsCA; - if (gpr.IsImm(a) && !carry) + RCOpArg Ra = gpr.Use(a, RCMode::Read); + RCX64Reg Rd = gpr.Bind(d, RCMode::Write); + RegCache::Realize(Ra, Rd); + if (doop == Add && Ra.IsSimpleReg() && !carry && d != a) { - gpr.SetImmediate32(d, doop(gpr.Imm32(a), value)); + LEA(32, Rd, MDisp(Ra.GetSimpleReg(), value)); } else { - RCOpArg Ra = gpr.Use(a, RCMode::Read); - RCX64Reg Rd = gpr.Bind(d, RCMode::Write); - RegCache::Realize(Ra, Rd); - if (doop == Add && Ra.IsSimpleReg() && !carry && d != a) - { - LEA(32, Rd, MDisp(Ra.GetSimpleReg(), value)); - } - else - { - if (d != a) - MOV(32, Rd, Ra); - (this->*op)(32, Rd, Imm32(value)); // m_GPR[d] = m_GPR[_inst.RA] + _inst.SIMM_16; - } + if (d != a) + MOV(32, Rd, Ra); + (this->*op)(32, Rd, Imm32(value)); // m_GPR[d] = m_GPR[_inst.RA] + _inst.SIMM_16; } if (carry) FinalizeCarry(CC_C); @@ -304,12 +297,8 @@ void Jit64::reg_imm(UGeckoInstruction inst) switch (inst.OPCD) { case 14: // addi - // occasionally used as MOV - emulate, with immediate propagation - if (a != 0 && d != a && gpr.IsImm(a)) - { - gpr.SetImmediate32(d, gpr.Imm32(a) + (u32)(s32)inst.SIMM_16); - } - else if (a != 0 && d != a && inst.SIMM_16 == 0) + // occasionally used as MOV + if (a != 0 && d != a && inst.SIMM_16 == 0) { RCOpArg Ra = gpr.Use(a, RCMode::Read); RCX64Reg Rd = gpr.Bind(d, RCMode::Write); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 05815710f1..ca8e8ce595 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -217,17 +217,10 @@ void JitArm64::addix(UGeckoInstruction inst) if (a) { - if (gpr.IsImm(a)) - { - gpr.SetImmediate(d, gpr.GetImm(a) + imm); - } - else - { - gpr.BindToRegister(d, d == a); + gpr.BindToRegister(d, d == a); - auto WA = gpr.GetScopedReg(); - ADDI2R(gpr.R(d), gpr.R(a), imm, WA); - } + auto WA = gpr.GetScopedReg(); + ADDI2R(gpr.R(d), gpr.R(a), imm, WA); } else { diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp index 1b09f42c80..34771366f3 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp @@ -24,6 +24,9 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc { switch (inst.OPCD) { + case 14: // addi + case 15: // addis + return EvaluateAddImm(inst); case 24: // ori case 25: // oris return EvaluateBitwiseImm(inst, BitOR); @@ -38,6 +41,19 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc } } +ConstantPropagationResult ConstantPropagation::EvaluateAddImm(UGeckoInstruction inst) const +{ + const s32 immediate = inst.OPCD & 1 ? inst.SIMM_16 << 16 : inst.SIMM_16; + + if (inst.RA == 0) + return ConstantPropagationResult(inst.RD, immediate); + + if (!HasGPR(inst.RA)) + return {}; + + return ConstantPropagationResult(inst.RD, m_gpr_values[inst.RA] + immediate); +} + ConstantPropagationResult ConstantPropagation::EvaluateBitwiseImm(UGeckoInstruction inst, u32 (*do_op)(u32, u32)) const { diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h index 176ee3d513..797c783925 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h @@ -77,6 +77,7 @@ public: void Clear() { m_gpr_values_known = BitSet32{}; } private: + ConstantPropagationResult EvaluateAddImm(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateBitwiseImm(UGeckoInstruction inst, u32 (*do_op)(u32, u32)) const;