summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorBram Speeckaert <bram.speeckaert@gmail.com>2022-11-02 21:33:47 +0100
committerBram Speeckaert <bram.speeckaert@gmail.com>2022-11-02 21:53:19 +0100
commit7073a135c659d59f1874b69250d54f34cfb33da2 (patch)
tree2f596a691f29e6f6c6ba4a6929c55cf78919ba45 /Source
parent1c87f040a3b0771f9b5d231eb5dee620d15b7ed6 (diff)
JitArm64: MultiplyImmediate - Handle -(2^n)
ARM64's flexible shifting of input registers also allows us to calculate a negative power of two in one instruction; shift the input of a NEG instruction. Before: 0x128001f7 mov w23, #-0x10 0x1b1a7efa mul w26, w23, w26 0x93407f58 sxtw x24, w26 After: 0x4b1a13fa neg w26, w26, lsl #4 0x93407f58 sxtw x24, w26
Diffstat (limited to 'Source')
-rw-r--r--Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp10
1 files changed, 10 insertions, 0 deletions
diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
index 6cd902d0c9..e3dac61ed0 100644
--- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
+++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp
@@ -917,6 +917,16 @@ bool JitArm64::MultiplyImmediate(u32 imm, int a, int d, bool rc)
if (rc)
ComputeRC0(gpr.R(d));
}
+ else if (MathUtil::IsPow2(~imm + 1))
+ {
+ // Multiplication by a negative power of two (-(2^n)).
+ const int shift = IntLog2(~imm + 1);
+
+ gpr.BindToRegister(d, d == a);
+ NEG(gpr.R(d), gpr.R(a), ArithOption(gpr.R(a), ShiftType::LSL, shift));
+ if (rc)
+ ComputeRC0(gpr.R(d));
+ }
else
{
// Immediate did not match any known special cases.