diff --git a/src/Cafe/HW/Espresso/Interpreter/PPCInterpreterHLE.cpp b/src/Cafe/HW/Espresso/Interpreter/PPCInterpreterHLE.cpp index 24219e66..cf7ba195 100644 --- a/src/Cafe/HW/Espresso/Interpreter/PPCInterpreterHLE.cpp +++ b/src/Cafe/HW/Espresso/Interpreter/PPCInterpreterHLE.cpp @@ -2,62 +2,70 @@ #include "PPCInterpreterInternal.h" #include "PPCInterpreterHelper.h" -std::unordered_set sUnsupportedHLECalls; +std::unordered_set s_unsupportedHLECalls; void PPCInterpreter_handleUnsupportedHLECall(PPCInterpreter_t* hCPU) { const char* libFuncName = (char*)memory_getPointerFromVirtualOffset(hCPU->instructionPointer + 8); std::string tempString = fmt::format("Unsupported lib call: {}", libFuncName); - if (sUnsupportedHLECalls.find(tempString) == sUnsupportedHLECalls.end()) + if (s_unsupportedHLECalls.find(tempString) == s_unsupportedHLECalls.end()) { cemuLog_log(LogType::UnsupportedAPI, "{}", tempString); - sUnsupportedHLECalls.emplace(tempString); + s_unsupportedHLECalls.emplace(tempString); } hCPU->gpr[3] = 0; PPCInterpreter_nextInstruction(hCPU); } -std::vector* sPPCHLETable{}; +static constexpr size_t HLE_TABLE_CAPACITY = 0x4000; +HLECALL s_ppcHleTable[HLE_TABLE_CAPACITY]{}; +sint32 s_ppcHleTableWriteIndex = 0; +std::mutex s_ppcHleTableMutex; HLEIDX PPCInterpreter_registerHLECall(HLECALL hleCall, std::string hleName) { - if (!sPPCHLETable) - sPPCHLETable = new std::vector(); - for (sint32 i = 0; i < sPPCHLETable->size(); i++) + std::unique_lock _l(s_ppcHleTableMutex); + if (s_ppcHleTableWriteIndex >= HLE_TABLE_CAPACITY) { - if ((*sPPCHLETable)[i] == hleCall) - return i; + cemuLog_log(LogType::Force, "HLE table is full"); + cemu_assert(false); } - HLEIDX newFuncIndex = (sint32)sPPCHLETable->size(); - sPPCHLETable->resize(sPPCHLETable->size() + 1); - (*sPPCHLETable)[newFuncIndex] = hleCall; - return newFuncIndex; + for (sint32 i = 0; i < s_ppcHleTableWriteIndex; i++) + { + if (s_ppcHleTable[i] == hleCall) + { + return i; + } + } + cemu_assert(s_ppcHleTableWriteIndex < HLE_TABLE_CAPACITY); + s_ppcHleTable[s_ppcHleTableWriteIndex] = hleCall; + HLEIDX funcIndex = s_ppcHleTableWriteIndex; + s_ppcHleTableWriteIndex++; + return funcIndex; } HLECALL PPCInterpreter_getHLECall(HLEIDX funcIndex) { - if (funcIndex < 0 || funcIndex >= sPPCHLETable->size()) + if (funcIndex < 0 || funcIndex >= HLE_TABLE_CAPACITY) return nullptr; - return sPPCHLETable->data()[funcIndex]; + return s_ppcHleTable[funcIndex]; } -std::mutex g_hleLogMutex; +std::mutex s_hleLogMutex; void PPCInterpreter_virtualHLE(PPCInterpreter_t* hCPU, unsigned int opcode) { uint32 hleFuncId = opcode & 0xFFFF; - if (hleFuncId == 0xFFD0) + if (hleFuncId == 0xFFD0) [[unlikely]] { - g_hleLogMutex.lock(); + s_hleLogMutex.lock(); PPCInterpreter_handleUnsupportedHLECall(hCPU); - g_hleLogMutex.unlock(); - return; + s_hleLogMutex.unlock(); } else { // os lib function - cemu_assert(hleFuncId < sPPCHLETable->size()); - auto hleCall = (*sPPCHLETable)[hleFuncId]; + auto hleCall = PPCInterpreter_getHLECall(hleFuncId); cemu_assert(hleCall); hleCall(hCPU); } diff --git a/src/Cafe/HW/Espresso/PPCState.h b/src/Cafe/HW/Espresso/PPCState.h index 179e2687..fd943d39 100644 --- a/src/Cafe/HW/Espresso/PPCState.h +++ b/src/Cafe/HW/Espresso/PPCState.h @@ -230,9 +230,9 @@ static inline float flushDenormalToZero(float f) // HLE interface -typedef void(*HLECALL)(PPCInterpreter_t* hCPU); +using HLECALL = void(*)(PPCInterpreter_t*); +using HLEIDX = sint32; -typedef sint32 HLEIDX; HLEIDX PPCInterpreter_registerHLECall(HLECALL hleCall, std::string hleName); HLECALL PPCInterpreter_getHLECall(HLEIDX funcIndex);