summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorSintendo <3380580+Sintendo@users.noreply.github.com>2025-09-20 10:08:31 +0200
committerSintendo <3380580+Sintendo@users.noreply.github.com>2025-11-23 09:54:45 +0100
commit419f90107dfe363aa77167331e4812e689ad9606 (patch)
tree99b8480f8c6f6b0a6ff7fe2aee78c74b179b9dcb /Source
parent490615c72ade1a41c6382fd5d21d96c424317e2c (diff)
JitArm64_Integer: Merge subfx and subfcx
The optimizations for subfcx introduced in #13852 also apply to subfx. Rather than duplicating the logic, we merge the handlers, like we did in #10120 for x86.
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/Jit.h1
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp47
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp4
3 files changed, 22 insertions, 30 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.h b/Source/Core/Core/PowerPC/JitArm64/Jit.h
index e98f950d42..5fd25d51d2 100644
--- a/Source/Core/Core/PowerPC/JitArm64/Jit.h
+++ b/Source/Core/Core/PowerPC/JitArm64/Jit.h
@@ -114,7 +114,6 @@ public:
void rlwimix(UGeckoInstruction inst);
void subfex(UGeckoInstruction inst);
void subfzex(UGeckoInstruction inst);
- void subfcx(UGeckoInstruction inst);
void subfic(UGeckoInstruction inst);
void addex(UGeckoInstruction inst);
void divwux(UGeckoInstruction inst);
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index cd8b00d49f..e82db40756 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -18,15 +18,18 @@
using namespace Arm64Gen;
using namespace JitCommon;
-#define CARRY_IF_NEEDED(inst_without_carry, inst_with_carry, ...) \
+#define CARRY_IF_NEEDED_COND(carry, inst_without_carry, inst_with_carry, ...) \
do \
{ \
- if (js.op->wantsCA) \
+ if ((carry) && js.op->wantsCA) \
inst_with_carry(__VA_ARGS__); \
else \
inst_without_carry(__VA_ARGS__); \
} while (0)
+#define CARRY_IF_NEEDED(inst_without_carry, inst_with_carry, ...) \
+ CARRY_IF_NEEDED_COND(true, inst_without_carry, inst_with_carry, __VA_ARGS__)
+
void JitArm64::ComputeRC0(ARM64Reg reg)
{
gpr.BindCRToRegister(0, false);
@@ -1114,20 +1117,6 @@ void JitArm64::addzex(UGeckoInstruction inst)
ComputeRC0(gpr.R(d));
}
-void JitArm64::subfx(UGeckoInstruction inst)
-{
- INSTRUCTION_START
- JITDISABLE(bJITIntegerOff);
- FALLBACK_IF(inst.OE);
-
- int a = inst.RA, b = inst.RB, d = inst.RD;
-
- 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)
{
INSTRUCTION_START
@@ -1259,13 +1248,14 @@ void JitArm64::subfex(UGeckoInstruction inst)
ComputeRC0(gpr.R(d));
}
-void JitArm64::subfcx(UGeckoInstruction inst)
+void JitArm64::subfx(UGeckoInstruction inst)
{
INSTRUCTION_START
JITDISABLE(bJITIntegerOff);
FALLBACK_IF(inst.OE);
- int a = inst.RA, b = inst.RB, d = inst.RD;
+ const int a = inst.RA, b = inst.RB, d = inst.RD;
+ const bool carry = !(inst.SUBOP10 & (1 << 5));
if (gpr.IsImm(a))
{
@@ -1278,7 +1268,8 @@ void JitArm64::subfcx(UGeckoInstruction inst)
gpr.BindToRegister(d, false);
MOV(gpr.R(d), gpr.R(b));
}
- ComputeCarry(true);
+ if (carry)
+ ComputeCarry(true);
if (inst.Rc)
ComputeRC0(gpr.R(d));
return;
@@ -1289,8 +1280,10 @@ void JitArm64::subfcx(UGeckoInstruction inst)
if (low_12 || high_12)
{
gpr.BindToRegister(d, d == b);
- CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), high_12 ? imm >> 12 : imm, high_12);
- ComputeCarry();
+ CARRY_IF_NEEDED_COND(carry, SUB, SUBS, gpr.R(d), gpr.R(b), high_12 ? imm >> 12 : imm,
+ high_12);
+ if (carry)
+ ComputeCarry();
if (inst.Rc)
ComputeRC0(gpr.R(d));
return;
@@ -1300,8 +1293,9 @@ void JitArm64::subfcx(UGeckoInstruction inst)
if (gpr.IsImm(b, 0))
{
gpr.BindToRegister(d, d == a);
- CARRY_IF_NEEDED(NEG, NEGS, gpr.R(d), gpr.R(a));
- ComputeCarry();
+ CARRY_IF_NEEDED_COND(carry, NEG, NEGS, gpr.R(d), gpr.R(a));
+ if (carry)
+ ComputeCarry();
if (inst.Rc)
ComputeRC0(gpr.R(d));
return;
@@ -1310,10 +1304,9 @@ void JitArm64::subfcx(UGeckoInstruction inst)
gpr.BindToRegister(d, d == a || d == b);
// d = b - a
- CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
-
- ComputeCarry();
-
+ CARRY_IF_NEEDED_COND(carry, SUB, SUBS, gpr.R(d), gpr.R(b), gpr.R(a));
+ if (carry)
+ ComputeCarry();
if (inst.Rc)
ComputeRC0(gpr.R(d));
}
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
index eb97db9b91..17b2030e25 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Tables.cpp
@@ -172,8 +172,8 @@ constexpr std::array<JitArm64OpTemplate, 107> s_table31{{
{616, &JitArm64::negx}, // negox
{40, &JitArm64::subfx}, // subfx
{552, &JitArm64::subfx}, // subfox
- {8, &JitArm64::subfcx}, // subfcx
- {520, &JitArm64::subfcx}, // subfcox
+ {8, &JitArm64::subfx}, // subfcx
+ {520, &JitArm64::subfx}, // subfcox
{136, &JitArm64::subfex}, // subfex
{648, &JitArm64::subfex}, // subfeox
{232, &JitArm64::subfex}, // subfmex