From 2ea95f5835956adccaea1e75ae5c553a30c4eee9 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Mon, 13 Nov 2023 18:28:40 +0100 Subject: [PATCH 1/2] JitArm64: Use BitSet8 for Arm64GPRCache::FlushCRRegisters There are only 8 CR registers, after all. --- Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp | 6 +++--- Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index ec9562f46c..fefa08753b 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -280,7 +280,7 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state, ARM64Reg } } -void Arm64GPRCache::FlushCRRegisters(BitSet32 regs, bool maintain_state, ARM64Reg tmp_reg) +void Arm64GPRCache::FlushCRRegisters(BitSet8 regs, bool maintain_state, ARM64Reg tmp_reg) { for (size_t i = 0; i < GUEST_CR_COUNT; ++i) { @@ -296,8 +296,8 @@ void Arm64GPRCache::FlushCRRegisters(BitSet32 regs, bool maintain_state, ARM64Re void Arm64GPRCache::Flush(FlushMode mode, ARM64Reg tmp_reg) { - FlushRegisters(BitSet32(~0U), mode == FlushMode::MaintainState, tmp_reg); - FlushCRRegisters(BitSet32(~0U), mode == FlushMode::MaintainState, tmp_reg); + FlushRegisters(BitSet32(0xFFFFFFFF), mode == FlushMode::MaintainState, tmp_reg); + FlushCRRegisters(BitSet8(0xFF), mode == FlushMode::MaintainState, tmp_reg); } ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index 01339184ea..fbe1f30134 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -330,7 +330,7 @@ public: FlushRegisters(regs, false, tmp_reg); } - void StoreCRRegisters(BitSet32 regs, Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG) + void StoreCRRegisters(BitSet8 regs, Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG) { FlushCRRegisters(regs, false, tmp_reg); } @@ -365,7 +365,7 @@ private: void BindToRegister(const GuestRegInfo& guest_reg, bool will_read, bool will_write = true); void FlushRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg); - void FlushCRRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg); + void FlushCRRegisters(BitSet8 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg); }; class Arm64FPRCache : public Arm64RegCache From 6a9f565ac4ddc65b2fdbf2293282ddd432ba89ae Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sun, 5 Nov 2023 12:19:41 +0100 Subject: [PATCH 2/2] JitArm64: Optimize Arm64GPRCache::FlushRegisters/FlushCRRegisters This way, the number of loop iterations is equal to the number of set bits in the bitset rather than the number of bits in the bitset, which is a good improvement because usually very few bits are set. --- .../PowerPC/JitArm64/JitArm64_RegCache.cpp | 62 +++++++++---------- 1 file changed, 28 insertions(+), 34 deletions(-) diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index fefa08753b..d4e933aaf3 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -241,56 +241,50 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state, ARM64Reg tm void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state, ARM64Reg tmp_reg) { - for (size_t i = 0; i < GUEST_GPR_COUNT; ++i) + for (int i : regs) { - if (regs[i]) - { - ASSERT_MSG(DYNA_REC, m_guest_registers[GUEST_GPR_OFFSET + i].GetType() != RegType::Discarded, - "Attempted to flush discarded register"); + ASSERT_MSG(DYNA_REC, m_guest_registers[GUEST_GPR_OFFSET + i].GetType() != RegType::Discarded, + "Attempted to flush discarded register"); - if (i + 1 < GUEST_GPR_COUNT && regs[i + 1]) + if (i + 1 < GUEST_GPR_COUNT && regs[i + 1]) + { + // 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) { - // 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 size_t ppc_offset = GetGuestByIndex(i).ppc_offset; + if (ppc_offset <= 252) { - const size_t ppc_offset = GetGuestByIndex(i).ppc_offset; - if (ppc_offset <= 252) + ARM64Reg RX1 = R(GetGuestByIndex(i)); + ARM64Reg RX2 = R(GetGuestByIndex(i + 1)); + m_emit->STP(IndexType::Signed, RX1, RX2, PPC_REG, u32(ppc_offset)); + if (!maintain_state) { - ARM64Reg RX1 = R(GetGuestByIndex(i)); - ARM64Reg RX2 = R(GetGuestByIndex(i + 1)); - m_emit->STP(IndexType::Signed, RX1, RX2, PPC_REG, u32(ppc_offset)); - if (!maintain_state) - { - UnlockRegister(EncodeRegTo32(RX1)); - UnlockRegister(EncodeRegTo32(RX2)); - reg1.Flush(); - reg2.Flush(); - } - ++i; - continue; + UnlockRegister(EncodeRegTo32(RX1)); + UnlockRegister(EncodeRegTo32(RX2)); + reg1.Flush(); + reg2.Flush(); } + ++i; + continue; } } - - FlushRegister(GUEST_GPR_OFFSET + i, maintain_state, tmp_reg); } + + FlushRegister(GUEST_GPR_OFFSET + i, maintain_state, tmp_reg); } } void Arm64GPRCache::FlushCRRegisters(BitSet8 regs, bool maintain_state, ARM64Reg tmp_reg) { - for (size_t i = 0; i < GUEST_CR_COUNT; ++i) + for (int i : regs) { - if (regs[i]) - { - ASSERT_MSG(DYNA_REC, m_guest_registers[GUEST_CR_OFFSET + i].GetType() != RegType::Discarded, - "Attempted to flush discarded register"); + ASSERT_MSG(DYNA_REC, m_guest_registers[GUEST_CR_OFFSET + i].GetType() != RegType::Discarded, + "Attempted to flush discarded register"); - FlushRegister(GUEST_CR_OFFSET + i, maintain_state, tmp_reg); - } + FlushRegister(GUEST_CR_OFFSET + i, maintain_state, tmp_reg); } }