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 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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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{};
|
||||||
|
|
Loading…
Reference in New Issue