diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp index d55cd1bc93..5af4855a91 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.cpp @@ -2,12 +2,18 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include "Core/PowerPC/JitArm64/Jit.h" +#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h" + +#include +#include +#include +#include + #include "Common/Assert.h" #include "Common/BitSet.h" #include "Common/CommonTypes.h" #include "Common/Logging/Log.h" -#include "Core/PowerPC/JitArm64/JitArm64_RegCache.h" +#include "Core/PowerPC/JitArm64/Jit.h" using namespace Arm64Gen; @@ -66,18 +72,22 @@ void Arm64RegCache::UnlockRegister(ARM64Reg host_reg) void Arm64RegCache::FlushMostStaleRegister() { - u32 most_stale_preg = 0; + size_t most_stale_preg = 0; u32 most_stale_amount = 0; - for (u32 i = 0; i < 32; ++i) + + for (size_t i = 0; i < m_guest_registers.size(); ++i) { - u32 last_used = m_guest_registers[i].GetLastUsed(); - if (last_used > most_stale_amount && (m_guest_registers[i].GetType() != REG_NOTLOADED && - m_guest_registers[i].GetType() != REG_IMM)) + const auto& reg = m_guest_registers[i]; + const u32 last_used = reg.GetLastUsed(); + + if (last_used > most_stale_amount && + (reg.GetType() != REG_NOTLOADED && reg.GetType() != REG_IMM)) { most_stale_preg = i; most_stale_amount = last_used; } } + FlushRegister(most_stale_preg, false); } @@ -88,13 +98,14 @@ void Arm64GPRCache::Start(PPCAnalyst::BlockRegStats& stats) bool Arm64GPRCache::IsCalleeSaved(ARM64Reg reg) { - static std::vector callee_regs = { + static constexpr std::array callee_regs{{ X28, X27, X26, X25, X24, X23, X22, X21, X20, X19, INVALID_REG, - }; + }}; + return std::find(callee_regs.begin(), callee_regs.end(), EncodeRegTo64(reg)) != callee_regs.end(); } -void Arm64GPRCache::FlushRegister(u32 preg, bool maintain_state) +void Arm64GPRCache::FlushRegister(size_t preg, bool maintain_state) { OpArg& reg = m_guest_registers[preg]; if (reg.GetType() == REG_REG) @@ -132,7 +143,7 @@ void Arm64GPRCache::FlushRegister(u32 preg, bool maintain_state) void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state) { - for (int i = 0; i < 32; ++i) + for (size_t i = 0; i < m_guest_registers.size(); ++i) { if (regs[i]) { @@ -168,7 +179,7 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state) void Arm64GPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op) { BitSet32 to_flush; - for (int i = 0; i < 32; ++i) + for (size_t i = 0; i < m_guest_registers.size(); ++i) { bool flush = true; if (m_guest_registers[i].GetType() == REG_REG) @@ -183,7 +194,7 @@ void Arm64GPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op) FlushRegisters(to_flush, mode == FLUSH_MAINTAIN_STATE); } -ARM64Reg Arm64GPRCache::R(u32 preg) +ARM64Reg Arm64GPRCache::R(size_t preg) { OpArg& reg = m_guest_registers[preg]; IncrementAllUsed(); @@ -223,7 +234,7 @@ ARM64Reg Arm64GPRCache::R(u32 preg) return INVALID_REG; } -void Arm64GPRCache::SetImmediate(u32 preg, u32 imm) +void Arm64GPRCache::SetImmediate(size_t preg, u32 imm) { OpArg& reg = m_guest_registers[preg]; if (reg.GetType() == REG_REG) @@ -231,7 +242,7 @@ void Arm64GPRCache::SetImmediate(u32 preg, u32 imm) reg.LoadToImm(imm); } -void Arm64GPRCache::BindToRegister(u32 preg, bool do_load) +void Arm64GPRCache::BindToRegister(size_t preg, bool do_load) { OpArg& reg = m_guest_registers[preg]; @@ -250,13 +261,13 @@ void Arm64GPRCache::BindToRegister(u32 preg, bool do_load) void Arm64GPRCache::GetAllocationOrder() { // Callee saved registers first in hopes that we will keep everything stored there first - const std::vector allocation_order = { + static constexpr std::array allocation_order{{ // Callee saved W27, W26, W25, W24, W23, W22, W21, W20, W19, // Caller saved W18, W17, W16, W15, W14, W13, W12, W11, W10, W9, W8, W7, W6, W5, W4, W3, W2, W1, W0, W30, - }; + }}; for (ARM64Reg reg : allocation_order) m_host_registers.push_back(HostReg(reg)); @@ -273,9 +284,9 @@ BitSet32 Arm64GPRCache::GetCallerSavedUsed() void Arm64GPRCache::FlushByHost(ARM64Reg host_reg) { - for (int i = 0; i < 32; ++i) + for (size_t i = 0; i < m_guest_registers.size(); ++i) { - OpArg& reg = m_guest_registers[i]; + const OpArg& reg = m_guest_registers[i]; if (reg.GetType() == REG_REG && reg.GetReg() == host_reg) { FlushRegister(i, false); @@ -287,10 +298,11 @@ void Arm64GPRCache::FlushByHost(ARM64Reg host_reg) // FPR Cache void Arm64FPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op) { - for (int i = 0; i < 32; ++i) + for (size_t i = 0; i < m_guest_registers.size(); ++i) { - if (m_guest_registers[i].GetType() != REG_NOTLOADED && - m_guest_registers[i].GetType() != REG_IMM) + const RegType reg_type = m_guest_registers[i].GetType(); + + if (reg_type != REG_NOTLOADED && reg_type != REG_IMM) { // XXX: Determine if we can keep a register in the lower 64bits // Which will allow it to be callee saved. @@ -299,7 +311,7 @@ void Arm64FPRCache::Flush(FlushMode mode, PPCAnalyst::CodeOp* op) } } -ARM64Reg Arm64FPRCache::R(u32 preg, RegType type) +ARM64Reg Arm64FPRCache::R(size_t preg, RegType type) { OpArg& reg = m_guest_registers[preg]; IncrementAllUsed(); @@ -408,7 +420,7 @@ ARM64Reg Arm64FPRCache::R(u32 preg, RegType type) return INVALID_REG; } -ARM64Reg Arm64FPRCache::RW(u32 preg, RegType type) +ARM64Reg Arm64FPRCache::RW(size_t preg, RegType type) { OpArg& reg = m_guest_registers[preg]; @@ -470,13 +482,14 @@ ARM64Reg Arm64FPRCache::RW(u32 preg, RegType type) void Arm64FPRCache::GetAllocationOrder() { - const std::vector allocation_order = {// Callee saved - Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, + static constexpr std::array allocation_order{{ + // Callee saved + Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, - // Caller saved - Q16, Q17, Q18, Q19, Q20, Q21, Q22, Q23, Q24, Q25, - Q26, Q27, Q28, Q29, Q30, Q31, Q7, Q6, Q5, Q4, Q3, - Q2, Q1, Q0}; + // Caller saved + Q16, Q17, Q18, Q19, Q20, Q21, Q22, Q23, Q24, Q25, Q26, Q27, Q28, Q29, Q30, Q31, Q7, Q6, Q5, + Q4, Q3, Q2, Q1, Q0, + }}; for (ARM64Reg reg : allocation_order) m_host_registers.push_back(HostReg(reg)); @@ -484,10 +497,12 @@ void Arm64FPRCache::GetAllocationOrder() void Arm64FPRCache::FlushByHost(ARM64Reg host_reg) { - for (int i = 0; i < 32; ++i) + for (size_t i = 0; i < m_guest_registers.size(); ++i) { - OpArg& reg = m_guest_registers[i]; - if ((reg.GetType() != REG_NOTLOADED && reg.GetType() != REG_IMM) && reg.GetReg() == host_reg) + const OpArg& reg = m_guest_registers[i]; + const RegType reg_type = reg.GetType(); + + if ((reg_type != REG_NOTLOADED && reg_type != REG_IMM) && reg.GetReg() == host_reg) { FlushRegister(i, false); return; @@ -497,13 +512,14 @@ void Arm64FPRCache::FlushByHost(ARM64Reg host_reg) bool Arm64FPRCache::IsCalleeSaved(ARM64Reg reg) { - static std::vector callee_regs = { + static constexpr std::array callee_regs{{ Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15, INVALID_REG, - }; + }}; + return std::find(callee_regs.begin(), callee_regs.end(), reg) != callee_regs.end(); } -void Arm64FPRCache::FlushRegister(u32 preg, bool maintain_state) +void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state) { OpArg& reg = m_guest_registers[preg]; ARM64Reg host_reg = reg.GetReg(); @@ -580,14 +596,14 @@ BitSet32 Arm64FPRCache::GetCallerSavedUsed() return registers; } -bool Arm64FPRCache::IsSingle(u32 preg, bool lower_only) +bool Arm64FPRCache::IsSingle(size_t preg, bool lower_only) { RegType type = m_guest_registers[preg].GetType(); return type == REG_REG_SINGLE || type == REG_DUP_SINGLE || (lower_only && type == REG_LOWER_PAIR_SINGLE); } -void Arm64FPRCache::FixSinglePrecision(u32 preg) +void Arm64FPRCache::FixSinglePrecision(size_t preg) { OpArg& reg = m_guest_registers[preg]; ARM64Reg host_reg = reg.GetReg(); diff --git a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h index 3a5cfb5105..f65eec4ad4 100644 --- a/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h +++ b/Source/Core/Core/PowerPC/JitArm64/JitArm64_RegCache.h @@ -4,10 +4,13 @@ #pragma once +#include +#include #include #include #include "Common/Arm64Emitter.h" +#include "Common/CommonTypes.h" #include "Core/PowerPC/Gekko.h" #include "Core/PowerPC/PPCAnalyst.h" #include "Core/PowerPC/PowerPC.h" @@ -171,7 +174,7 @@ protected: // Flushes a guest register by host provided virtual void FlushByHost(ARM64Reg host_reg) = 0; - virtual void FlushRegister(u32 preg, bool maintain_state) = 0; + virtual void FlushRegister(size_t preg, bool maintain_state) = 0; virtual void FlushRegisters(BitSet32 regs, bool maintain_state) = 0; @@ -196,7 +199,7 @@ protected: // Our guest GPRs // PowerPC has 32 GPRs // PowerPC also has 32 paired FPRs - OpArg m_guest_registers[32]; + std::array m_guest_registers; // Register stats for the current block PPCAnalyst::BlockRegStats* m_reg_stats; @@ -213,16 +216,16 @@ public: // Returns a guest register inside of a host register // Will dump an immediate to the host register as well - ARM64Reg R(u32 preg); + ARM64Reg R(size_t preg); // Set a register to an immediate - void SetImmediate(u32 preg, u32 imm); + void SetImmediate(size_t preg, u32 imm); // Returns if a register is set as an immediate - bool IsImm(u32 reg) const { return m_guest_registers[reg].GetType() == REG_IMM; } + bool IsImm(size_t reg) const { return m_guest_registers[reg].GetType() == REG_IMM; } // Gets the immediate that a register is set to - u32 GetImm(u32 reg) const { return m_guest_registers[reg].GetImm(); } - void BindToRegister(u32 preg, bool do_load); + u32 GetImm(size_t reg) const { return m_guest_registers[reg].GetImm(); } + void BindToRegister(size_t preg, bool do_load); BitSet32 GetCallerSavedUsed() override; @@ -233,7 +236,7 @@ protected: // Flushes a guest register by host provided void FlushByHost(ARM64Reg host_reg) override; - void FlushRegister(u32 preg, bool maintain_state) override; + void FlushRegister(size_t preg, bool maintain_state) override; void FlushRegisters(BitSet32 regs, bool maintain_state) override; @@ -250,15 +253,15 @@ public: // Returns a guest register inside of a host register // Will dump an immediate to the host register as well - ARM64Reg R(u32 preg, RegType type = REG_LOWER_PAIR); + ARM64Reg R(size_t preg, RegType type = REG_LOWER_PAIR); - ARM64Reg RW(u32 preg, RegType type = REG_LOWER_PAIR); + ARM64Reg RW(size_t preg, RegType type = REG_LOWER_PAIR); BitSet32 GetCallerSavedUsed() override; - bool IsSingle(u32 preg, bool lower_only = false); + bool IsSingle(size_t preg, bool lower_only = false); - void FixSinglePrecision(u32 preg); + void FixSinglePrecision(size_t preg); protected: // Get the order of the host registers @@ -267,7 +270,7 @@ protected: // Flushes a guest register by host provided void FlushByHost(ARM64Reg host_reg) override; - void FlushRegister(u32 preg, bool maintain_state) override; + void FlushRegister(size_t preg, bool maintain_state) override; void FlushRegisters(BitSet32 regs, bool maintain_state) override;