diff options
| author | Sintendo <3380580+Sintendo@users.noreply.github.com> | 2024-06-26 00:07:20 +0200 |
|---|---|---|
| committer | Sintendo <3380580+Sintendo@users.noreply.github.com> | 2024-06-29 23:08:02 +0200 |
| commit | d877cfa4e2c3baf3cb8b8449d1608e1c2f05208c (patch) | |
| tree | cfcd36eae47a4ec421cde11fddcec577f03b5ab9 /Source/Core | |
| parent | f49659fbfc931fde6478d3c5d0fc445bfb62d3bf (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.cpp | 14 |
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) |
