CPU/Recompiler: Add temporary inhibiting of register allocation
This commit is contained in:
parent
1d5f810a4b
commit
901ca71fdc
|
@ -1433,6 +1433,7 @@ bool CodeGenerator::Compile_Divide(const CodeBlockInstruction& cbi)
|
|||
|
||||
Value lo = m_register_cache.AllocateScratch(RegSize_32);
|
||||
Value hi = m_register_cache.AllocateScratch(RegSize_32);
|
||||
m_register_cache.InhibitAllocation();
|
||||
|
||||
LabelType do_divide, done;
|
||||
|
||||
|
@ -1458,6 +1459,7 @@ bool CodeGenerator::Compile_Divide(const CodeBlockInstruction& cbi)
|
|||
|
||||
EmitBindLabel(&done);
|
||||
|
||||
m_register_cache.UnunhibitAllocation();
|
||||
m_register_cache.WriteGuestRegister(Reg::lo, std::move(lo));
|
||||
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 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
|
||||
EmitCopyValue(lo.GetHostRegister(), Value::FromConstantU32(0x80000000u));
|
||||
|
@ -1538,6 +1541,7 @@ bool CodeGenerator::Compile_SignedDivide(const CodeBlockInstruction& cbi)
|
|||
|
||||
EmitBindLabel(&done);
|
||||
|
||||
m_register_cache.UnunhibitAllocation();
|
||||
m_register_cache.WriteGuestRegister(Reg::lo, std::move(lo));
|
||||
m_register_cache.WriteGuestRegister(Reg::hi, std::move(hi));
|
||||
}
|
||||
|
|
|
@ -184,6 +184,9 @@ u32 RegisterCache::GetFreeHostRegisters() const
|
|||
|
||||
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
|
||||
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.callee_saved_order_count = m_state.callee_saved_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_value.regcache = m_state.load_delay_value.regcache;
|
||||
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())
|
||||
{
|
||||
Log_DebugPrintf("Copying guest register %s from constant 0x%08X to scratch host register %s", GetRegName(guest_reg),
|
||||
static_cast<u32>(cache_value.constant_value),
|
||||
Log_DebugPrintf("Copying guest register %s from constant 0x%08X to scratch host register %s",
|
||||
GetRegName(guest_reg), static_cast<u32>(cache_value.constant_value),
|
||||
m_code_generator.GetHostRegName(host_reg, RegSize_32));
|
||||
}
|
||||
else
|
||||
{
|
||||
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
|
||||
|
@ -796,4 +801,15 @@ void RegisterCache::AppendRegisterToOrder(Reg reg)
|
|||
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
|
||||
|
|
|
@ -317,6 +317,10 @@ public:
|
|||
void FlushAllGuestRegisters(bool invalidate, bool clear_dirty);
|
||||
bool EvictOneGuestRegister();
|
||||
|
||||
/// Temporarily prevents register allocation.
|
||||
void InhibitAllocation();
|
||||
void UnunhibitAllocation();
|
||||
|
||||
private:
|
||||
void ClearRegisterFromOrder(Reg reg);
|
||||
void PushRegisterToOrder(Reg reg);
|
||||
|
@ -338,6 +342,7 @@ private:
|
|||
u32 available_count = 0;
|
||||
u32 callee_saved_order_count = 0;
|
||||
u32 guest_reg_order_count = 0;
|
||||
u32 allocator_inhibit_count = 0;
|
||||
|
||||
Reg load_delay_register = Reg::count;
|
||||
Value load_delay_value{};
|
||||
|
|
Loading…
Reference in New Issue