CPU/Recompiler: Add temporary inhibiting of register allocation

This commit is contained in:
Connor McLaughlin 2020-08-08 22:55:39 +10:00
parent 1d5f810a4b
commit 901ca71fdc
3 changed files with 28 additions and 3 deletions

View File

@ -1433,6 +1433,7 @@ bool CodeGenerator::Compile_Divide(const CodeBlockInstruction& cbi)
Value lo = m_register_cache.AllocateScratch(RegSize_32); Value lo = m_register_cache.AllocateScratch(RegSize_32);
Value hi = m_register_cache.AllocateScratch(RegSize_32); Value hi = m_register_cache.AllocateScratch(RegSize_32);
m_register_cache.InhibitAllocation();
LabelType do_divide, done; LabelType do_divide, done;
@ -1458,6 +1459,7 @@ bool CodeGenerator::Compile_Divide(const CodeBlockInstruction& cbi)
EmitBindLabel(&done); EmitBindLabel(&done);
m_register_cache.UnunhibitAllocation();
m_register_cache.WriteGuestRegister(Reg::lo, std::move(lo)); m_register_cache.WriteGuestRegister(Reg::lo, std::move(lo));
m_register_cache.WriteGuestRegister(Reg::hi, std::move(hi)); m_register_cache.WriteGuestRegister(Reg::hi, std::move(hi));
} }
@ -1488,6 +1490,7 @@ bool CodeGenerator::Compile_SignedDivide(const CodeBlockInstruction& cbi)
Value lo = m_register_cache.AllocateScratch(RegSize_32); Value lo = m_register_cache.AllocateScratch(RegSize_32);
Value hi = m_register_cache.AllocateScratch(RegSize_32); Value hi = m_register_cache.AllocateScratch(RegSize_32);
m_register_cache.InhibitAllocation();
// we need this in a register on ARM because it won't fit in an immediate // we need this in a register on ARM because it won't fit in an immediate
EmitCopyValue(lo.GetHostRegister(), Value::FromConstantU32(0x80000000u)); EmitCopyValue(lo.GetHostRegister(), Value::FromConstantU32(0x80000000u));
@ -1538,6 +1541,7 @@ bool CodeGenerator::Compile_SignedDivide(const CodeBlockInstruction& cbi)
EmitBindLabel(&done); EmitBindLabel(&done);
m_register_cache.UnunhibitAllocation();
m_register_cache.WriteGuestRegister(Reg::lo, std::move(lo)); m_register_cache.WriteGuestRegister(Reg::lo, std::move(lo));
m_register_cache.WriteGuestRegister(Reg::hi, std::move(hi)); m_register_cache.WriteGuestRegister(Reg::hi, std::move(hi));
} }

View File

@ -184,6 +184,9 @@ u32 RegisterCache::GetFreeHostRegisters() const
HostReg RegisterCache::AllocateHostReg(HostRegState state /* = HostRegState::InUse */) HostReg RegisterCache::AllocateHostReg(HostRegState state /* = HostRegState::InUse */)
{ {
if (m_state.allocator_inhibit_count > 0)
Panic("Allocating when inhibited");
// try for a free register in allocation order // try for a free register in allocation order
for (u32 i = 0; i < m_state.available_count; i++) for (u32 i = 0; i < m_state.available_count; i++)
{ {
@ -359,6 +362,7 @@ void RegisterCache::PushState()
save_state.available_count = m_state.available_count; save_state.available_count = m_state.available_count;
save_state.callee_saved_order_count = m_state.callee_saved_order_count; save_state.callee_saved_order_count = m_state.callee_saved_order_count;
save_state.guest_reg_order_count = m_state.guest_reg_order_count; save_state.guest_reg_order_count = m_state.guest_reg_order_count;
save_state.allocator_inhibit_count = m_state.allocator_inhibit_count;
save_state.load_delay_register = m_state.load_delay_register; save_state.load_delay_register = m_state.load_delay_register;
save_state.load_delay_value.regcache = m_state.load_delay_value.regcache; save_state.load_delay_value.regcache = m_state.load_delay_value.regcache;
save_state.load_delay_value.host_reg = m_state.load_delay_value.host_reg; save_state.load_delay_value.host_reg = m_state.load_delay_value.host_reg;
@ -496,14 +500,15 @@ Value RegisterCache::ReadGuestRegisterToScratch(Reg guest_reg)
if (cache_value.IsConstant()) if (cache_value.IsConstant())
{ {
Log_DebugPrintf("Copying guest register %s from constant 0x%08X to scratch host register %s", GetRegName(guest_reg), Log_DebugPrintf("Copying guest register %s from constant 0x%08X to scratch host register %s",
static_cast<u32>(cache_value.constant_value), GetRegName(guest_reg), static_cast<u32>(cache_value.constant_value),
m_code_generator.GetHostRegName(host_reg, RegSize_32)); m_code_generator.GetHostRegName(host_reg, RegSize_32));
} }
else else
{ {
Log_DebugPrintf("Copying guest register %s from %s to scratch host register %s", GetRegName(guest_reg), Log_DebugPrintf("Copying guest register %s from %s to scratch host register %s", GetRegName(guest_reg),
m_code_generator.GetHostRegName(cache_value.host_reg, RegSize_32), m_code_generator.GetHostRegName(host_reg, RegSize_32)); m_code_generator.GetHostRegName(cache_value.host_reg, RegSize_32),
m_code_generator.GetHostRegName(host_reg, RegSize_32));
} }
} }
else else
@ -796,4 +801,15 @@ void RegisterCache::AppendRegisterToOrder(Reg reg)
m_state.guest_reg_order_count++; m_state.guest_reg_order_count++;
} }
void RegisterCache::InhibitAllocation()
{
m_state.allocator_inhibit_count++;
}
void RegisterCache::UnunhibitAllocation()
{
Assert(m_state.allocator_inhibit_count > 0);
m_state.allocator_inhibit_count--;
}
} // namespace CPU::Recompiler } // namespace CPU::Recompiler

View File

@ -317,6 +317,10 @@ public:
void FlushAllGuestRegisters(bool invalidate, bool clear_dirty); void FlushAllGuestRegisters(bool invalidate, bool clear_dirty);
bool EvictOneGuestRegister(); bool EvictOneGuestRegister();
/// Temporarily prevents register allocation.
void InhibitAllocation();
void UnunhibitAllocation();
private: private:
void ClearRegisterFromOrder(Reg reg); void ClearRegisterFromOrder(Reg reg);
void PushRegisterToOrder(Reg reg); void PushRegisterToOrder(Reg reg);
@ -338,6 +342,7 @@ private:
u32 available_count = 0; u32 available_count = 0;
u32 callee_saved_order_count = 0; u32 callee_saved_order_count = 0;
u32 guest_reg_order_count = 0; u32 guest_reg_order_count = 0;
u32 allocator_inhibit_count = 0;
Reg load_delay_register = Reg::count; Reg load_delay_register = Reg::count;
Value load_delay_value{}; Value load_delay_value{};