mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-15 05:47:56 -07:00
Merge pull request #5254 from lioncash/arm-rc
JitArm64_RegCache: Use std::array where applicable
This commit is contained in:
commit
722aca0830
@ -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 <algorithm>
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#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<ARM64Reg> callee_regs = {
|
||||
static constexpr std::array<ARM64Reg, 11> 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<ARM64Reg> allocation_order = {
|
||||
static constexpr std::array<ARM64Reg, 29> 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<ARM64Reg> allocation_order = {// Callee saved
|
||||
Q8, Q9, Q10, Q11, Q12, Q13, Q14, Q15,
|
||||
static constexpr std::array<ARM64Reg, 32> 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<ARM64Reg> callee_regs = {
|
||||
static constexpr std::array<ARM64Reg, 9> 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();
|
||||
|
@ -4,10 +4,13 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#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<OpArg, 32> 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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user