From 9c1fb241c7b314fed444a828481b96bf608897d2 Mon Sep 17 00:00:00 2001 From: skidau Date: Sun, 28 Nov 2010 11:04:50 +0000 Subject: [PATCH] LLE JIT: Speed up the idle skip detection by moving the logic into the block and removing it from the dispatcher. This works because we can detect the idle skip blocks at compile time. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6488 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Core/Src/HW/DSP.cpp | 4 +- Source/Core/DSPCore/Src/DSPEmitter.cpp | 61 +++++++++++--------------- 2 files changed, 28 insertions(+), 37 deletions(-) diff --git a/Source/Core/Core/Src/HW/DSP.cpp b/Source/Core/Core/Src/HW/DSP.cpp index 71b338a9a6..3c4685be01 100644 --- a/Source/Core/Core/Src/HW/DSP.cpp +++ b/Source/Core/Core/Src/HW/DSP.cpp @@ -353,13 +353,13 @@ void Read16(u16& _uReturnValue, const u32 _iAddress) if (_iAddress != (0xCC000000 + DSP_MAIL_FROM_DSP_HI)) { - DEBUG_LOG(DSPINTERFACE, "DSPInterface(r16) 0x%08x (%02x) (%08x)", _iAddress, _uReturnValue, PowerPC::ppcState.pc); + DEBUG_LOG(DSPINTERFACE, "DSPInterface(r16) 0x%08x (0x%04x) (%08x)", _iAddress, _uReturnValue, PowerPC::ppcState.pc); } } void Write16(const u16 _Value, const u32 _Address) { - DEBUG_LOG(DSPINTERFACE, "DSPInterface(w16) 0x%04x 0x%08x", _Value, _Address); + DEBUG_LOG(DSPINTERFACE, "DSPInterface(w16) 0x%08x (0x%04x) (%08x)", _Address, _Value, PowerPC::ppcState.pc); switch (_Address & 0xFFFF) { diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp index d09800289e..113d3aea0e 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.cpp +++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp @@ -220,7 +220,14 @@ void DSPEmitter::Compile(int start_addr) ABI_CallFunction((void *)&DSPInterpreter::HandleLoop); // ABI_RestoreStack(0); ABI_PopAllCalleeSavedRegsAndAdjustStack(); - MOV(32,R(EAX),Imm32(blockSize[start_addr])); + if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + { + MOV(32,R(EAX),Imm32(DSP_IDLE_SKIP_CYCLES)); + } + else + { + MOV(32,R(EAX),Imm32(blockSize[start_addr])); + } RET(); SetJumpTarget(rLoopAddressExit); @@ -246,7 +253,14 @@ void DSPEmitter::Compile(int start_addr) // ABI_RestoreStack(0); ABI_PopAllCalleeSavedRegsAndAdjustStack(); - MOV(32,R(EAX),Imm32(blockSize[start_addr])); + if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + { + MOV(32,R(EAX),Imm32(DSP_IDLE_SKIP_CYCLES)); + } + else + { + MOV(32,R(EAX),Imm32(blockSize[start_addr])); + } RET(); SetJumpTarget(rNoBranch); @@ -271,7 +285,14 @@ void DSPEmitter::Compile(int start_addr) // ABI_RestoreStack(0); ABI_PopAllCalleeSavedRegsAndAdjustStack(); - MOV(32,R(EAX),Imm32(blockSize[start_addr])); + if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + { + MOV(32,R(EAX),Imm32(DSP_IDLE_SKIP_CYCLES)); + } + else + { + MOV(32,R(EAX),Imm32(blockSize[start_addr])); + } RET(); } @@ -311,25 +332,6 @@ void DSPEmitter::CompileDispatcher() CMP(32, R(ESI), R(EAX)); FixupBranch noCycles = J_CC(CC_B); - // Check for idle skip (C++ version below) - // if (code_flags[pc] & CODE_IDLE_SKIP) - // if (cycles > DSP_IDLE_SKIP_CYCLES) cycles -= DSP_IDLE_SKIP_CYCLES; - // else cycles = 0; -#ifdef _M_IX86 - MOV(32, R(EDX), Imm32((u32)DSPAnalyzer::code_flags)); -#else - MOV(64, R(RDX), Imm64((u64)DSPAnalyzer::code_flags)); -#endif - TEST(8, MComplex(RDX, ECX, SCALE_1, 0), Imm8(DSPAnalyzer::CODE_IDLE_SKIP)); - FixupBranch noIdleSkip = J_CC(CC_E); - SUB(32, R(ESI), Imm32(DSP_IDLE_SKIP_CYCLES)); - FixupBranch idleSkip = J_CC(CC_A); - //MOV(32, M(&cyclesLeft), Imm32(0)); - ABI_PopAllCalleeSavedRegsAndAdjustStack(); - RET(); - SetJumpTarget(idleSkip); - SetJumpTarget(noIdleSkip); - // Execute block. Cycles executed returned in EAX. #ifdef _M_IX86 CALLptr(MComplex(EBX, ECX, SCALE_4, 0)); @@ -374,18 +376,7 @@ int STACKALIGN DSPEmitter::RunForCycles(int cycles) // Execute the block if we have enough cycles if (cycles > block_size) { - 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 -= c; - } + cycles -= blocks[block_addr](); } else { @@ -394,7 +385,7 @@ int STACKALIGN DSPEmitter::RunForCycles(int cycles) } // DSP gave up the remaining cycles. - if (g_dsp.cr & CR_HALT) + if (g_dsp.cr & CR_HALT || cycles < 0) return 0; return cycles;