diff options
| author | skidau <skidau@gmail.com> | 2010-12-15 07:08:36 +0000 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2010-12-15 07:08:36 +0000 |
| commit | c584bd533383ca6ec1fec35ff0b0794d6c64fe5e (patch) | |
| tree | 5fa31678d91288884d684d5a25485207fb7ec0f3 /Source/Core | |
| parent | e61133625acb138ea73f6e801c7e263dc96544f7 (diff) | |
LLE JIT: Added simple block linking at immediate CALL's and JUMP's. The code checks if the block being jump to has already been compiled and jumps there if it has, bypassing the dispatcher. This results in a speed-up of around 7 - 10%.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6585 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/DSPCore/Src/DSPEmitter.cpp | 8 | ||||
| -rw-r--r-- | Source/Core/DSPCore/Src/DSPEmitter.h | 2 | ||||
| -rw-r--r-- | Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp | 30 |
3 files changed, 40 insertions, 0 deletions
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
|
