summaryrefslogtreecommitdiff
path: root/Source/Core
diff options
context:
space:
mode:
authorSintendo <3380580+Sintendo@users.noreply.github.com>2024-06-26 00:07:20 +0200
committerSintendo <3380580+Sintendo@users.noreply.github.com>2024-06-29 23:08:02 +0200
commitd877cfa4e2c3baf3cb8b8449d1608e1c2f05208c (patch)
treecfcd36eae47a4ec421cde11fddcec577f03b5ab9 /Source/Core
parentf49659fbfc931fde6478d3c5d0fc445bfb62d3bf (diff)
JitArm64_Integer: Optimize subfic for zero
When the immediate value is zero, we can do a negation. On ARM64 the NEG /NEGS instructions are just an alias for SUB/SUBS with a hardcoded WZR. Before: ``` ldr w22, [x29, #0x28] mov w21, #0x0 ; =0 subs w22, w21, w22 ``` After: ``` ldr w22, [x29, #0x28] negs w22, w22 ```
Diffstat (limited to 'Source/Core')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp14
1 files changed, 10 insertions, 4 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index 7e5817ac0c..f3d263379c 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -1392,13 +1392,19 @@ void JitArm64::subfic(UGeckoInstruction inst)
}
else
{
- const bool allocate_reg = d == a;
- gpr.BindToRegister(d, allocate_reg);
+ const bool will_read = d == a;
+ const bool is_zero = imm == 0;
+ const bool allocate_reg = will_read && !is_zero;
+ gpr.BindToRegister(d, will_read);
// d = imm - a
ARM64Reg RD = gpr.R(d);
- ARM64Reg WA = allocate_reg ? gpr.GetReg() : RD;
- MOVI2R(WA, imm);
+ ARM64Reg WA = ARM64Reg::WZR;
+ if (!is_zero)
+ {
+ WA = will_read ? gpr.GetReg() : RD;
+ MOVI2R(WA, imm);
+ }
CARRY_IF_NEEDED(SUB, SUBS, RD, WA, gpr.R(a));
if (allocate_reg)