CPU/Recompiler: Flush caller-saved regs before calling functions

Should provide a very small performance boost.
This commit is contained in:
Connor McLaughlin 2020-08-23 14:03:08 +10:00
parent 136a9d60e9
commit 60eb22537b
4 changed files with 30 additions and 0 deletions

View File

@ -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.
Value result = m_register_cache.AllocateScratch(RegSize_64);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
// NOTE: This can leave junk in the upper bits
switch (size)
@ -1357,6 +1358,8 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
else
{
Value result = m_register_cache.AllocateScratch(RegSize_32);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
switch (size)
{
case RegSize_8:
@ -1406,6 +1409,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
if (g_settings.cpu_recompiler_memory_exceptions)
{
Value result = m_register_cache.AllocateScratch(RegSize_32);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
switch (value.size)
{
case RegSize_8:
@ -1449,6 +1454,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
}
else
{
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
switch (value.size)
{
case RegSize_8:

View File

@ -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.
Value result = m_register_cache.AllocateScratch(RegSize_64);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
// NOTE: This can leave junk in the upper bits
switch (size)
@ -1811,6 +1812,8 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
else
{
Value result = m_register_cache.AllocateScratch(RegSize_32);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
switch (size)
{
case RegSize_8:
@ -1860,6 +1863,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
if (g_settings.cpu_recompiler_memory_exceptions)
{
Value result = m_register_cache.AllocateScratch(RegSize_32);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
switch (value.size)
{
case RegSize_8:
@ -1901,6 +1906,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
}
else
{
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
switch (value.size)
{
case RegSize_8:

View File

@ -739,6 +739,21 @@ void RegisterCache::FlushAllGuestRegisters(bool invalidate, bool 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()
{
if (m_state.guest_reg_order_count == 0)

View File

@ -316,6 +316,7 @@ public:
void InvalidateAllNonDirtyGuestRegisters();
void FlushAllGuestRegisters(bool invalidate, bool clear_dirty);
void FlushCallerSavedGuestRegisters(bool invalidate, bool clear_dirty);
bool EvictOneGuestRegister();
/// Temporarily prevents register allocation.