diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index d3baf4edd7..e7d4ed3c43 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -437,10 +437,11 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc //Analyze the block, collect all instructions it is made of (including inlining, //if that is enabled), reorder instructions for optimal performance, and join joinable instructions. u32 nextPC = em_address; + std::vector merged_addresses; if (!memory_exception) { // If there is a memory exception inside a block (broken_block==true), compile up to that instruction. - nextPC = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize); + nextPC = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses); } PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -496,7 +497,13 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc js.downcountAmount = 0; if (!Core::g_CoreStartupParameter.bEnableDebugging) - js.downcountAmount += PatchEngine::GetSpeedhackCycles(em_address); + { + for (int i = 0; i < merged_addresses.size(); ++i) + { + const u32 address = merged_addresses[i]; + js.downcountAmount += PatchEngine::GetSpeedhackCycles(address); + } + } js.skipnext = false; js.blockSize = size; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index 42b82a532e..da0f5eb51b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -429,10 +429,11 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc //Analyze the block, collect all instructions it is made of (including inlining, //if that is enabled), reorder instructions for optimal performance, and join joinable instructions. b->exitAddress[0] = em_address; + std::vector merged_addresses; if (!memory_exception) { // If there is a memory exception inside a block (broken_block==true), compile up to that instruction. - b->exitAddress[0] = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize); + b->exitAddress[0] = PPCAnalyst::Flatten(em_address, &size, &js.st, &js.gpa, &js.fpa, broken_block, code_buf, blockSize, merged_addresses); } PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -468,10 +469,15 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc // instruction processed by the JIT routines) ibuild.Reset(); - js.downcountAmount = 0; if (!Core::g_CoreStartupParameter.bEnableDebugging) - js.downcountAmount += PatchEngine::GetSpeedhackCycles(em_address); + { + for (int i = 0; i < merged_addresses.size(); ++i) + { + const u32 address = merged_addresses[i]; + js.downcountAmount += PatchEngine::GetSpeedhackCycles(address); + } + } // Translate instructions for (int i = 0; i < (int)size; i++) diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp index ccc9472333..56276507f2 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.cpp @@ -285,8 +285,9 @@ bool CanSwapAdjacentOps(const CodeOp &a, const CodeOp &b) // Does not yet perform inlining - although there are plans for that. // Returns the exit address of the next PC -u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, bool &broken_block, CodeBuffer *buffer, int blockSize) +u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, bool &broken_block, CodeBuffer *buffer, int blockSize, std::vector& merged_addresses) { + merged_addresses.push_back(address); memset(st, 0, sizeof(st)); // Disabled the following optimization in preference of FAST_ICACHE @@ -474,6 +475,7 @@ u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, Bloc // because bx may store a certain value to the link register. // Instead, we skip a part of bx in Jit**::bx(). address = destination; + merged_addresses.push_back(address); } } else diff --git a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h index 174b0ec128..3eecc263c9 100644 --- a/Source/Core/Core/Src/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/Src/PowerPC/PPCAnalyst.h @@ -108,7 +108,7 @@ public: }; -u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, bool &broken_block, CodeBuffer *buffer, int blockSize); +u32 Flatten(u32 address, int *realsize, BlockStats *st, BlockRegStats *gpa, BlockRegStats *fpa, bool &broken_block, CodeBuffer *buffer, int blockSize, std::vector& merged_addresses); void LogFunctionCall(u32 addr); void FindFunctions(u32 startAddr, u32 endAddr, PPCSymbolDB *func_db); bool AnalyzeFunction(u32 startAddr, Symbol &func, int max_size = 0);