From 383cbffdecf07672b4f24296ea07dc1fabd184a6 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 21 Oct 2024 21:44:02 +0200 Subject: [PATCH 1/2] JitArm64: Allow ppcState STP optimization for imm --- .../Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index 19cd2b0f32..881b171c44 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -254,8 +254,12 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, FlushMode mode, ARM64Reg tmp_r // We've got two guest registers in a row to store OpArg& reg1 = m_guest_registers[GUEST_GPR_OFFSET + i]; OpArg& reg2 = m_guest_registers[GUEST_GPR_OFFSET + i + 1]; - if (reg1.IsDirty() && reg2.IsDirty() && reg1.GetType() == RegType::Register && - reg2.GetType() == RegType::Register) + const bool reg1_imm = reg1.GetType() == RegType::Immediate; + const bool reg2_imm = reg2.GetType() == RegType::Immediate; + const bool flush_all = mode == FlushMode::All; + if (reg1.IsDirty() && reg2.IsDirty() && + (reg1.GetType() == RegType::Register || (reg1_imm && flush_all)) && + (reg2.GetType() == RegType::Register || (reg2_imm && flush_all))) { const size_t ppc_offset = GetGuestByIndex(i).ppc_offset; if (ppc_offset <= 252) @@ -263,7 +267,7 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, FlushMode mode, ARM64Reg tmp_r ARM64Reg RX1 = R(GetGuestByIndex(i)); ARM64Reg RX2 = R(GetGuestByIndex(i + 1)); m_emit->STP(IndexType::Signed, RX1, RX2, PPC_REG, u32(ppc_offset)); - if (mode == FlushMode::All) + if (flush_all) { UnlockRegister(EncodeRegTo32(RX1)); UnlockRegister(EncodeRegTo32(RX2)); From 6fb3e9226b82f383c33b5fa79e1b710d05f15550 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 21 Oct 2024 21:48:44 +0200 Subject: [PATCH 2/2] JitArm64: Use WZR for ppcState STP optimization with imm == 0 --- .../Core/PowerPC/JitArm64/JitArm64_RegCache.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index 881b171c44..b93b30153f 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -256,21 +256,25 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, FlushMode mode, ARM64Reg tmp_r OpArg& reg2 = m_guest_registers[GUEST_GPR_OFFSET + i + 1]; const bool reg1_imm = reg1.GetType() == RegType::Immediate; const bool reg2_imm = reg2.GetType() == RegType::Immediate; + const bool reg1_zero = reg1_imm && reg1.GetImm() == 0; + const bool reg2_zero = reg2_imm && reg2.GetImm() == 0; const bool flush_all = mode == FlushMode::All; if (reg1.IsDirty() && reg2.IsDirty() && - (reg1.GetType() == RegType::Register || (reg1_imm && flush_all)) && - (reg2.GetType() == RegType::Register || (reg2_imm && flush_all))) + (reg1.GetType() == RegType::Register || (reg1_imm && (reg1_zero || flush_all))) && + (reg2.GetType() == RegType::Register || (reg2_imm && (reg2_zero || flush_all)))) { const size_t ppc_offset = GetGuestByIndex(i).ppc_offset; if (ppc_offset <= 252) { - ARM64Reg RX1 = R(GetGuestByIndex(i)); - ARM64Reg RX2 = R(GetGuestByIndex(i + 1)); + ARM64Reg RX1 = reg1_zero ? ARM64Reg::WZR : R(GetGuestByIndex(i)); + ARM64Reg RX2 = reg2_zero ? ARM64Reg::WZR : R(GetGuestByIndex(i + 1)); m_emit->STP(IndexType::Signed, RX1, RX2, PPC_REG, u32(ppc_offset)); if (flush_all) { - UnlockRegister(EncodeRegTo32(RX1)); - UnlockRegister(EncodeRegTo32(RX2)); + if (!reg1_zero) + UnlockRegister(EncodeRegTo32(RX1)); + if (!reg2_zero) + UnlockRegister(EncodeRegTo32(RX2)); reg1.Flush(); reg2.Flush(); }