Merge pull request #12472 from mitaclaw/arm64-flush-mode
Arm64RegCache: Use FlushMode everywhere
This commit is contained in:
commit
696a6defd2
|
@ -122,7 +122,7 @@ void Arm64RegCache::FlushMostStaleRegister()
|
|||
}
|
||||
}
|
||||
|
||||
FlushRegister(most_stale_preg, false, ARM64Reg::INVALID_REG);
|
||||
FlushRegister(most_stale_preg, FlushMode::All, ARM64Reg::INVALID_REG);
|
||||
}
|
||||
|
||||
void Arm64RegCache::DiscardRegister(size_t preg)
|
||||
|
@ -184,7 +184,7 @@ Arm64GPRCache::GuestRegInfo Arm64GPRCache::GetGuestByIndex(size_t index)
|
|||
return GetGuestGPR(0);
|
||||
}
|
||||
|
||||
void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state, ARM64Reg tmp_reg)
|
||||
void Arm64GPRCache::FlushRegister(size_t index, FlushMode mode, ARM64Reg tmp_reg)
|
||||
{
|
||||
GuestRegInfo guest_reg = GetGuestByIndex(index);
|
||||
OpArg& reg = guest_reg.reg;
|
||||
|
@ -196,7 +196,7 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state, ARM64Reg tm
|
|||
if (reg.IsDirty())
|
||||
m_emit->STR(IndexType::Unsigned, host_reg, PPC_REG, u32(guest_reg.ppc_offset));
|
||||
|
||||
if (!maintain_state)
|
||||
if (mode == FlushMode::All)
|
||||
{
|
||||
UnlockRegister(EncodeRegTo32(host_reg));
|
||||
reg.Flush();
|
||||
|
@ -220,7 +220,7 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state, ARM64Reg tm
|
|||
}
|
||||
else
|
||||
{
|
||||
ASSERT_MSG(DYNA_REC, !maintain_state,
|
||||
ASSERT_MSG(DYNA_REC, mode != FlushMode::MaintainState,
|
||||
"Flushing immediate while maintaining state requires temporary register");
|
||||
tmp_reg = GetReg();
|
||||
allocated_tmp_reg = true;
|
||||
|
@ -236,12 +236,12 @@ void Arm64GPRCache::FlushRegister(size_t index, bool maintain_state, ARM64Reg tm
|
|||
}
|
||||
}
|
||||
|
||||
if (!maintain_state)
|
||||
if (mode == FlushMode::All)
|
||||
reg.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state, ARM64Reg tmp_reg)
|
||||
void Arm64GPRCache::FlushRegisters(BitSet32 regs, FlushMode mode, ARM64Reg tmp_reg)
|
||||
{
|
||||
for (auto iter = regs.begin(); iter != regs.end(); ++iter)
|
||||
{
|
||||
|
@ -263,7 +263,7 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state, ARM64Reg
|
|||
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)
|
||||
if (mode == FlushMode::All)
|
||||
{
|
||||
UnlockRegister(EncodeRegTo32(RX1));
|
||||
UnlockRegister(EncodeRegTo32(RX2));
|
||||
|
@ -276,18 +276,18 @@ void Arm64GPRCache::FlushRegisters(BitSet32 regs, bool maintain_state, ARM64Reg
|
|||
}
|
||||
}
|
||||
|
||||
FlushRegister(GUEST_GPR_OFFSET + i, maintain_state, tmp_reg);
|
||||
FlushRegister(GUEST_GPR_OFFSET + i, mode, tmp_reg);
|
||||
}
|
||||
}
|
||||
|
||||
void Arm64GPRCache::FlushCRRegisters(BitSet8 regs, bool maintain_state, ARM64Reg tmp_reg)
|
||||
void Arm64GPRCache::FlushCRRegisters(BitSet8 regs, FlushMode mode, ARM64Reg tmp_reg)
|
||||
{
|
||||
for (int i : regs)
|
||||
{
|
||||
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, mode, tmp_reg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,8 +312,8 @@ void Arm64GPRCache::ResetCRRegisters(BitSet8 regs)
|
|||
|
||||
void Arm64GPRCache::Flush(FlushMode mode, ARM64Reg tmp_reg)
|
||||
{
|
||||
FlushRegisters(BitSet32(0xFFFFFFFF), mode == FlushMode::MaintainState, tmp_reg);
|
||||
FlushCRRegisters(BitSet8(0xFF), mode == FlushMode::MaintainState, tmp_reg);
|
||||
FlushRegisters(BitSet32(0xFFFFFFFF), mode, tmp_reg);
|
||||
FlushCRRegisters(BitSet8(0xFF), mode, tmp_reg);
|
||||
}
|
||||
|
||||
ARM64Reg Arm64GPRCache::R(const GuestRegInfo& guest_reg)
|
||||
|
@ -477,7 +477,7 @@ void Arm64GPRCache::FlushByHost(ARM64Reg host_reg, ARM64Reg tmp_reg)
|
|||
const OpArg& reg = m_guest_registers[i];
|
||||
if (reg.GetType() == RegType::Register && DecodeReg(reg.GetReg()) == DecodeReg(host_reg))
|
||||
{
|
||||
FlushRegister(i, false, tmp_reg);
|
||||
FlushRegister(i, FlushMode::All, tmp_reg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -499,7 +499,7 @@ void Arm64FPRCache::Flush(FlushMode mode, ARM64Reg tmp_reg)
|
|||
if (reg_type != RegType::NotLoaded && reg_type != RegType::Discarded &&
|
||||
reg_type != RegType::Immediate)
|
||||
{
|
||||
FlushRegister(i, mode == FlushMode::MaintainState, tmp_reg);
|
||||
FlushRegister(i, mode, tmp_reg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -763,7 +763,7 @@ void Arm64FPRCache::FlushByHost(ARM64Reg host_reg, ARM64Reg tmp_reg)
|
|||
if (reg_type != RegType::NotLoaded && reg_type != RegType::Discarded &&
|
||||
reg_type != RegType::Immediate && reg.GetReg() == host_reg)
|
||||
{
|
||||
FlushRegister(i, false, tmp_reg);
|
||||
FlushRegister(i, FlushMode::All, tmp_reg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ bool Arm64FPRCache::IsTopHalfUsed(ARM64Reg reg) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state, ARM64Reg tmp_reg)
|
||||
void Arm64FPRCache::FlushRegister(size_t preg, FlushMode mode, ARM64Reg tmp_reg)
|
||||
{
|
||||
OpArg& reg = m_guest_registers[preg];
|
||||
const ARM64Reg host_reg = reg.GetReg();
|
||||
|
@ -802,7 +802,7 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state, ARM64Reg tmp
|
|||
// Calling GetReg here with 0 registers free could cause problems for two reasons:
|
||||
//
|
||||
// 1. When GetReg needs to flush, it calls this function, which can lead to infinite recursion
|
||||
// 2. When GetReg needs to flush, it does not respect maintain_state == true
|
||||
// 2. When GetReg needs to flush, it does not respect mode == FlushMode::MaintainState
|
||||
//
|
||||
// So if we have 0 registers free, just don't allocate a temporary register.
|
||||
// The emitted code will still work but might be a little less efficient.
|
||||
|
@ -843,7 +843,7 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state, ARM64Reg tmp
|
|||
static_cast<s32>(PPCSTATE_OFF_PS0(preg)));
|
||||
}
|
||||
|
||||
if (!maintain_state)
|
||||
if (mode == FlushMode::All)
|
||||
{
|
||||
UnlockRegister(host_reg);
|
||||
reg.Flush();
|
||||
|
@ -867,7 +867,7 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state, ARM64Reg tmp
|
|||
}
|
||||
}
|
||||
|
||||
if (!maintain_state)
|
||||
if (mode == FlushMode::All)
|
||||
{
|
||||
UnlockRegister(host_reg);
|
||||
reg.Flush();
|
||||
|
@ -878,10 +878,10 @@ void Arm64FPRCache::FlushRegister(size_t preg, bool maintain_state, ARM64Reg tmp
|
|||
UnlockRegister(tmp_reg);
|
||||
}
|
||||
|
||||
void Arm64FPRCache::FlushRegisters(BitSet32 regs, bool maintain_state, ARM64Reg tmp_reg)
|
||||
void Arm64FPRCache::FlushRegisters(BitSet32 regs, FlushMode mode, ARM64Reg tmp_reg)
|
||||
{
|
||||
for (int j : regs)
|
||||
FlushRegister(j, maintain_state, tmp_reg);
|
||||
FlushRegister(j, mode, tmp_reg);
|
||||
}
|
||||
|
||||
BitSet32 Arm64FPRCache::GetCallerSavedUsed() const
|
||||
|
|
|
@ -72,7 +72,7 @@ enum class RegType
|
|||
DuplicatedSingle, // The lower one contains both registers, as single
|
||||
};
|
||||
|
||||
enum class FlushMode
|
||||
enum class FlushMode : bool
|
||||
{
|
||||
// Flushes all registers, no exceptions
|
||||
All,
|
||||
|
@ -227,7 +227,7 @@ protected:
|
|||
Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG) = 0;
|
||||
|
||||
void DiscardRegister(size_t preg);
|
||||
virtual void FlushRegister(size_t preg, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg) = 0;
|
||||
virtual void FlushRegister(size_t preg, FlushMode mode, Arm64Gen::ARM64Reg tmp_reg) = 0;
|
||||
|
||||
void IncrementAllUsed()
|
||||
{
|
||||
|
@ -329,12 +329,12 @@ public:
|
|||
|
||||
void StoreRegisters(BitSet32 regs, Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG)
|
||||
{
|
||||
FlushRegisters(regs, false, tmp_reg);
|
||||
FlushRegisters(regs, FlushMode::All, tmp_reg);
|
||||
}
|
||||
|
||||
void StoreCRRegisters(BitSet8 regs, Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG)
|
||||
{
|
||||
FlushCRRegisters(regs, false, tmp_reg);
|
||||
FlushCRRegisters(regs, FlushMode::All, tmp_reg);
|
||||
}
|
||||
|
||||
void DiscardCRRegisters(BitSet8 regs);
|
||||
|
@ -348,7 +348,7 @@ protected:
|
|||
void FlushByHost(Arm64Gen::ARM64Reg host_reg,
|
||||
Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG) override;
|
||||
|
||||
void FlushRegister(size_t index, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg) override;
|
||||
void FlushRegister(size_t index, FlushMode mode, Arm64Gen::ARM64Reg tmp_reg) override;
|
||||
|
||||
private:
|
||||
bool IsCallerSaved(Arm64Gen::ARM64Reg reg) const;
|
||||
|
@ -369,8 +369,8 @@ private:
|
|||
void SetImmediate(const GuestRegInfo& guest_reg, u32 imm, bool dirty);
|
||||
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(BitSet8 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg);
|
||||
void FlushRegisters(BitSet32 regs, FlushMode mode, Arm64Gen::ARM64Reg tmp_reg);
|
||||
void FlushCRRegisters(BitSet8 regs, FlushMode mode, Arm64Gen::ARM64Reg tmp_reg);
|
||||
};
|
||||
|
||||
class Arm64FPRCache : public Arm64RegCache
|
||||
|
@ -396,7 +396,7 @@ public:
|
|||
|
||||
void StoreRegisters(BitSet32 regs, Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG)
|
||||
{
|
||||
FlushRegisters(regs, false, tmp_reg);
|
||||
FlushRegisters(regs, FlushMode::All, tmp_reg);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -407,11 +407,11 @@ protected:
|
|||
void FlushByHost(Arm64Gen::ARM64Reg host_reg,
|
||||
Arm64Gen::ARM64Reg tmp_reg = Arm64Gen::ARM64Reg::INVALID_REG) override;
|
||||
|
||||
void FlushRegister(size_t preg, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg) override;
|
||||
void FlushRegister(size_t preg, FlushMode mode, Arm64Gen::ARM64Reg tmp_reg) override;
|
||||
|
||||
private:
|
||||
bool IsCallerSaved(Arm64Gen::ARM64Reg reg) const;
|
||||
bool IsTopHalfUsed(Arm64Gen::ARM64Reg reg) const;
|
||||
|
||||
void FlushRegisters(BitSet32 regs, bool maintain_state, Arm64Gen::ARM64Reg tmp_reg);
|
||||
void FlushRegisters(BitSet32 regs, FlushMode mode, Arm64Gen::ARM64Reg tmp_reg);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue