From 662ae570a0b8bbdfa73caabc37e1f2148d73f0b1 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Fri, 2 Jul 2021 18:34:56 +0200 Subject: [PATCH] JitArm64: Make EmitBackpatchRoutine support saving W0 Being able to preserve the address register is useful for the next commit, and W0 is the address register used for loads. Saving the address register used for stores, W1, was already supported. --- .../PowerPC/JitArm64/JitArm64_BackPatch.cpp | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp index 4923e713cb..13cc4722a7 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_BackPatch.cpp @@ -6,6 +6,7 @@ #include #include +#include "Common/Align.h" #include "Common/BitSet.h" #include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" @@ -144,15 +145,21 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR const ARM64Reg temp_reg = flags & BackPatchInfo::FLAG_LOAD ? ARM64Reg::W30 : ARM64Reg::W0; const int temp_reg_index = DecodeReg(temp_reg); - if (memcheck && (flags & BackPatchInfo::FLAG_LOAD)) - { - ABI_PushRegisters(gprs_to_push & BitSet32{temp_reg_index}); - ABI_PushRegisters(gprs_to_push & ~BitSet32{temp_reg_index}); - } - else - { - ABI_PushRegisters(gprs_to_push); - } + BitSet32 gprs_to_push_early = {}; + if (memcheck) + gprs_to_push_early[temp_reg_index] = true; + if (flags & BackPatchInfo::FLAG_LOAD) + gprs_to_push_early[0] = true; + + // If we're already pushing one register in the first PushRegisters call, we can push a + // second one for free. Let's do so, since it might save one instruction in the second + // PushRegisters call. (Do not do this for caller-saved registers which may be in the register + // cache, or else EmitMemcheck will not be able to flush the register cache correctly!) + if (gprs_to_push & gprs_to_push_early) + gprs_to_push_early[30] = true; + + ABI_PushRegisters(gprs_to_push & gprs_to_push_early); + ABI_PushRegisters(gprs_to_push & ~gprs_to_push_early); m_float_emit.ABI_PushRegisters(fprs_to_push, ARM64Reg::X30); if (flags & BackPatchInfo::FLAG_STORE) @@ -213,21 +220,17 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR } m_float_emit.ABI_PopRegisters(fprs_to_push, ARM64Reg::X30); - if (memcheck && (flags & BackPatchInfo::FLAG_LOAD)) - ABI_PopRegisters(gprs_to_push & ~BitSet32{temp_reg_index}); - else - ABI_PopRegisters(gprs_to_push); + ABI_PopRegisters(gprs_to_push & ~gprs_to_push_early); if (memcheck) { - const u64 early_push_size = flags & BackPatchInfo::FLAG_LOAD ? 16 : 0; + const u64 early_push_size = Common::AlignUp(gprs_to_push_early.Count(), 2) * 8; WriteConditionalExceptionExit(EXCEPTION_DSI, temp_reg, early_push_size); } if (flags & BackPatchInfo::FLAG_LOAD) { ARM64Reg src_reg = access_size == 64 ? ARM64Reg::X0 : ARM64Reg::W0; - ASSERT(!gprs_to_push[DecodeReg(src_reg)]); if (flags & BackPatchInfo::FLAG_PAIR) { @@ -248,10 +251,9 @@ void JitArm64::EmitBackpatchRoutine(u32 flags, bool fastmem, bool do_farcode, AR } ByteswapAfterLoad(this, &m_float_emit, RS, src_reg, flags, false, false); - - if (memcheck) - ABI_PopRegisters(gprs_to_push & BitSet32{temp_reg_index}); } + + ABI_PopRegisters(gprs_to_push & gprs_to_push_early); } if (in_far_code)