From f04417eb5a117dfe6552f3203d39697b4ef0d7d5 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Thu, 24 Aug 2023 13:16:08 +0200 Subject: [PATCH] Jit: Move addx to ConstantPropagation --- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 2 +- .../Core/Core/PowerPC/Jit64/Jit_Integer.cpp | 11 +-- Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 2 +- .../PowerPC/JitArm64/JitArm64_Integer.cpp | 32 ++------- .../PowerPC/JitCommon/ConstantPropagation.cpp | 68 ++++++++++++++++--- .../PowerPC/JitCommon/ConstantPropagation.h | 12 ++-- 6 files changed, 75 insertions(+), 52 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 6c161bd8b4f..024b4c6e4af 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -1115,7 +1115,7 @@ bool Jit64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) else { const JitCommon::ConstantPropagationResult constant_propagation_result = - m_constant_propagation.EvaluateInstruction(op.inst); + m_constant_propagation.EvaluateInstruction(op.inst, opinfo->flags); if (!constant_propagation_result.instruction_fully_executed) { diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp index d9b5cb360b3..1b5674f65b9 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp @@ -1826,16 +1826,7 @@ void Jit64::addx(UGeckoInstruction inst) int a = inst.RA, b = inst.RB, d = inst.RD; bool carry = !(inst.SUBOP10 & (1 << 8)); - if (gpr.IsImm(a, b)) - { - const s32 i = gpr.SImm32(a), j = gpr.SImm32(b); - gpr.SetImmediate32(d, i + j); - if (carry) - FinalizeCarry(Interpreter::Helper_Carry(i, j)); - if (inst.OE) - GenerateConstantOverflow((s64)i + (s64)j); - } - else if (gpr.IsImm(a) || gpr.IsImm(b)) + if (gpr.IsImm(a) || gpr.IsImm(b)) { const auto [i, j] = gpr.IsImm(a) ? std::pair(a, b) : std::pair(b, a); const s32 imm = gpr.SImm32(i); diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index f968ef5bdf1..ba30b0bc818 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -1351,7 +1351,7 @@ bool JitArm64::DoJit(u32 em_address, JitBlock* b, u32 nextPC) else { const JitCommon::ConstantPropagationResult constant_propagation_result = - m_constant_propagation.EvaluateInstruction(op.inst); + m_constant_propagation.EvaluateInstruction(op.inst, opinfo->flags); if (!constant_propagation_result.instruction_fully_executed) { diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 9ab44b66aed..6739de44399 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -476,14 +476,7 @@ void JitArm64::addx(UGeckoInstruction inst) int a = inst.RA, b = inst.RB, d = inst.RD; - if (gpr.IsImm(a) && gpr.IsImm(b)) - { - s32 i = (s32)gpr.GetImm(a), j = (s32)gpr.GetImm(b); - gpr.SetImmediate(d, i + j); - if (inst.Rc) - ComputeRC0(gpr.GetImm(d)); - } - else if (gpr.IsImm(a) || gpr.IsImm(b)) + if (gpr.IsImm(a) || gpr.IsImm(b)) { int imm_reg = gpr.IsImm(a) ? a : b; int in_reg = gpr.IsImm(a) ? b : a; @@ -1679,25 +1672,12 @@ void JitArm64::addcx(UGeckoInstruction inst) int a = inst.RA, b = inst.RB, d = inst.RD; - if (gpr.IsImm(a) && gpr.IsImm(b)) - { - u32 i = gpr.GetImm(a), j = gpr.GetImm(b); - gpr.SetImmediate(d, i + j); + gpr.BindToRegister(d, d == a || d == b); + CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b)); - bool has_carry = Interpreter::Helper_Carry(i, j); - ComputeCarry(has_carry); - if (inst.Rc) - ComputeRC0(gpr.GetImm(d)); - } - else - { - gpr.BindToRegister(d, d == a || d == b); - CARRY_IF_NEEDED(ADD, ADDS, gpr.R(d), gpr.R(a), gpr.R(b)); - - ComputeCarry(); - if (inst.Rc) - ComputeRC0(gpr.R(d)); - } + ComputeCarry(); + if (inst.Rc) + ComputeRC0(gpr.R(d)); } void JitArm64::divwux(UGeckoInstruction inst) diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp index f29ce2a759e..84a37efa16d 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp @@ -3,6 +3,8 @@ #include "Core/PowerPC/JitCommon/ConstantPropagation.h" +#include "Core/PowerPC/PPCTables.h" + namespace JitCommon { static constexpr u32 BitOR(u32 a, u32 b) @@ -20,7 +22,8 @@ static constexpr u32 BitXOR(u32 a, u32 b) return a ^ b; } -ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst) const +ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruction inst, + u64 flags) const { switch (inst.OPCD) { @@ -37,7 +40,7 @@ ConstantPropagationResult ConstantPropagation::EvaluateInstruction(UGeckoInstruc case 29: // andis return EvaluateBitwiseImm(inst, BitAND); case 31: - return EvaluateTable31(inst); + return EvaluateTable31(inst, flags); default: return {}; } @@ -71,18 +74,65 @@ ConstantPropagationResult ConstantPropagation::EvaluateBitwiseImm(UGeckoInstruct return ConstantPropagationResult(inst.RA, do_op(m_gpr_values[inst.RS], immediate), is_and); } -ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction inst) const +ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction inst, + u64 flags) const +{ + if (flags & FL_OUT_D) + { + // input a, b -> output d + return EvaluateTable31AB(inst, flags); + } + else + { + // input s, b -> output a + return EvaluateTable31SB(inst); + } +} + +ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstruction inst, + u64 flags) const +{ + if (!HasGPR(inst.RA, inst.RB)) + return {}; + + u64 d; + s64 d_overflow; + const u32 a = GetGPR(inst.RA); + const u32 b = GetGPR(inst.RB); + + switch (inst.SUBOP10) + { + case 10: // addcx + case 522: // addcox + case 266: // addx + case 778: // addox + d = u64(a) + u64(b); + d_overflow = s64(s32(a)) + s64(s32(b)); + break; + default: + return {}; + } + + ConstantPropagationResult result(inst.RD, u32(d), inst.Rc); + if (flags & FL_SET_CA) + result.carry = (d >> 32 != 0); + if (flags & FL_SET_OE) + result.overflow = (d_overflow != s64(s32(d_overflow))); + return result; +} + +ConstantPropagationResult ConstantPropagation::EvaluateTable31SB(UGeckoInstruction inst) const { const bool has_s = HasGPR(inst.RS); const bool has_b = HasGPR(inst.RB); if (!has_s || !has_b) { if (has_s) - return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RS), false); + return EvaluateTable31SBOneRegisterKnown(inst, GetGPR(inst.RS), false); else if (has_b) - return EvaluateTable31OneRegisterKnown(inst, GetGPR(inst.RB), true); + return EvaluateTable31SBOneRegisterKnown(inst, GetGPR(inst.RB), true); else if (inst.RS == inst.RB) - return EvaluateTable31IdenticalRegisters(inst); + return EvaluateTable31SBIdenticalRegisters(inst); else return {}; } @@ -125,8 +175,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31(UGeckoInstruction } ConstantPropagationResult -ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value, - bool known_reg_is_b) const +ConstantPropagation::EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value, + bool known_reg_is_b) const { u32 a; @@ -172,7 +222,7 @@ ConstantPropagation::EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 } ConstantPropagationResult -ConstantPropagation::EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const +ConstantPropagation::EvaluateTable31SBIdenticalRegisters(UGeckoInstruction inst) const { u32 a; diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h index 5560ffdb808..a7f5b27fd30 100644 --- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h +++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h @@ -46,7 +46,7 @@ struct ConstantPropagationResult final class ConstantPropagation final { public: - ConstantPropagationResult EvaluateInstruction(UGeckoInstruction inst) const; + ConstantPropagationResult EvaluateInstruction(UGeckoInstruction inst, u64 flags) const; void Apply(ConstantPropagationResult result); @@ -80,10 +80,12 @@ private: ConstantPropagationResult EvaluateAddImm(UGeckoInstruction inst) const; ConstantPropagationResult EvaluateBitwiseImm(UGeckoInstruction inst, u32 (*do_op)(u32, u32)) const; - ConstantPropagationResult EvaluateTable31(UGeckoInstruction inst) const; - ConstantPropagationResult EvaluateTable31OneRegisterKnown(UGeckoInstruction inst, u32 value, - bool known_reg_is_b) const; - ConstantPropagationResult EvaluateTable31IdenticalRegisters(UGeckoInstruction inst) const; + ConstantPropagationResult EvaluateTable31(UGeckoInstruction inst, u64 flags) const; + ConstantPropagationResult EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const; + ConstantPropagationResult EvaluateTable31SB(UGeckoInstruction inst) const; + ConstantPropagationResult EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value, + bool known_reg_is_b) const; + ConstantPropagationResult EvaluateTable31SBIdenticalRegisters(UGeckoInstruction inst) const; static constexpr ConstantPropagationResult DO_NOTHING = [] { ConstantPropagationResult result;