CPU/Recompiler: Use fastmem instead of global for RAM loads
This commit is contained in:
parent
622aee7c96
commit
6a4a4c62d7
|
@ -284,9 +284,9 @@ void UpdateFastmemViews(bool enabled, bool isolate_cache)
|
||||||
CPU::g_state.fastmem_base = m_fastmem_base;
|
CPU::g_state.fastmem_base = m_fastmem_base;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto MapRAM = [](u32 base_address) {
|
auto MapRAM = [](u32 base_address, bool writable) {
|
||||||
u8* map_address = m_fastmem_base + base_address;
|
u8* map_address = m_fastmem_base + base_address;
|
||||||
auto view = m_memory_arena.CreateView(MEMORY_ARENA_RAM_OFFSET, RAM_SIZE, true, false, map_address);
|
auto view = m_memory_arena.CreateView(MEMORY_ARENA_RAM_OFFSET, RAM_SIZE, writable, false, map_address);
|
||||||
if (!view)
|
if (!view)
|
||||||
{
|
{
|
||||||
Log_ErrorPrintf("Failed to map RAM at fastmem area %p (offset 0x%08X)", map_address, RAM_SIZE);
|
Log_ErrorPrintf("Failed to map RAM at fastmem area %p (offset 0x%08X)", map_address, RAM_SIZE);
|
||||||
|
@ -313,23 +313,23 @@ void UpdateFastmemViews(bool enabled, bool isolate_cache)
|
||||||
if (!isolate_cache)
|
if (!isolate_cache)
|
||||||
{
|
{
|
||||||
// KUSEG - cached
|
// KUSEG - cached
|
||||||
MapRAM(0x00000000);
|
MapRAM(0x00000000, !isolate_cache);
|
||||||
//MapRAM(0x00200000);
|
//MapRAM(0x00200000, !isolate_cache);
|
||||||
//MapRAM(0x00400000);
|
//MapRAM(0x00400000, !isolate_cache);
|
||||||
//MapRAM(0x00600000);
|
//MapRAM(0x00600000, !isolate_cache);
|
||||||
|
|
||||||
// KSEG0 - cached
|
// KSEG0 - cached
|
||||||
MapRAM(0x80000000);
|
MapRAM(0x80000000, !isolate_cache);
|
||||||
//MapRAM(0x80200000);
|
//MapRAM(0x80200000, !isolate_cache);
|
||||||
//MapRAM(0x80400000);
|
//MapRAM(0x80400000, !isolate_cache);
|
||||||
//MapRAM(0x80600000);
|
//MapRAM(0x80600000, !isolate_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
// KSEG1 - uncached
|
// KSEG1 - uncached
|
||||||
MapRAM(0xA0000000);
|
MapRAM(0xA0000000, true);
|
||||||
//MapRAM(0xA0200000);
|
//MapRAM(0xA0200000, true);
|
||||||
//MapRAM(0xA0400000);
|
//MapRAM(0xA0400000, true);
|
||||||
//MapRAM(0xA0600000);
|
//MapRAM(0xA0600000, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CanUseFastmemForAddress(VirtualMemoryAddress address)
|
bool CanUseFastmemForAddress(VirtualMemoryAddress address)
|
||||||
|
|
|
@ -79,6 +79,7 @@ public:
|
||||||
// Automatically generates an exception handler.
|
// Automatically generates an exception handler.
|
||||||
Value EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const Value& address, const SpeculativeValue& address_spec,
|
Value EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const Value& address, const SpeculativeValue& address_spec,
|
||||||
RegSize size);
|
RegSize size);
|
||||||
|
void EmitLoadGuestRAMFastmem(const Value& address, RegSize size, Value& result);
|
||||||
void EmitLoadGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size, Value& result);
|
void EmitLoadGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size, Value& result);
|
||||||
void EmitLoadGuestMemorySlowmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size, Value& result,
|
void EmitLoadGuestMemorySlowmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size, Value& result,
|
||||||
bool in_far_code);
|
bool in_far_code);
|
||||||
|
|
|
@ -1281,6 +1281,39 @@ void CodeGenerator::EmitAddCPUStructField(u32 offset, const Value& value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::EmitLoadGuestRAMFastmem(const Value& address, RegSize size, Value& result)
|
||||||
|
{
|
||||||
|
a64::MemOperand actual_address;
|
||||||
|
if (address.IsConstant())
|
||||||
|
{
|
||||||
|
m_emit->Mov(GetHostReg32(result.host_reg), address.constant_value);
|
||||||
|
actual_address = a64::MemOperand(GetFastmemBasePtrReg(), GetHostReg32(result.host_reg));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
actual_address = a64::MemOperand(GetFastmemBasePtrReg(), GetHostReg32(address));
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case RegSize_8:
|
||||||
|
m_emit->Ldrb(GetHostReg32(result.host_reg), actual_address);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RegSize_16:
|
||||||
|
m_emit->Ldrh(GetHostReg32(result.host_reg), actual_address);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RegSize_32:
|
||||||
|
m_emit->Ldr(GetHostReg32(result.host_reg), actual_address);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
UnreachableCode();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CodeGenerator::EmitLoadGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size,
|
void CodeGenerator::EmitLoadGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size,
|
||||||
Value& result)
|
Value& result)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
|
#include "common/log.h"
|
||||||
#include "cpu_core.h"
|
#include "cpu_core.h"
|
||||||
#include "cpu_core_private.h"
|
#include "cpu_core_private.h"
|
||||||
#include "cpu_recompiler_code_generator.h"
|
#include "cpu_recompiler_code_generator.h"
|
||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
#include "common/log.h"
|
|
||||||
Log_SetChannel(Recompiler::CodeGenerator);
|
Log_SetChannel(Recompiler::CodeGenerator);
|
||||||
|
|
||||||
namespace CPU::Recompiler {
|
namespace CPU::Recompiler {
|
||||||
|
@ -40,7 +40,12 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
|
||||||
if (ptr)
|
if (ptr)
|
||||||
{
|
{
|
||||||
Value result = m_register_cache.AllocateScratch(size);
|
Value result = m_register_cache.AllocateScratch(size);
|
||||||
|
|
||||||
|
if (g_settings.IsUsingFastmem() && Bus::IsRAMAddress(static_cast<u32>(address.constant_value)))
|
||||||
|
EmitLoadGuestRAMFastmem(address, size, result);
|
||||||
|
else
|
||||||
EmitLoadGlobal(result.GetHostRegister(), size, ptr);
|
EmitLoadGlobal(result.GetHostRegister(), size, ptr);
|
||||||
|
|
||||||
m_delayed_cycles_add += read_ticks;
|
m_delayed_cycles_add += read_ticks;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1745,6 +1745,66 @@ void CodeGenerator::EmitAddCPUStructField(u32 offset, const Value& value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CodeGenerator::EmitLoadGuestRAMFastmem(const Value& address, RegSize size, Value& result)
|
||||||
|
{
|
||||||
|
// can't store displacements > 0x80000000 in-line
|
||||||
|
const Value* actual_address = &address;
|
||||||
|
if (address.IsConstant() && address.constant_value >= 0x80000000)
|
||||||
|
{
|
||||||
|
actual_address = &result;
|
||||||
|
m_emit->mov(GetHostReg32(result.host_reg), address.constant_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: movsx/zx inline here
|
||||||
|
switch (size)
|
||||||
|
{
|
||||||
|
case RegSize_8:
|
||||||
|
{
|
||||||
|
if (actual_address->IsConstant())
|
||||||
|
{
|
||||||
|
m_emit->mov(GetHostReg8(result.host_reg),
|
||||||
|
m_emit->byte[GetFastmemBasePtrReg() + actual_address->constant_value]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_emit->mov(GetHostReg8(result.host_reg),
|
||||||
|
m_emit->byte[GetFastmemBasePtrReg() + GetHostReg64(actual_address->host_reg)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RegSize_16:
|
||||||
|
{
|
||||||
|
if (actual_address->IsConstant())
|
||||||
|
{
|
||||||
|
m_emit->mov(GetHostReg16(result.host_reg),
|
||||||
|
m_emit->word[GetFastmemBasePtrReg() + actual_address->constant_value]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_emit->mov(GetHostReg16(result.host_reg),
|
||||||
|
m_emit->word[GetFastmemBasePtrReg() + GetHostReg64(actual_address->host_reg)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RegSize_32:
|
||||||
|
{
|
||||||
|
if (actual_address->IsConstant())
|
||||||
|
{
|
||||||
|
m_emit->mov(GetHostReg32(result.host_reg),
|
||||||
|
m_emit->dword[GetFastmemBasePtrReg() + actual_address->constant_value]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_emit->mov(GetHostReg32(result.host_reg),
|
||||||
|
m_emit->dword[GetFastmemBasePtrReg() + GetHostReg64(actual_address->host_reg)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void CodeGenerator::EmitLoadGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size,
|
void CodeGenerator::EmitLoadGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, RegSize size,
|
||||||
Value& result)
|
Value& result)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue