summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosJuice <josjuice@gmail.com>2025-08-20 22:40:14 +0200
committerGitHub <noreply@github.com>2025-08-20 22:40:14 +0200
commit09e68e707efd806abf2deb655c42a2e338ae6185 (patch)
tree4fd2a87bdb4f8f1e919d972b782add2ddf5d65ef
parent5aaf522a6f00b46942be9a32033249f26d11a275 (diff)
parente9d28649dccda8cad209dd1eda4e1a93a0188526 (diff)
Merge pull request #13836 from Sintendo/jitarm64-subfe
JitArm64_Integer: Minor subfe optimizations
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp37
1 files changed, 25 insertions, 12 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index df2b48631d..86027d425a 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -6,18 +6,14 @@
#include <bit>
#include "Common/Arm64Emitter.h"
-#include "Common/Assert.h"
-#include "Common/BitUtils.h"
+#include "Common/ArmCommon.h"
#include "Common/CommonTypes.h"
#include "Common/MathUtil.h"
-#include "Core/Core.h"
-#include "Core/CoreTiming.h"
#include "Core/PowerPC/Interpreter/Interpreter.h"
#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h"
#include "Core/PowerPC/JitCommon/DivUtils.h"
#include "Core/PowerPC/PPCTables.h"
-#include "Core/PowerPC/PowerPC.h"
using namespace Arm64Gen;
using namespace JitCommon;
@@ -1306,13 +1302,10 @@ void JitArm64::subfex(UGeckoInstruction inst)
JITDISABLE(bJITIntegerOff);
FALLBACK_IF(inst.OE);
- bool mex = inst.SUBOP10 & 32;
- int a = inst.RA, b = inst.RB, d = inst.RD;
+ const bool mex = inst.SUBOP10 & 32;
+ const int a = inst.RA, b = inst.RB, d = inst.RD;
- if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
- {
- const u32 i = gpr.GetImm(a);
- const u32 j = mex ? -1 : gpr.GetImm(b);
+ const auto handle_imm = [&](const u32 i, const u32 j) {
const u32 imm = ~i + j;
const bool is_zero = imm == 0;
const bool is_all_ones = imm == 0xFFFFFFFF;
@@ -1339,7 +1332,12 @@ void JitArm64::subfex(UGeckoInstruction inst)
{
gpr.BindToRegister(d, false);
ARM64Reg RD = gpr.R(d);
- if (is_all_ones)
+ if (is_zero)
+ {
+ // RD = 0 + carry
+ CSET(RD, CC_CS);
+ }
+ else if (is_all_ones)
{
// RD = -1 + carry = carry ? 0 : -1
// CSETM sets the destination to -1 if the condition is true, 0
@@ -1380,6 +1378,21 @@ void JitArm64::subfex(UGeckoInstruction inst)
{
ComputeCarry(false);
}
+ };
+
+ if (!mex && a == b)
+ {
+ // Special case: subfe A, B, B is a common compiler idiom to copy the carry
+ // flag to a register.
+ // We handle this as-if we're dealing with two identical immediate values.
+ // The exact values used here don't matter. We use zeroes.
+ handle_imm(0, 0);
+ }
+ else if (gpr.IsImm(a) && (mex || gpr.IsImm(b)))
+ {
+ const u32 i = gpr.GetImm(a);
+ const u32 j = mex ? -1 : gpr.GetImm(b);
+ handle_imm(i, j);
}
else
{