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;
|
||||
}
|
||||
|
||||
auto MapRAM = [](u32 base_address) {
|
||||
auto MapRAM = [](u32 base_address, bool writable) {
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// KUSEG - cached
|
||||
MapRAM(0x00000000);
|
||||
//MapRAM(0x00200000);
|
||||
//MapRAM(0x00400000);
|
||||
//MapRAM(0x00600000);
|
||||
MapRAM(0x00000000, !isolate_cache);
|
||||
//MapRAM(0x00200000, !isolate_cache);
|
||||
//MapRAM(0x00400000, !isolate_cache);
|
||||
//MapRAM(0x00600000, !isolate_cache);
|
||||
|
||||
// KSEG0 - cached
|
||||
MapRAM(0x80000000);
|
||||
//MapRAM(0x80200000);
|
||||
//MapRAM(0x80400000);
|
||||
//MapRAM(0x80600000);
|
||||
MapRAM(0x80000000, !isolate_cache);
|
||||
//MapRAM(0x80200000, !isolate_cache);
|
||||
//MapRAM(0x80400000, !isolate_cache);
|
||||
//MapRAM(0x80600000, !isolate_cache);
|
||||
}
|
||||
|
||||
// KSEG1 - uncached
|
||||
MapRAM(0xA0000000);
|
||||
//MapRAM(0xA0200000);
|
||||
//MapRAM(0xA0400000);
|
||||
//MapRAM(0xA0600000);
|
||||
MapRAM(0xA0000000, true);
|
||||
//MapRAM(0xA0200000, true);
|
||||
//MapRAM(0xA0400000, true);
|
||||
//MapRAM(0xA0600000, true);
|
||||
}
|
||||
|
||||
bool CanUseFastmemForAddress(VirtualMemoryAddress address)
|
||||
|
|
|
@ -79,6 +79,7 @@ public:
|
|||
// Automatically generates an exception handler.
|
||||
Value EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const Value& address, const SpeculativeValue& address_spec,
|
||||
RegSize size);
|
||||
void EmitLoadGuestRAMFastmem(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,
|
||||
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,
|
||||
Value& result)
|
||||
{
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "common/log.h"
|
||||
#include "cpu_core.h"
|
||||
#include "cpu_core_private.h"
|
||||
#include "cpu_recompiler_code_generator.h"
|
||||
#include "settings.h"
|
||||
#include "common/log.h"
|
||||
Log_SetChannel(Recompiler::CodeGenerator);
|
||||
|
||||
namespace CPU::Recompiler {
|
||||
|
@ -40,7 +40,12 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
|
|||
if (ptr)
|
||||
{
|
||||
Value result = m_register_cache.AllocateScratch(size);
|
||||
EmitLoadGlobal(result.GetHostRegister(), size, ptr);
|
||||
|
||||
if (g_settings.IsUsingFastmem() && Bus::IsRAMAddress(static_cast<u32>(address.constant_value)))
|
||||
EmitLoadGuestRAMFastmem(address, size, result);
|
||||
else
|
||||
EmitLoadGlobal(result.GetHostRegister(), size, ptr);
|
||||
|
||||
m_delayed_cycles_add += read_ticks;
|
||||
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,
|
||||
Value& result)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue