diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp index a9da27e405..27c636d6dc 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.cpp +++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp @@ -39,6 +39,7 @@ DSPEmitter::DSPEmitter() : storeIndex(-1), storeIndex2(-1) AllocCodeSpace(COMPILED_CODE_SIZE); blocks = new CompiledCode[MAX_BLOCKS]; + blockLinks = new CompiledCode[MAX_BLOCKS]; blockSize = new u16[0x10000]; compileSR = 0; @@ -52,6 +53,7 @@ DSPEmitter::DSPEmitter() : storeIndex(-1), storeIndex2(-1) for(int i = 0x0000; i < MAX_BLOCKS; i++) { blocks[i] = (CompiledCode)stubEntryPoint; + blockLinks[i] = 0; blockSize[i] = 0; } } @@ -59,6 +61,7 @@ DSPEmitter::DSPEmitter() : storeIndex(-1), storeIndex2(-1) DSPEmitter::~DSPEmitter() { delete[] blocks; + delete[] blockLinks; delete[] blockSize; FreeCodeSpace(); } @@ -68,6 +71,7 @@ void DSPEmitter::ClearIRAM() { for(int i = 0x0000; i < 0x1000; i++) { blocks[i] = (CompiledCode)stubEntryPoint; + blockLinks[i] = 0; blockSize[i] = 0; } } @@ -202,6 +206,9 @@ void DSPEmitter::Compile(int start_addr) if (g_dsp.exceptions == 0) return; */ + + blockLinkEntry = GetCodePtr(); + ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt); compilePC = start_addr; @@ -327,6 +334,7 @@ void DSPEmitter::Compile(int start_addr) } blocks[start_addr] = (CompiledCode)entryPoint; + blockLinks[start_addr] = (CompiledCode)blockLinkEntry; if (blockSize[start_addr] == 0) { // just a safeguard, should never happen anymore. diff --git a/Source/Core/DSPCore/Src/DSPEmitter.h b/Source/Core/DSPCore/Src/DSPEmitter.h index 017203e952..a5fb0f2f0c 100644 --- a/Source/Core/DSPCore/Src/DSPEmitter.h +++ b/Source/Core/DSPCore/Src/DSPEmitter.h @@ -156,9 +156,11 @@ public: // CALL this to start the dispatcher const u8 *enterDispatcher; u16 compilePC; + CompiledCode *blockLinks; private: CompiledCode *blocks; + const u8 *blockLinkEntry; u16 *blockSize; u16 compileSR; diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp index a588189824..ff1700ce65 100644 --- a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp +++ b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp @@ -139,9 +139,24 @@ void r_jcc(const UDSPInstruction opc, DSPEmitter& emitter) u16 dest = dsp_imem_read(emitter.compilePC + 1); #ifdef _M_IX86 // All32 emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest)); + + // Jump directly to the called block if it has already been compiled. + // TODO: Subtract cycles from cyclesLeft + if (emitter.blockLinks[dest]) + { + emitter.JMPptr(M(&emitter.blockLinks[dest])); + } #else emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc))); emitter.MOV(16, MDisp(RAX,0), Imm16(dest)); + + // Jump directly to the next block if it has already been compiled. + // TODO: Subtract cycles from cyclesLeft + if (emitter.blockLinks[dest]) + { + emitter.MOV(64, R(RAX), ImmPtr(emitter.blockLinks[dest])); + emitter.JMPptr(R(RAX)); + } #endif } // Generic jmp implementation @@ -190,9 +205,24 @@ void r_call(const UDSPInstruction opc, DSPEmitter& emitter) emitter.ABI_CallFunctionCC16((void *)dsp_reg_store_stack, DSP_STACK_C, emitter.compilePC + 2); #ifdef _M_IX86 // All32 emitter.MOV(16, M(&(g_dsp.pc)), Imm16(dest)); + + // Jump directly to the called block if it has already been compiled. + // TODO: Subtract cycles from cyclesLeft + if (emitter.blockLinks[dest]) + { + emitter.JMPptr(M(&emitter.blockLinks[dest])); + } #else emitter.MOV(64, R(RAX), ImmPtr(&(g_dsp.pc))); emitter.MOV(16, MDisp(RAX,0), Imm16(dest)); + + // Jump directly to the called block if it has already been compiled. + // TODO: Subtract cycles from cyclesLeft + if (emitter.blockLinks[dest]) + { + emitter.MOV(64, R(RAX), ImmPtr(emitter.blockLinks[dest])); + emitter.JMPptr(R(RAX)); + } #endif } // Generic call implementation