From 9d73583ea307b54d1b8fae1a5d0ec1bd9de8e43a Mon Sep 17 00:00:00 2001 From: Bram Speeckaert Date: Sun, 25 Sep 2022 10:04:51 +0200 Subject: [PATCH] JitArm64: Skip redundant imm to register writes When a guest register is an immediate, it may be necessary to move this value into a register. This is handled by gpr.R(), which lacks context on how the register will be used. This leads to cases where the immediate is written to a register, only for it to be overwritten. Take for example this code generated by srwx: 0x5280031b mov w27, #0x18 0x53187edb lsr w27, w22, #24 gpr.BindToRegister() does have this context through the do_load parameter, but didn't handle immediates. By adding this logic, we can intelligently skip the write when do_load is false. --- .../Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index 7a077f6ce2..27a07a8d7b 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -362,6 +362,16 @@ void Arm64GPRCache::BindToRegister(const GuestRegInfo& guest_reg, bool do_load, m_emit->LDR(IndexType::Unsigned, host_reg, PPC_REG, u32(guest_reg.ppc_offset)); } } + else if (reg_type == RegType::Immediate) + { + const ARM64Reg host_reg = bitsize != 64 ? GetReg() : EncodeRegTo64(GetReg()); + if (do_load) + { + m_emit->MOVI2R(host_reg, reg.GetImm()); + } + reg.Load(host_reg); + reg.SetDirty(set_dirty); + } else if (set_dirty) { reg.SetDirty(true);