CPU: Make fastmem a compile-time feature (support 32-bit targets)

This commit is contained in:
Connor McLaughlin 2020-11-21 01:56:51 +10:00
parent dba42cf323
commit a03bca2f72
10 changed files with 127 additions and 29 deletions

View file

@ -115,13 +115,13 @@ endif()
if(${CPU_ARCH} STREQUAL "x64") if(${CPU_ARCH} STREQUAL "x64")
target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../dep/xbyak/xbyak") target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/../../dep/xbyak/xbyak")
target_compile_definitions(core PRIVATE "WITH_RECOMPILER=1") target_compile_definitions(core PRIVATE "WITH_RECOMPILER=1 WITH_FASTMEM=1")
target_sources(core PRIVATE ${RECOMPILER_SRCS} target_sources(core PRIVATE ${RECOMPILER_SRCS}
cpu_recompiler_code_generator_x64.cpp cpu_recompiler_code_generator_x64.cpp
) )
message("Building x64 recompiler") message("Building x64 recompiler")
elseif(${CPU_ARCH} STREQUAL "aarch64") elseif(${CPU_ARCH} STREQUAL "aarch64")
target_compile_definitions(core PRIVATE "WITH_RECOMPILER=1") target_compile_definitions(core PRIVATE "WITH_RECOMPILER=1 WITH_FASTMEM=1")
target_sources(core PRIVATE ${RECOMPILER_SRCS} target_sources(core PRIVATE ${RECOMPILER_SRCS}
cpu_recompiler_code_generator_aarch64.cpp cpu_recompiler_code_generator_aarch64.cpp
) )

View file

@ -87,15 +87,21 @@ static u32 m_ram_size_reg = 0;
static std::string m_tty_line_buffer; static std::string m_tty_line_buffer;
static Common::MemoryArena m_memory_arena; static Common::MemoryArena m_memory_arena;
#ifdef WITH_FASTMEM
static u8* m_fastmem_base = nullptr; static u8* m_fastmem_base = nullptr;
static std::vector<Common::MemoryArena::View> m_fastmem_ram_views; static std::vector<Common::MemoryArena::View> m_fastmem_ram_views;
#endif
static std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay); static std::tuple<TickCount, TickCount, TickCount> CalculateMemoryTiming(MEMDELAY mem_delay, COMDELAY common_delay);
static void RecalculateMemoryTimings(); static void RecalculateMemoryTimings();
static void SetCodePageFastmemProtection(u32 page_index, bool writable);
static bool AllocateMemory(); static bool AllocateMemory();
#ifdef WITH_FASTMEM
static void SetCodePageFastmemProtection(u32 page_index, bool writable);
static void UnmapFastmemViews(); static void UnmapFastmemViews();
#endif
#define FIXUP_WORD_READ_OFFSET(offset) ((offset) & ~u32(3)) #define FIXUP_WORD_READ_OFFSET(offset) ((offset) & ~u32(3))
#define FIXUP_WORD_READ_VALUE(offset, value) ((value) >> (((offset)&u32(3)) * 8u)) #define FIXUP_WORD_READ_VALUE(offset, value) ((value) >> (((offset)&u32(3)) * 8u))
@ -126,7 +132,10 @@ bool Initialize()
void Shutdown() void Shutdown()
{ {
#ifdef WITH_FASTMEM
UnmapFastmemViews(); UnmapFastmemViews();
#endif
if (g_ram) if (g_ram)
{ {
m_memory_arena.ReleaseViewPtr(g_ram, RAM_SIZE); m_memory_arena.ReleaseViewPtr(g_ram, RAM_SIZE);
@ -259,6 +268,8 @@ bool AllocateMemory()
return true; return true;
} }
#ifdef WITH_FASTMEM
void UnmapFastmemViews() void UnmapFastmemViews()
{ {
m_fastmem_ram_views.clear(); m_fastmem_ram_views.clear();
@ -344,6 +355,8 @@ bool CanUseFastmemForAddress(VirtualMemoryAddress address)
return (paddr < RAM_SIZE); return (paddr < RAM_SIZE);
} }
#endif
bool IsRAMCodePage(u32 index) bool IsRAMCodePage(u32 index)
{ {
return m_ram_code_bits[index]; return m_ram_code_bits[index];
@ -356,7 +369,10 @@ void SetRAMCodePage(u32 index)
// protect fastmem pages // protect fastmem pages
m_ram_code_bits[index] = true; m_ram_code_bits[index] = true;
#ifdef WITH_FASTMEM
SetCodePageFastmemProtection(index, false); SetCodePageFastmemProtection(index, false);
#endif
} }
void ClearRAMCodePage(u32 index) void ClearRAMCodePage(u32 index)
@ -366,9 +382,14 @@ void ClearRAMCodePage(u32 index)
// unprotect fastmem pages // unprotect fastmem pages
m_ram_code_bits[index] = false; m_ram_code_bits[index] = false;
#ifdef WITH_FASTMEM
SetCodePageFastmemProtection(index, true); SetCodePageFastmemProtection(index, true);
#endif
} }
#ifdef WITH_FASTMEM
void SetCodePageFastmemProtection(u32 page_index, bool writable) void SetCodePageFastmemProtection(u32 page_index, bool writable)
{ {
// unprotect fastmem pages // unprotect fastmem pages
@ -383,10 +404,13 @@ void SetCodePageFastmemProtection(u32 page_index, bool writable)
} }
} }
#endif
void ClearRAMCodePageFlags() void ClearRAMCodePageFlags()
{ {
m_ram_code_bits.reset(); m_ram_code_bits.reset();
#ifdef WITH_FASTMEM
// unprotect fastmem pages // unprotect fastmem pages
for (const auto& view : m_fastmem_ram_views) for (const auto& view : m_fastmem_ram_views)
{ {
@ -395,6 +419,7 @@ void ClearRAMCodePageFlags()
Log_ErrorPrintf("Failed to unprotect code pages for fastmem view @ %p", view.GetBasePointer()); Log_ErrorPrintf("Failed to unprotect code pages for fastmem view @ %p", view.GetBasePointer());
} }
} }
#endif
} }
bool IsCodePageAddress(PhysicalMemoryAddress address) bool IsCodePageAddress(PhysicalMemoryAddress address)

View file

@ -82,8 +82,10 @@ enum : size_t
// Offsets within the memory arena. // Offsets within the memory arena.
MEMORY_ARENA_RAM_OFFSET = 0, MEMORY_ARENA_RAM_OFFSET = 0,
#ifdef WITH_FASTMEM
// Fastmem region size is 4GB to cover the entire 32-bit address space. // Fastmem region size is 4GB to cover the entire 32-bit address space.
FASTMEM_REGION_SIZE = UINT64_C(0x100000000) FASTMEM_REGION_SIZE = UINT64_C(0x100000000)
#endif
}; };
bool Initialize(); bool Initialize();
@ -91,9 +93,10 @@ void Shutdown();
void Reset(); void Reset();
bool DoState(StateWrapper& sw); bool DoState(StateWrapper& sw);
u8* GetFastmemBase(); #ifdef WITH_FASTMEM
void UpdateFastmemViews(bool enabled, bool isolate_cache); void UpdateFastmemViews(bool enabled, bool isolate_cache);
bool CanUseFastmemForAddress(VirtualMemoryAddress address); bool CanUseFastmemForAddress(VirtualMemoryAddress address);
#endif
void SetExpansionROM(std::vector<u8> data); void SetExpansionROM(std::vector<u8> data);
void SetBIOS(const std::vector<u8>& image); void SetBIOS(const std::vector<u8>& image);

View file

@ -425,7 +425,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ -451,7 +451,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ -506,7 +506,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ -535,7 +535,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_ITERATOR_DEBUG_LEVEL=1;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUGFAST;_DEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
@ -620,7 +620,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
@ -647,7 +647,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>false</WholeProgramOptimization> <WholeProgramOptimization>false</WholeProgramOptimization>
@ -674,7 +674,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\xbyak\xbyak;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
@ -702,7 +702,7 @@
</PrecompiledHeader> </PrecompiledHeader>
<Optimization>MaxSpeed</Optimization> <Optimization>MaxSpeed</Optimization>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>WITH_IMGUI=1;WITH_RECOMPILER=1;WITH_FASTMEM=1;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>$(SolutionDir)dep\msvc\include;$(SolutionDir)dep\glad\include;$(SolutionDir)dep\stb\include;$(SolutionDir)dep\imgui\include;$(SolutionDir)dep\vixl\include;$(SolutionDir)dep\zlib\include;$(SolutionDir)dep\vulkan-loader\include;$(SolutionDir)src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>

View file

@ -99,10 +99,13 @@ static HostCodeMap s_host_code_map;
static void AddBlockToHostCodeMap(CodeBlock* block); static void AddBlockToHostCodeMap(CodeBlock* block);
static void RemoveBlockFromHostCodeMap(CodeBlock* block); static void RemoveBlockFromHostCodeMap(CodeBlock* block);
#ifdef WITH_FASTMEM
static bool InitializeFastmem(); static bool InitializeFastmem();
static void ShutdownFastmem(); static void ShutdownFastmem();
static Common::PageFaultHandler::HandlerResult PageFaultHandler(void* exception_pc, void* fault_address, bool is_write); static Common::PageFaultHandler::HandlerResult PageFaultHandler(void* exception_pc, void* fault_address, bool is_write);
#endif #endif // WITH_FASTMEM
#endif // WITH_RECOMPILER
void Initialize() void Initialize()
{ {
@ -121,8 +124,10 @@ void Initialize()
Panic("Failed to initialize code space"); Panic("Failed to initialize code space");
} }
#ifdef WITH_FASTMEM
if (g_settings.IsUsingFastmem() && !InitializeFastmem()) if (g_settings.IsUsingFastmem() && !InitializeFastmem())
Panic("Failed to initialize fastmem"); Panic("Failed to initialize fastmem");
#endif
ResetFastMap(); ResetFastMap();
CompileDispatcher(); CompileDispatcher();
@ -150,7 +155,9 @@ void ClearState()
void Shutdown() void Shutdown()
{ {
ClearState(); ClearState();
#ifdef WITH_FASTMEM
ShutdownFastmem(); ShutdownFastmem();
#endif
#ifdef WITH_RECOMPILER #ifdef WITH_RECOMPILER
s_code_buffer.Destroy(); s_code_buffer.Destroy();
#endif #endif
@ -326,7 +333,10 @@ void Reinitialize()
#ifdef WITH_RECOMPILER #ifdef WITH_RECOMPILER
#ifdef WITH_FASTMEM
ShutdownFastmem(); ShutdownFastmem();
#endif
s_code_buffer.Destroy(); s_code_buffer.Destroy();
if (g_settings.IsUsingRecompiler()) if (g_settings.IsUsingRecompiler())
@ -342,8 +352,10 @@ void Reinitialize()
Panic("Failed to initialize code space"); Panic("Failed to initialize code space");
} }
#ifdef WITH_FASTMEM
if (g_settings.IsUsingFastmem() && !InitializeFastmem()) if (g_settings.IsUsingFastmem() && !InitializeFastmem())
Panic("Failed to initialize fastmem"); Panic("Failed to initialize fastmem");
#endif
ResetFastMap(); ResetFastMap();
CompileDispatcher(); CompileDispatcher();
@ -354,8 +366,10 @@ void Reinitialize()
void Flush() void Flush()
{ {
ClearState(); ClearState();
#ifdef WITH_RECOMPILER
if (g_settings.IsUsingRecompiler()) if (g_settings.IsUsingRecompiler())
CompileDispatcher(); CompileDispatcher();
#endif
} }
void LogCurrentState() void LogCurrentState()
@ -437,7 +451,9 @@ bool RevalidateBlock(CodeBlock* block)
return true; return true;
recompile: recompile:
#ifdef WITH_RECOMPILER
RemoveBlockFromHostCodeMap(block); RemoveBlockFromHostCodeMap(block);
#endif
block->instructions.clear(); block->instructions.clear();
if (!CompileBlock(block)) if (!CompileBlock(block))
@ -447,8 +463,10 @@ recompile:
return false; return false;
} }
#ifdef WITH_RECOMPILER
// re-add to page map again // re-add to page map again
AddBlockToHostCodeMap(block); AddBlockToHostCodeMap(block);
#endif
if (block->IsInRAM()) if (block->IsInRAM())
AddBlockToPageMap(block); AddBlockToPageMap(block);
@ -713,6 +731,8 @@ void RemoveBlockFromHostCodeMap(CodeBlock* block)
s_host_code_map.erase(hc_iter); s_host_code_map.erase(hc_iter);
} }
#ifdef WITH_FASTMEM
bool InitializeFastmem() bool InitializeFastmem()
{ {
if (!Common::PageFaultHandler::InstallHandler(&s_host_code_map, PageFaultHandler)) if (!Common::PageFaultHandler::InstallHandler(&s_host_code_map, PageFaultHandler))
@ -801,6 +821,8 @@ Common::PageFaultHandler::HandlerResult PageFaultHandler(void* exception_pc, voi
return Common::PageFaultHandler::HandlerResult::ExecuteNextHandler; return Common::PageFaultHandler::HandlerResult::ExecuteNextHandler;
} }
#endif #endif // WITH_FASTMEM
#endif // WITH_RECOMPILER
} // namespace CPU::CodeCache } // namespace CPU::CodeCache

View file

@ -1600,11 +1600,15 @@ bool InterpretInstructionPGXP()
return g_state.exception_raised; return g_state.exception_raised;
} }
#ifdef WITH_FASTMEM
void UpdateFastmemMapping() void UpdateFastmemMapping()
{ {
Bus::UpdateFastmemViews(true, g_state.cop0_regs.sr.Isc); Bus::UpdateFastmemViews(true, g_state.cop0_regs.sr.Isc);
} }
#endif
} // namespace Recompiler::Thunks } // namespace Recompiler::Thunks
} // namespace CPU } // namespace CPU

View file

@ -2202,6 +2202,7 @@ bool CodeGenerator::Compile_cop0(const CodeBlockInstruction& cbi)
value = AndValues(value, Value::FromConstantU32(write_mask)); value = AndValues(value, Value::FromConstantU32(write_mask));
} }
#ifdef WITH_FASTMEM
// changing SR[Isc] needs to update fastmem views // changing SR[Isc] needs to update fastmem views
if (reg == Cop0Reg::SR && g_settings.cpu_fastmem) if (reg == Cop0Reg::SR && g_settings.cpu_fastmem)
{ {
@ -2211,13 +2212,18 @@ bool CodeGenerator::Compile_cop0(const CodeBlockInstruction& cbi)
EmitStoreCPUStructField(offset, value); EmitStoreCPUStructField(offset, value);
EmitXor(old_value.host_reg, old_value.host_reg, value); EmitXor(old_value.host_reg, old_value.host_reg, value);
EmitBranchIfBitClear(old_value.host_reg, RegSize_32, 16, &skip_fastmem_update); EmitBranchIfBitClear(old_value.host_reg, RegSize_32, 16, &skip_fastmem_update);
m_register_cache.InhibitAllocation();
EmitFunctionCall(nullptr, &Thunks::UpdateFastmemMapping, m_register_cache.GetCPUPtr()); EmitFunctionCall(nullptr, &Thunks::UpdateFastmemMapping, m_register_cache.GetCPUPtr());
EmitBindLabel(&skip_fastmem_update); EmitBindLabel(&skip_fastmem_update);
m_register_cache.UninhibitAllocation();
} }
else else
{ {
EmitStoreCPUStructField(offset, value); EmitStoreCPUStructField(offset, value);
} }
#else
EmitStoreCPUStructField(offset, value);
#endif
} }
} }

View file

@ -79,13 +79,17 @@ 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);
#ifdef WITH_FASTMEM
void EmitLoadGuestRAMFastmem(const Value& address, RegSize size, Value& result); 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);
#endif
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);
void EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const Value& address, const SpeculativeValue& address_spec, void EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const Value& address, const SpeculativeValue& address_spec,
const Value& value); const Value& value);
#ifdef WITH_FASTMEM
void EmitStoreGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, const Value& value); void EmitStoreGuestMemoryFastmem(const CodeBlockInstruction& cbi, const Value& address, const Value& value);
#endif
void EmitStoreGuestMemorySlowmem(const CodeBlockInstruction& cbi, const Value& address, const Value& value, void EmitStoreGuestMemorySlowmem(const CodeBlockInstruction& cbi, const Value& address, const Value& value,
bool in_far_code); bool in_far_code);

View file

@ -41,6 +41,8 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
{ {
Value result = m_register_cache.AllocateScratch(size); Value result = m_register_cache.AllocateScratch(size);
#ifdef WITH_FASTMEM
if (g_settings.IsUsingFastmem() && Bus::IsRAMAddress(static_cast<u32>(address.constant_value))) if (g_settings.IsUsingFastmem() && Bus::IsRAMAddress(static_cast<u32>(address.constant_value)))
{ {
// have to mask away the high bits for mirrors, since we don't map them in fastmem // have to mask away the high bits for mirrors, since we don't map them in fastmem
@ -52,6 +54,12 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
EmitLoadGlobal(result.GetHostRegister(), size, ptr); EmitLoadGlobal(result.GetHostRegister(), size, ptr);
} }
#else
EmitLoadGlobal(result.GetHostRegister(), size, ptr);
#endif
m_delayed_cycles_add += read_ticks; m_delayed_cycles_add += read_ticks;
return result; return result;
} }
@ -59,6 +67,8 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
AddPendingCycles(true); AddPendingCycles(true);
#ifdef WITH_FASTMEM
const bool use_fastmem = address_spec ? Bus::CanUseFastmemForAddress(*address_spec) : true; const bool use_fastmem = address_spec ? Bus::CanUseFastmemForAddress(*address_spec) : true;
if (address_spec) if (address_spec)
{ {
@ -83,7 +93,17 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
EmitLoadGuestMemorySlowmem(cbi, address, size, result, false); EmitLoadGuestMemorySlowmem(cbi, address, size, result, false);
} }
#else
Value result = m_register_cache.AllocateScratch(HostPointerSize);
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
EmitLoadGuestMemorySlowmem(cbi, address, size, result, false);
#endif
// Downcast to ignore upper 56/48/32 bits. This should be a noop. // Downcast to ignore upper 56/48/32 bits. This should be a noop.
if (result.size != size)
{
switch (size) switch (size)
{ {
case RegSize_8: case RegSize_8:
@ -102,6 +122,7 @@ Value CodeGenerator::EmitLoadGuestMemory(const CodeBlockInstruction& cbi, const
UnreachableCode(); UnreachableCode();
break; break;
} }
}
return result; return result;
} }
@ -124,6 +145,8 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
AddPendingCycles(true); AddPendingCycles(true);
#ifdef WITH_FASTMEM
const bool use_fastmem = address_spec ? Bus::CanUseFastmemForAddress(*address_spec) : true; const bool use_fastmem = address_spec ? Bus::CanUseFastmemForAddress(*address_spec) : true;
if (address_spec) if (address_spec)
{ {
@ -146,6 +169,13 @@ void CodeGenerator::EmitStoreGuestMemory(const CodeBlockInstruction& cbi, const
m_register_cache.FlushCallerSavedGuestRegisters(true, true); m_register_cache.FlushCallerSavedGuestRegisters(true, true);
EmitStoreGuestMemorySlowmem(cbi, address, value, false); EmitStoreGuestMemorySlowmem(cbi, address, value, false);
} }
#else
m_register_cache.FlushCallerSavedGuestRegisters(true, true);
EmitStoreGuestMemorySlowmem(cbi, address, value, false);
#endif
} }
#ifndef CPU_X64 #ifndef CPU_X64

View file

@ -32,8 +32,12 @@ void UncheckedWriteMemoryByte(u32 address, u8 value);
void UncheckedWriteMemoryHalfWord(u32 address, u16 value); void UncheckedWriteMemoryHalfWord(u32 address, u16 value);
void UncheckedWriteMemoryWord(u32 address, u32 value); void UncheckedWriteMemoryWord(u32 address, u32 value);
#ifdef WITH_FASTMEM
void UpdateFastmemMapping(); void UpdateFastmemMapping();
#endif
} // namespace Recompiler::Thunks } // namespace Recompiler::Thunks
} // namespace CPU } // namespace CPU