From cdec575bef6bc03a5934ef1928abdbff013df482 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 9 May 2014 09:10:45 -0500 Subject: [PATCH] Fixes games that use the MMU to page in code(Rogue Leader). The issue was that on memory exception we wouldn't call in to PPCAnalyst and our code_block would retain the previous blocks information. This would cause us to compile the previous blocks instructions in prior to the exception exit. --- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 24 ++------------------- Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp | 23 ++------------------ Source/Core/Core/PowerPC/JitArm32/Jit.cpp | 17 +++------------ Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp | 17 ++------------- Source/Core/Core/PowerPC/PPCAnalyst.cpp | 20 ++++++++++++++++- Source/Core/Core/PowerPC/PPCAnalyst.h | 3 +++ 6 files changed, 31 insertions(+), 73 deletions(-) diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 9c2284e2d4..2ad723d1f5 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -406,9 +406,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { int blockSize = code_buf->GetSize(); - // Memory exception on instruction fetch - bool memory_exception = false; - if (Core::g_CoreStartupParameter.bEnableDebugging) { // Comment out the following to disable breakpoints (speed-up) @@ -420,21 +417,6 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } } - if (em_address == 0) - { - // Memory exception occurred during instruction fetch - memory_exception = true; - } - - if (Core::g_CoreStartupParameter.bMMU && (em_address & JIT_ICACHE_VMEM_BIT)) - { - if (!Memory::TranslateAddress(em_address, Memory::FLAG_OPCODE)) - { - // Memory exception occurred during instruction fetch - memory_exception = true; - } - } - js.firstFPInstructionFound = false; js.isLastInstruction = false; js.blockStart = em_address; @@ -448,9 +430,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc u32 nextPC = em_address; // 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. - if (!memory_exception) - nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); - + nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -678,7 +658,7 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } } - if (memory_exception) + if (code_block.m_memory_exception) { // Address of instruction could not be translated MOV(32, M(&NPC), Imm32(js.compilerPC)); diff --git a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp index b686cbc514..404398c898 100644 --- a/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/PowerPC/Jit64IL/JitIL.cpp @@ -501,9 +501,6 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { int blockSize = code_buf->GetSize(); - // Memory exception on instruction fetch - bool memory_exception = false; - if (Core::g_CoreStartupParameter.bEnableDebugging) { // Comment out the following to disable breakpoints (speed-up) @@ -515,21 +512,6 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } } - if (em_address == 0) - { - // Memory exception occurred during instruction fetch - memory_exception = true; - } - - if (Core::g_CoreStartupParameter.bMMU && (em_address & JIT_ICACHE_VMEM_BIT)) - { - if (!Memory::TranslateAddress(em_address, Memory::FLAG_OPCODE)) - { - // Memory exception occurred during instruction fetch - memory_exception = true; - } - } - js.isLastInstruction = false; js.blockStart = em_address; js.fifoBytesThisBlock = 0; @@ -541,8 +523,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc u32 nextPC = em_address; // 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. - if (!memory_exception) - nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); + nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -689,7 +670,7 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc } } - if (memory_exception) + if (code_block.m_memory_exception) { ibuild.EmitISIException(ibuild.EmitIntConst(em_address)); } diff --git a/Source/Core/Core/PowerPC/JitArm32/Jit.cpp b/Source/Core/Core/PowerPC/JitArm32/Jit.cpp index c08e1809be..820cace463 100644 --- a/Source/Core/Core/PowerPC/JitArm32/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm32/Jit.cpp @@ -300,8 +300,6 @@ void JitArm::Break(UGeckoInstruction inst) const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b) { int blockSize = code_buf->GetSize(); - // Memory exception on instruction fetch - bool memory_exception = false; if (Core::g_CoreStartupParameter.bEnableDebugging) { @@ -316,15 +314,6 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo PanicAlert("ERROR: Compiling at 0. LR=%08x CTR=%08x", LR, CTR); } - if (Core::g_CoreStartupParameter.bMMU && (em_address & JIT_ICACHE_VMEM_BIT)) - { - if (!Memory::TranslateAddress(em_address, Memory::FLAG_OPCODE)) - { - // Memory exception occurred during instruction fetch - memory_exception = true; - } - } - js.isLastInstruction = false; js.blockStart = em_address; js.fifoBytesThisBlock = 0; @@ -335,8 +324,7 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo u32 nextPC = em_address; // 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. - if (!memory_exception) - nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); + nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -478,8 +466,9 @@ const u8* JitArm::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlo } } } - if (memory_exception) + if (code_block.m_memory_exception) BKPT(0x500); + if (code_block.m_broken) { printf("Broken Block going to 0x%08x\n", nextPC); diff --git a/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp b/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp index 2c5baf33bb..9b8785111e 100644 --- a/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp +++ b/Source/Core/Core/PowerPC/JitArmIL/JitIL.cpp @@ -203,8 +203,6 @@ void STACKALIGN JitArmIL::Jit(u32 em_address) const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBlock *b) { int blockSize = code_buf->GetSize(); - // Memory exception on instruction fetch - bool memory_exception = false; if (Core::g_CoreStartupParameter.bEnableDebugging) { @@ -218,16 +216,6 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB PanicAlert("ERROR: Compiling at 0. LR=%08x CTR=%08x", LR, CTR); } - if (Core::g_CoreStartupParameter.bMMU && (em_address & JIT_ICACHE_VMEM_BIT)) - { - if (!Memory::TranslateAddress(em_address, Memory::FLAG_OPCODE)) - { - // Memory exception occurred during instruction fetch - memory_exception = true; - } - } - - js.isLastInstruction = false; js.blockStart = em_address; js.fifoBytesThisBlock = 0; @@ -238,8 +226,7 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB u32 nextPC = em_address; // 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. - if (!memory_exception) - nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); + nextPC = analyzer.Analyze(em_address, &code_block, code_buf, blockSize); PPCAnalyst::CodeOp *ops = code_buf->codebuffer; @@ -334,7 +321,7 @@ const u8* JitArmIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitB } } } - if (memory_exception) + if (code_block.m_memory_exception) BKPT(0x500); if (code_block.m_broken) diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.cpp b/Source/Core/Core/PowerPC/PPCAnalyst.cpp index edf1425299..040f9fe25a 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.cpp +++ b/Source/Core/Core/PowerPC/PPCAnalyst.cpp @@ -15,7 +15,7 @@ #include "Core/PowerPC/PPCSymbolDB.h" #include "Core/PowerPC/PPCTables.h" #include "Core/PowerPC/SignatureDB.h" -#include "Core/PowerPC/Interpreter/Interpreter.h" +#include "Core/PowerPC/JitCommon/JitCache.h" // Analyzes PowerPC code in memory to find functions // After running, for each function we will know what functions it calls @@ -543,8 +543,26 @@ u32 PPCAnalyzer::Analyze(u32 address, CodeBlock *block, CodeBuffer *buffer, u32 // Reset our block state block->m_broken = false; + block->m_memory_exception = false; block->m_num_instructions = 0; + if (address == 0) + { + // Memory exception occurred during instruction fetch + block->m_memory_exception = true; + return address; + } + + if (Core::g_CoreStartupParameter.bMMU && (address & JIT_ICACHE_VMEM_BIT)) + { + if (!Memory::TranslateAddress(address, Memory::FLAG_OPCODE)) + { + // Memory exception occurred during instruction fetch + block->m_memory_exception = true; + return address; + } + } + CodeOp *code = buffer->codebuffer; bool found_exit = false; diff --git a/Source/Core/Core/PowerPC/PPCAnalyst.h b/Source/Core/Core/PowerPC/PPCAnalyst.h index 16c4f2cd14..f2b6ec7afa 100644 --- a/Source/Core/Core/PowerPC/PPCAnalyst.h +++ b/Source/Core/Core/PowerPC/PPCAnalyst.h @@ -124,6 +124,9 @@ struct CodeBlock // Are we a broken block? bool m_broken; + + // Did we have a memory_exception? + bool m_memory_exception; }; class PPCAnalyzer