From c349875cdca6ee5abc2f78d1e0c3a09c8716256f Mon Sep 17 00:00:00 2001 From: Bram Speeckaert Date: Tue, 1 Nov 2022 21:06:43 +0100 Subject: [PATCH] JitArm64: MultiplyImmediate - Handle 2^n + 1 By taking advantage of ARM64's ability to shift an input register by any amount, we can calculate multiplication by a number that is one more than a power of two with a single instruction. Before: 0x52800838 mov w24, #0x41 0x1b187f7b mul w27, w27, w24 After: 0x0b1b1b7b add w27, w27, w27, lsl #6 --- Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp index 70dfea5f99..85554829df 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_Integer.cpp @@ -904,6 +904,15 @@ bool JitArm64::MultiplyImmediate(u32 imm, int a, int d, bool rc) if (rc) ComputeRC0(gpr.R(d)); } + else if (MathUtil::IsPow2(imm - 1)) + { + const int shift = IntLog2(imm - 1); + + gpr.BindToRegister(d, d == a); + ADD(gpr.R(d), gpr.R(a), 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.