CPU/Recompiler: Flush caller-saved regs before calling functions
Should provide a very small performance boost.
This commit is contained in:
parent
136a9d60e9
commit
60eb22537b
|
@ -1288,6 +1288,7 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
{
|
{
|
||||||
// We need to use the full 64 bits here since we test the sign bit result.
|
// We need to use the full 64 bits here since we test the sign bit result.
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_64);
|
Value result = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
// NOTE: This can leave junk in the upper bits
|
// NOTE: This can leave junk in the upper bits
|
||||||
switch (size)
|
switch (size)
|
||||||
|
@ -1357,6 +1358,8 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
@ -1406,6 +1409,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
if (g_settings.cpu_recompiler_memory_exceptions)
|
if (g_settings.cpu_recompiler_memory_exceptions)
|
||||||
{
|
{
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
switch (value.size)
|
switch (value.size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
@ -1449,6 +1454,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
switch (value.size)
|
switch (value.size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
|
|
@ -1744,6 +1744,7 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
{
|
{
|
||||||
// We need to use the full 64 bits here since we test the sign bit result.
|
// We need to use the full 64 bits here since we test the sign bit result.
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_64);
|
Value result = m_register_cache.AllocateScratch(RegSize_64);
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
// NOTE: This can leave junk in the upper bits
|
// NOTE: This can leave junk in the upper bits
|
||||||
switch (size)
|
switch (size)
|
||||||
|
@ -1811,6 +1812,8 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
switch (size)
|
switch (size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
@ -1860,6 +1863,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
if (g_settings.cpu_recompiler_memory_exceptions)
|
if (g_settings.cpu_recompiler_memory_exceptions)
|
||||||
{
|
{
|
||||||
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
Value result = m_register_cache.AllocateScratch(RegSize_32);
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
switch (value.size)
|
switch (value.size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
@ -1901,6 +1906,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
|
||||||
|
|
||||||
switch (value.size)
|
switch (value.size)
|
||||||
{
|
{
|
||||||
case RegSize_8:
|
case RegSize_8:
|
||||||
|
|
|
@ -739,6 +739,21 @@ void RegisterCache::FlushAllGuestRegisters(bool invalidate, bool clear_dirty)
|
||||||
FlushGuestRegister(static_cast<Reg>(reg), invalidate, clear_dirty);
|
FlushGuestRegister(static_cast<Reg>(reg), invalidate, clear_dirty);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RegisterCache::FlushCallerSavedGuestRegisters(bool invalidate, bool clear_dirty)
|
||||||
|
{
|
||||||
|
for (u8 reg = 0; reg < static_cast<u8>(Reg::count); reg++)
|
||||||
|
{
|
||||||
|
const Value& gr = m_state.guest_reg_state[reg];
|
||||||
|
if (!gr.IsInHostRegister() ||
|
||||||
|
(m_state.host_reg_state[gr.GetHostRegister()] & HostRegState::CallerSaved) != HostRegState::CallerSaved)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlushGuestRegister(static_cast<Reg>(reg), invalidate, clear_dirty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool RegisterCache::EvictOneGuestRegister()
|
bool RegisterCache::EvictOneGuestRegister()
|
||||||
{
|
{
|
||||||
if (m_state.guest_reg_order_count == 0)
|
if (m_state.guest_reg_order_count == 0)
|
||||||
|
|
|
@ -316,6 +316,7 @@ public:
|
||||||
|
|
||||||
void InvalidateAllNonDirtyGuestRegisters();
|
void InvalidateAllNonDirtyGuestRegisters();
|
||||||
void FlushAllGuestRegisters(bool invalidate, bool clear_dirty);
|
void FlushAllGuestRegisters(bool invalidate, bool clear_dirty);
|
||||||
|
void FlushCallerSavedGuestRegisters(bool invalidate, bool clear_dirty);
|
||||||
bool EvictOneGuestRegister();
|
bool EvictOneGuestRegister();
|
||||||
|
|
||||||
/// Temporarily prevents register allocation.
|
/// Temporarily prevents register allocation.
|
||||||
|
|
Loading…
Reference in New Issue