summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2023-08-24 13:16:08 +0200
committerJosJuice <josjuice@gmail.com>2025-11-16 09:50:31 +0100
commitf04417eb5a117dfe6552f3203d39697b4ef0d7d5 (patch)
tree7624420c0a3318f23dba65b7e3b32fe967cccafd /Source/Core
parent77b46c30aded7b562566483ab8d94c24c3461499 (diff)
Jit: Move addx to ConstantPropagation
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit.cpp2
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp11
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.cpp2
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp32
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp68
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h12
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 6c161bd8b4..024b4c6e4a 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 d9b5cb360b..1b5674f65b 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 f968ef5bdf..ba30b0bc81 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 9ab44b66ae..6739de4439 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 f29ce2a759..84a37efa16 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 5560ffdb80..a7f5b27fd3 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;