From 34909ecebc28c470c89ca2c33cd975c0af9635f4 Mon Sep 17 00:00:00 2001 From: pierre Date: Sat, 9 Oct 2010 21:43:57 +0000 Subject: [PATCH] Core/DSPCore: Make the JIT blocks return the number of cycles executed. The block_size seems to be not reliable, even after trying to more closely match the interpreter by looking at the analysis for (addr+opcode->size-1) for detecting the end of the block. Since we need to "calculate" this number shortly before returning to RunForCycles, it seemed logical to use the (up to now) unused return value of the blocks. Improves SMG2 here. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6266 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/DSPCore/Src/DSPEmitter.cpp | 29 +++++++++++++++----------- Source/Core/DSPCore/Src/DSPEmitter.h | 4 ++-- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp index 3f3edace5d..2b4a6ed2e8 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.cpp +++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp @@ -65,7 +65,7 @@ void DSPEmitter::ClearIRAM() { // Must go out of block if exception is detected -void DSPEmitter::checkExceptions() { +void DSPEmitter::checkExceptions(u32 retval) { /* // check if there is an external interrupt if (! dsp_SR_is_flag_set(SR_EXT_INT_ENABLE)) @@ -97,6 +97,7 @@ void DSPEmitter::checkExceptions() { // ABI_RestoreStack(0); ABI_PopAllCalleeSavedRegsAndAdjustStack(); + MOV(32,R(EAX),Imm32(retval)); RET(); SetJumpTarget(skipCheck); @@ -162,14 +163,15 @@ const u8 *DSPEmitter::Compile(int start_addr) { // ABI_AlignStack(0); int addr = start_addr; - checkExceptions(); blockSize[start_addr] = 0; + checkExceptions(blockSize[start_addr]); while (addr < start_addr + MAX_BLOCK_SIZE) { UDSPInstruction inst = dsp_imem_read(addr); const DSPOPCTemplate *opcode = GetOpTemplate(inst); - + // Increment PC - we shouldn't need to do this for every instruction. only for branches and end of block. + // fallbacks to interpreter need this for fetching immedate values #ifdef _M_IX86 // All32 ADD(16, M(&(g_dsp.pc)), Imm16(1)); #else @@ -178,9 +180,12 @@ const u8 *DSPEmitter::Compile(int start_addr) { #endif EmitInstruction(inst); - + + blockSize[start_addr]++; + // 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) { @@ -207,14 +212,13 @@ const u8 *DSPEmitter::Compile(int start_addr) { ABI_CallFunction((void *)&DSPInterpreter::HandleLoop); // ABI_RestoreStack(0); ABI_PopAllCalleeSavedRegsAndAdjustStack(); + MOV(32,R(EAX),Imm32(blockSize[start_addr])); RET(); SetJumpTarget(rLoopAddressExit); SetJumpTarget(rLoopCounterExit); } - blockSize[start_addr]++; - // End the block if we're at a loop end. if (opcode->branch || (DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_LOOP_END) || @@ -224,10 +228,6 @@ const u8 *DSPEmitter::Compile(int start_addr) { addr += opcode->size; } - // ABI_RestoreStack(0); - ABI_PopAllCalleeSavedRegsAndAdjustStack(); - RET(); - blocks[start_addr] = (CompiledCode)entryPoint; if (blockSize[start_addr] == 0) { @@ -237,6 +237,11 @@ const u8 *DSPEmitter::Compile(int start_addr) { blockSize[start_addr] = 1; } + // ABI_RestoreStack(0); + ABI_PopAllCalleeSavedRegsAndAdjustStack(); + MOV(32,R(EAX),Imm32(blockSize[start_addr])); + RET(); + return entryPoint; } @@ -273,14 +278,14 @@ int STACKALIGN DSPEmitter::RunForCycles(int cycles) // Execute the block if we have enough cycles if (cycles > block_size) { - blocks[block_addr](); + int c = blocks[block_addr](); if (DSPAnalyzer::code_flags[block_addr] & DSPAnalyzer::CODE_IDLE_SKIP) { if (cycles > idle_cycles) cycles -= idle_cycles; else cycles = 0; } else { - cycles -= block_size; + cycles -= c; } } else { diff --git a/Source/Core/DSPCore/Src/DSPEmitter.h b/Source/Core/DSPCore/Src/DSPEmitter.h index 2a9cc80c46..8ddd9aa368 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.h +++ b/Source/Core/DSPCore/Src/DSPEmitter.h @@ -25,7 +25,7 @@ #define MAX_BLOCKS 0x10000 -typedef void (*CompiledCode)(); +typedef u32 (*CompiledCode)(); class DSPEmitter : public Gen::XCodeBlock { @@ -49,7 +49,7 @@ public: // Register helpers void setCompileSR(u16 bit); void clrCompileSR(u16 bit); - void checkExceptions(); + void checkExceptions(u32 retval); // Memory helper functions void increment_addr_reg(int reg);