diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index af6723c821..cdca3274af 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -1201,13 +1201,6 @@ void Jit64::MultiplyImmediate(u32 imm, int a, int d, bool overflow) RCX64Reg Rd = gpr.Bind(d, RCMode::Write); RegCache::Realize(Ra, Rd); - // simplest cases first - if (imm == 0) - { - XOR(32, Rd, Rd); - return; - } - if (imm == (u32)-1) { if (d != a) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 0c901c47a5..bd68618cd7 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -832,14 +832,7 @@ void JitArm64::addic(UGeckoInstruction inst) bool JitArm64::MultiplyImmediate(u32 imm, int a, int d, bool rc) { - if (imm == 0) - { - // Multiplication by zero (0). - gpr.SetImmediate(d, 0); - if (rc) - ComputeRC0(gpr.GetImm(d)); - } - else if (imm == 1) + if (imm == 1) { // Multiplication by one (1). if (d != a) diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp index 78facf40bd..980347062b 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp @@ -64,6 +64,9 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc ConstantPropagationResult ConstantPropagation::EvaluateMulImm(UGeckoInstruction inst) const { + if (inst.SIMM_16 == 0) + return ConstantPropagationResult(inst.RD, 0); + if (!HasGPR(inst.RA)) return {}; @@ -202,8 +205,17 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31S(UGeckoInstructio ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const { - if (!HasGPR(inst.RA, inst.RB)) - return {}; + const bool has_a = HasGPR(inst.RA); + const bool has_b = HasGPR(inst.RB); + if (!has_a || !has_b) + { + if (has_a) + return EvaluateTable31ABOneRegisterKnown(inst, flags, GetGPR(inst.RA)); + else if (has_b) + return EvaluateTable31ABOneRegisterKnown(inst, flags, GetGPR(inst.RB)); + else + return {}; + } u64 d; s64 d_overflow; @@ -241,6 +253,29 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstructi return result; } +ConstantPropagationResult +ConstantPropagation::EvaluateTable31ABOneRegisterKnown(UGeckoInstruction inst, u64 flags, + u32 value) const +{ + switch (inst.SUBOP10) + { + case 11: // mulhwux + case 75: // mulhwx + case 235: // mullwx + case 747: // mullwox + if (value == 0) + { + ConstantPropagationResult result(inst.RD, 0, inst.Rc); + if (flags & FL_SET_OE) + result.overflow = false; + return result; + } + break; + } + + return {}; +} + ConstantPropagationResult ConstantPropagation::EvaluateTable31SB(UGeckoInstruction inst) const { const bool has_s = HasGPR(inst.RS); diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h index 9b8070caf1..4ff7823aa4 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h @@ -87,6 +87,8 @@ private: ConstantPropagationResult EvaluateTable31Negx(UGeckoInstruction inst, u64 flags) const; ConstantPropagationResult EvaluateTable31S(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const; + ConstantPropagationResult EvaluateTable31ABOneRegisterKnown(UGeckoInstruction inst, u64 flags, + u32 value) const; ConstantPropagationResult EvaluateTable31SB(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value, bool known_reg_is_b) const;