summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2024-08-31 16:03:02 +0200
committerJosJuice <josjuice@gmail.com>2025-11-16 09:50:31 +0100
commit204a8fbd5348ae2b072bca63697a72adb4c357ae (patch)
tree96039899eb70f2eacaf7e521f87ae681cf5c918a /Source
parent2134991be8300eb454ab2e779973017ef29f6c46 (diff)
Jit: Move subfx to ConstantPropagation
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp19
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp36
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp31
-rw-r--r--Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h2
4 files changed, 39 insertions, 49 deletions
diff --git a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
index cdca3274af..f10bca3cf3 100644
--- a/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
+++ b/Source/Core/Core/PowerPC/Jit64/Jit_Integer.cpp
@@ -1097,24 +1097,7 @@ void Jit64::subfx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
const bool carry = !(inst.SUBOP10 & (1 << 5));
- if (a == b)
- {
- gpr.SetImmediate32(d, 0);
- if (carry)
- FinalizeCarry(true);
- if (inst.OE)
- GenerateConstantOverflow(false);
- }
- else if (gpr.IsImm(a, b))
- {
- s32 i = gpr.SImm32(b), j = gpr.SImm32(a);
- gpr.SetImmediate32(d, i - j);
- if (carry)
- FinalizeCarry(j == 0 || Interpreter::Helper_Carry((u32)i, 0u - (u32)j));
- if (inst.OE)
- GenerateConstantOverflow((s64)i - (s64)j);
- }
- else if (gpr.IsImm(a))
+ if (gpr.IsImm(a))
{
s32 j = gpr.SImm32(a);
RCOpArg Rb = gpr.Use(b, RCMode::Read);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index 1a4027059c..fe5a401b6a 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -1122,26 +1122,10 @@ void JitArm64::subfx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
- if (a == b)
- {
- gpr.SetImmediate(d, 0);
- if (inst.Rc)
- ComputeRC0(gpr.GetImm(d));
- }
- else if (gpr.IsImm(a) && gpr.IsImm(b))
- {
- u32 i = gpr.GetImm(a), j = gpr.GetImm(b);
- gpr.SetImmediate(d, j - i);
- if (inst.Rc)
- ComputeRC0(gpr.GetImm(d));
- }
- else
- {
- gpr.BindToRegister(d, d == a || d == b);
- SUB(gpr.R(d), gpr.R(b), gpr.R(a));
- if (inst.Rc)
- ComputeRC0(gpr.R(d));
- }
+ gpr.BindToRegister(d, d == a || d == b);
+ SUB(gpr.R(d), gpr.R(b), gpr.R(a));
+ if (inst.Rc)
+ ComputeRC0(gpr.R(d));
}
void JitArm64::subfex(UGeckoInstruction inst)
@@ -1283,17 +1267,7 @@ void JitArm64::subfcx(UGeckoInstruction inst)
int a = inst.RA, b = inst.RB, d = inst.RD;
- if (gpr.IsImm(a) && gpr.IsImm(b))
- {
- u32 a_imm = gpr.GetImm(a), b_imm = gpr.GetImm(b);
-
- gpr.SetImmediate(d, b_imm - a_imm);
- ComputeCarry(a_imm == 0 || Interpreter::Helper_Carry(b_imm, 0u - a_imm));
-
- if (inst.Rc)
- ComputeRC0(gpr.GetImm(d));
- }
- else if (gpr.IsImm(a, 0))
+ if (gpr.IsImm(a, 0))
{
if (d != b)
{
diff --git a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp
index 980347062b..f794af1653 100644
--- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp
+++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.cpp
@@ -213,6 +213,8 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstructi
return EvaluateTable31ABOneRegisterKnown(inst, flags, GetGPR(inst.RA));
else if (has_b)
return EvaluateTable31ABOneRegisterKnown(inst, flags, GetGPR(inst.RB));
+ else if (inst.RA == inst.RB)
+ return EvaluateTable31ABIdenticalRegisters(inst, flags);
else
return {};
}
@@ -224,6 +226,13 @@ ConstantPropagationResult ConstantPropagation::EvaluateTable31AB(UGeckoInstructi
switch (inst.SUBOP10)
{
+ case 8: // subfcx
+ case 40: // subfx
+ case 520: // subfcox
+ case 552: // subfox
+ d = u64(u32(~a)) + u64(b) + 1;
+ d_overflow = s64(s32(b)) - s64(s32(a));
+ break;
case 10: // addcx
case 522: // addcox
case 266: // addx
@@ -276,6 +285,28 @@ ConstantPropagation::EvaluateTable31ABOneRegisterKnown(UGeckoInstruction inst, u
return {};
}
+ConstantPropagationResult
+ConstantPropagation::EvaluateTable31ABIdenticalRegisters(UGeckoInstruction inst, u64 flags) const
+{
+ switch (inst.SUBOP10)
+ {
+ case 8: // subfcx
+ case 40: // subfx
+ case 520: // subfcox
+ case 552: // subfox
+ {
+ ConstantPropagationResult result(inst.RD, 0, inst.Rc);
+ if (flags & FL_SET_CA)
+ result.carry = true;
+ if (flags & FL_SET_OE)
+ result.overflow = false;
+ return result;
+ }
+ default:
+ 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 4ff7823aa4..7b4759c0ae 100644
--- a/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h
+++ b/Source/Core/Core/PowerPC/JitCommon/ConstantPropagation.h
@@ -89,6 +89,8 @@ private:
ConstantPropagationResult EvaluateTable31AB(UGeckoInstruction inst, u64 flags) const;
ConstantPropagationResult EvaluateTable31ABOneRegisterKnown(UGeckoInstruction inst, u64 flags,
u32 value) const;
+ ConstantPropagationResult EvaluateTable31ABIdenticalRegisters(UGeckoInstruction inst,
+ u64 flags) const;
ConstantPropagationResult EvaluateTable31SB(UGeckoInstruction inst) const;
ConstantPropagationResult EvaluateTable31SBOneRegisterKnown(UGeckoInstruction inst, u32 value,
bool known_reg_is_b) const;