From 610cced4931c8045c46bf026dea0d0591b659add Mon Sep 17 00:00:00 2001 From: SSimco <37044560+SSimco@users.noreply.github.com> Date: Fri, 16 Feb 2024 22:50:07 +0200 Subject: [PATCH] Recompiler fix --- .../HW/Espresso/Recompiler/PPCRecompiler.cpp | 23 +++++++++++++++++-- .../HW/Espresso/Recompiler/PPCRecompiler.h | 2 ++ src/config/ActiveSettings.cpp | 4 ---- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.cpp b/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.cpp index b15ae77d..9e507053 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.cpp +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.cpp @@ -21,6 +21,16 @@ #include "BackendAArch64/BackendAArch64.h" #endif +std::bitset ppcRecompilerDirectJumpTableInitialized; +void ppcRecompilerDirectJumpTableUpdateInitialzed(int position) +{ + ppcRecompilerDirectJumpTableInitialized.set(position); +} +bool isppcRecompilerDirectJumpTableUpdateInitialzed(int position) +{ + return ppcRecompilerDirectJumpTableInitialized.test(position); +} + struct PPCInvalidationRange { MPTR startAddress; @@ -45,10 +55,12 @@ void ATTR_MS_ABI (*PPCRecompiler_leaveRecompilerCode_unvisited)(); PPCRecompilerInstanceData_t* ppcRecompilerInstanceData; bool ppcRecompilerEnabled = false; - // this function does never block and can fail if the recompiler lock cannot be acquired immediately void PPCRecompiler_visitAddressNoBlock(uint32 enterAddress) { + if(!isppcRecompilerDirectJumpTableUpdateInitialzed(enterAddress/4)) + return; + // quick read-only check without lock if (ppcRecompilerInstanceData->ppcRecompilerDirectJumpTable[enterAddress / 4] != PPCRecompiler_leaveRecompilerCode_unvisited) return; @@ -107,6 +119,9 @@ void PPCRecompiler_attemptEnterWithoutRecompile(PPCInterpreter_t* hCPU, uint32 e cemu_assert_debug(hCPU->instructionPointer == enterAddress); if (ppcRecompilerEnabled == false) return; + if(!isppcRecompilerDirectJumpTableUpdateInitialzed(enterAddress/4)) + return; + auto funcPtr = ppcRecompilerInstanceData->ppcRecompilerDirectJumpTable[enterAddress / 4]; if (funcPtr != PPCRecompiler_leaveRecompilerCode_unvisited && funcPtr != PPCRecompiler_leaveRecompilerCode_visited) { @@ -122,6 +137,9 @@ void PPCRecompiler_attemptEnter(PPCInterpreter_t* hCPU, uint32 enterAddress) return; if (hCPU->remainingCycles <= 0) return; + if(!isppcRecompilerDirectJumpTableUpdateInitialzed(enterAddress/4)) + return; + auto funcPtr = ppcRecompilerInstanceData->ppcRecompilerDirectJumpTable[enterAddress / 4]; if (funcPtr == PPCRecompiler_leaveRecompilerCode_unvisited) { @@ -487,9 +505,9 @@ void PPCRecompiler_reserveLookupTableBlock(uint32 offset) if (ppcRecompiler_reservedBlockMask[blockIndex]) return; ppcRecompiler_reservedBlockMask[blockIndex] = true; - void* p1 = MemMapper::AllocateMemory(&(ppcRecompilerInstanceData->ppcRecompilerFuncTable[offset/4]), (PPC_REC_ALLOC_BLOCK_SIZE/4)*sizeof(void*), MemMapper::PAGE_PERMISSION::P_RW, true); void* p3 = MemMapper::AllocateMemory(&(ppcRecompilerInstanceData->ppcRecompilerDirectJumpTable[offset/4]), (PPC_REC_ALLOC_BLOCK_SIZE/4)*sizeof(void*), MemMapper::PAGE_PERMISSION::P_RW, true); + ppcRecompilerDirectJumpTableUpdateInitialzed(offset/4); if( !p1 || !p3 ) { cemuLog_log(LogType::Force, "Failed to allocate memory for recompiler (0x{:08x})", offset); @@ -499,6 +517,7 @@ void PPCRecompiler_reserveLookupTableBlock(uint32 offset) for(uint32 i=0; ippcRecompilerDirectJumpTable[offset/4+i] = PPCRecompiler_leaveRecompilerCode_unvisited; + ppcRecompilerDirectJumpTableUpdateInitialzed(offset/4+1); } } diff --git a/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h b/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h index 080ce2fa..189fbe8d 100644 --- a/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h +++ b/src/Cafe/HW/Espresso/Recompiler/PPCRecompiler.h @@ -1,5 +1,7 @@ #pragma once +#include +#include #define PPC_REC_CODE_AREA_START (0x00000000) // lower bound of executable memory area. Recompiler expects this address to be 0 #define PPC_REC_CODE_AREA_END (0x10000000) // upper bound of executable memory area #define PPC_REC_CODE_AREA_SIZE (PPC_REC_CODE_AREA_END - PPC_REC_CODE_AREA_START) diff --git a/src/config/ActiveSettings.cpp b/src/config/ActiveSettings.cpp index a9da11da..2049bd65 100644 --- a/src/config/ActiveSettings.cpp +++ b/src/config/ActiveSettings.cpp @@ -65,9 +65,6 @@ bool ActiveSettings::FullscreenEnabled() CPUMode ActiveSettings::GetCPUMode() { -#ifndef ARCH_X86_64 - return CPUMode::SinglecoreRecompiler; -#else auto mode = g_current_game_profile->GetCPUMode().value_or(CPUMode::Auto); if (mode == CPUMode::Auto) @@ -81,7 +78,6 @@ CPUMode ActiveSettings::GetCPUMode() mode = CPUMode::MulticoreRecompiler; return mode; -#endif } uint8 ActiveSettings::GetTimerShiftFactor()