From 47eb5c3416780007318247757a688528df5141ea Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 14 Oct 2010 11:37:59 +0000 Subject: [PATCH] Core/DSPCore: Only check for internal exceptions in DSPEmitter::checkException, but call it for every instruction, like in DSPInterpreter::Step. Fix the analysis lookups for DSP_IDLE_SKIP and DSP_LOOP_END. After this patch, the block_size and the return value from the block always match, except when an internal exception is detected. This will change in a later patch, so we actually get some benefits from checking if we need to call HandleLoop(). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6280 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DSPCore/Src/DSPEmitter.cpp | 50 +++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp index 421b75ee1f..8347852c48 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.cpp +++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp @@ -71,24 +71,6 @@ void DSPEmitter::ClearIRAM() { // Must go out of block if exception is detected void DSPEmitter::checkExceptions(u32 retval) { - /* - // check if there is an external interrupt - if (! dsp_SR_is_flag_set(SR_EXT_INT_ENABLE)) - return; - - if (! (g_dsp.cr & CR_EXTERNAL_INT)) - return; - - g_dsp.cr &= ~CR_EXTERNAL_INT; - - // Check for other exceptions - if (dsp_SR_is_flag_set(SR_INT_ENABLE)) - return; - - if (g_dsp.exceptions == 0) - return; - */ - ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt); // Check for interrupts and exceptions #ifdef _M_IX86 // All32 TEST(8, M(&g_dsp.exceptions), Imm8(0xff)); @@ -167,11 +149,31 @@ const u8 *DSPEmitter::Compile(int start_addr) { ABI_PushAllCalleeSavedRegsAndAdjustStack(); // ABI_AlignStack(0); + /* + // check if there is an external interrupt + if (! dsp_SR_is_flag_set(SR_EXT_INT_ENABLE)) + return; + + if (! (g_dsp.cr & CR_EXTERNAL_INT)) + return; + + g_dsp.cr &= ~CR_EXTERNAL_INT; + + // Check for other exceptions + if (dsp_SR_is_flag_set(SR_INT_ENABLE)) + return; + + if (g_dsp.exceptions == 0) + return; + */ + ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt); + int addr = start_addr; blockSize[start_addr] = 0; - checkExceptions(blockSize[start_addr]); while (addr < start_addr + MAX_BLOCK_SIZE) { + checkExceptions(blockSize[start_addr]); + UDSPInstruction inst = dsp_imem_read(addr); const DSPOPCTemplate *opcode = GetOpTemplate(inst); @@ -187,12 +189,11 @@ const u8 *DSPEmitter::Compile(int start_addr) { EmitInstruction(inst); blockSize[start_addr]++; + addr += opcode->size; // Handle loop condition, only if current instruction was flagged as a loop destination - // by the analyzer. COMMENTED OUT - this breaks Zelda TP. Bah. - //probably just misses a +opcode->size-1 - - // if (DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_LOOP_END) + // by the analyzer. + if (DSPAnalyzer::code_flags[addr-1] & DSPAnalyzer::CODE_LOOP_END) { // TODO: Change to TEST for some reason (who added this comment?) #ifdef _M_IX86 // All32 @@ -226,11 +227,10 @@ const u8 *DSPEmitter::Compile(int start_addr) { // End the block if we're at a loop end. if (opcode->branch || - (DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_LOOP_END) || + (DSPAnalyzer::code_flags[addr-1] & DSPAnalyzer::CODE_LOOP_END) || (DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_IDLE_SKIP)) { break; } - addr += opcode->size; } blocks[start_addr] = (CompiledCode)entryPoint;