From e3d889feb17782804061233f01bbf7ae691b4fac Mon Sep 17 00:00:00 2001 From: Sintendo <3380580+Sintendo@users.noreply.github.com> Date: Sun, 3 Aug 2025 09:41:44 +0200 Subject: [PATCH 1/4] JitArm64_Integer: subfcx - Optimize a == 0 This case can be handled as a move. It also generates a constant carry flag. Before: 0x52800013 mov w19, #0x0 ; =0 0x6b1302b3 subs w19, w21, w19 After: 0x2a1503f3 mov w19, w21 --- .../Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index df2b48631da..31b8f96f71e 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1432,6 +1432,17 @@ void JitArm64::subfcx(UGeckoInstruction inst) if (inst.Rc) ComputeRC0(gpr.GetImm(d)); } + else if (gpr.IsImm(a, 0)) + { + if (d != b) + { + gpr.BindToRegister(d, false); + MOV(gpr.R(d), gpr.R(b)); + } + ComputeCarry(true); + if (inst.Rc) + ComputeRC0(gpr.R(d)); + } else { gpr.BindToRegister(d, d == a || d == b); From fc9f2d9cea4fc0e92e16edbe075780d68c591cc7 Mon Sep 17 00:00:00 2001 From: Sintendo <3380580+Sintendo@users.noreply.github.com> Date: Wed, 6 Aug 2025 00:30:31 +0200 Subject: [PATCH 2/4] JitArm64_Integer: subfcx - Optimize b == 0 Equivalent to a negation, no need to materialize the zero. Before: 0x52800015 mov w21, #0x0 ; =0 0x6b1802b6 subs w22, w21, w24 After: 0x6b1803f6 negs w22, w24 --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 31b8f96f71e..25a4ada4780 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1443,6 +1443,14 @@ void JitArm64::subfcx(UGeckoInstruction inst) if (inst.Rc) ComputeRC0(gpr.R(d)); } + else if (gpr.IsImm(b, 0)) + { + gpr.BindToRegister(d, d == a); + CARRY_IF_NEEDED(NEG, NEGS, gpr.R(d), gpr.R(a)); + ComputeCarry(); + if (inst.Rc) + ComputeRC0(gpr.R(d)); + } else { gpr.BindToRegister(d, d == a || d == b); From 45a3e35b0684d8f42e51f2c074e208658125b49e Mon Sep 17 00:00:00 2001 From: Sintendo <3380580+Sintendo@users.noreply.github.com> Date: Wed, 6 Aug 2025 01:22:01 +0200 Subject: [PATCH 3/4] JitArm64_Integer: subfcx - Subtract 12-bit constant Eliminate an instruction by encoding the constant in the subtraction. Before: 0x5280037a mov w26, #0x1b ; =27 0x6b1a02bb subs w27, w21, w26 0x93407f78 sxtw x24, w27 After: 0x71006ebb subs w27, w21, #0x1b 0x93407f7a sxtw x26, w27 --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 25a4ada4780..7cf2305d5a6 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1443,6 +1443,14 @@ void JitArm64::subfcx(UGeckoInstruction inst) if (inst.Rc) ComputeRC0(gpr.R(d)); } + else if (gpr.IsImm(a) && ((gpr.GetImm(a) & 0xFFF) == gpr.GetImm(a))) + { + gpr.BindToRegister(d, d == b); + CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.GetImm(a)); + ComputeCarry(); + if (inst.Rc) + ComputeRC0(gpr.R(d)); + } else if (gpr.IsImm(b, 0)) { gpr.BindToRegister(d, d == a); From 6a92a90bce95641bf676a8214d80d2224b65ba83 Mon Sep 17 00:00:00 2001 From: Sintendo <3380580+Sintendo@users.noreply.github.com> Date: Wed, 6 Aug 2025 01:27:35 +0200 Subject: [PATCH 4/4] JitArm64_Integer: subfcx - Subtract shifted 12-bit constant Eliminate an instruction by encoding the constant in the subtraction, part two. Before: 0x52900019 mov w25, #0x8000 ; =32768 0x6b190359 subs w25, w26, w25 After: 0x71402359 subs w25, w26, #0x8, lsl #12 ; =0x8000 --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 7cf2305d5a6..3cf722409a8 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -1451,6 +1451,14 @@ void JitArm64::subfcx(UGeckoInstruction inst) if (inst.Rc) ComputeRC0(gpr.R(d)); } + else if (gpr.IsImm(a) && ((gpr.GetImm(a) & 0xFFF000) == gpr.GetImm(a))) + { + gpr.BindToRegister(d, d == b); + CARRY_IF_NEEDED(SUB, SUBS, gpr.R(d), gpr.R(b), gpr.GetImm(a) >> 12, true); + ComputeCarry(); + if (inst.Rc) + ComputeRC0(gpr.R(d)); + } else if (gpr.IsImm(b, 0)) { gpr.BindToRegister(d, d == a);