summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/DSPCore')
-rw-r--r--Source/Core/DSPCore/Src/DSPCore.cpp9
-rw-r--r--Source/Core/DSPCore/Src/DSPEmitter.cpp80
-rw-r--r--Source/Core/DSPCore/Src/DSPEmitter.h3
-rw-r--r--Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp8
4 files changed, 21 insertions, 79 deletions
diff --git a/Source/Core/DSPCore/Src/DSPCore.cpp b/Source/Core/DSPCore/Src/DSPCore.cpp
index 42da6410f9..46d9ee1f38 100644
--- a/Source/Core/DSPCore/Src/DSPCore.cpp
+++ b/Source/Core/DSPCore/Src/DSPCore.cpp
@@ -241,19 +241,14 @@ int DSPCore_RunCycles(int cycles)
{
if (jit)
{
- // DSPCore_CheckExceptions();
- // DSPCore_CheckExternalInterrupt();
cyclesLeft = cycles;
-
CompiledCode pExecAddr = (CompiledCode)jit->enterDispatcher;
pExecAddr();
-
- // To use the C++ dispatcher, uncomment the line below and comment out the two lines above
- //jit->RunForCycles(cyclesLeft);
return cyclesLeft;
}
- while (cycles > 0) {
+ while (cycles > 0)
+ {
reswitch:
switch (core_state)
{
diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp
index 2ec62b1cd4..e68fea7e18 100644
--- a/Source/Core/DSPCore/Src/DSPEmitter.cpp
+++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp
@@ -96,15 +96,10 @@ void DSPEmitter::checkExceptions(u32 retval)
#endif
DSPJitRegCache c(gpr);
-
SaveDSPRegs();
ABI_CallFunction((void *)&DSPCore_CheckExceptions);
-
- // ABI_RestoreStack(0);
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
MOV(32, R(EAX), Imm32(retval));
- RET();
-
+ JMP(returnDispatcher, true);
gpr.flushRegs(c,false);
SetJumpTarget(skipCheck);
@@ -201,8 +196,6 @@ void DSPEmitter::Compile(u16 start_addr)
unresolvedJumps[start_addr].clear();
const u8 *entryPoint = AlignCode16();
- ABI_PushAllCalleeSavedRegsAndAdjustStack();
- // ABI_AlignStack(0);
/*
// Check for other exceptions
@@ -276,7 +269,6 @@ void DSPEmitter::Compile(u16 start_addr)
DSPJitRegCache c(gpr);
HandleLoop();
SaveDSPRegs();
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP)
{
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
@@ -285,7 +277,7 @@ void DSPEmitter::Compile(u16 start_addr)
{
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
}
- RET();
+ JMP(returnDispatcher, true);
gpr.flushRegs(c,false);
SetJumpTarget(rLoopAddressExit);
@@ -315,7 +307,6 @@ void DSPEmitter::Compile(u16 start_addr)
DSPJitRegCache c(gpr);
//don't update g_dsp.pc -- the branch insn already did
SaveDSPRegs();
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP)
{
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
@@ -324,7 +315,7 @@ void DSPEmitter::Compile(u16 start_addr)
{
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
}
- RET();
+ JMP(returnDispatcher, true);
gpr.flushRegs(c,false);
SetJumpTarget(rNoBranch);
@@ -382,8 +373,6 @@ void DSPEmitter::Compile(u16 start_addr)
}
SaveDSPRegs();
-
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
if (DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP)
{
MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES));
@@ -392,18 +381,16 @@ void DSPEmitter::Compile(u16 start_addr)
{
MOV(16, R(EAX), Imm16(blockSize[start_addr]));
}
- RET();
+ JMP(returnDispatcher, true);
}
const u8 *DSPEmitter::CompileStub()
{
const u8 *entryPoint = AlignCode16();
- ABI_PushAllCalleeSavedRegsAndAdjustStack();
ABI_CallFunction((void *)&CompileCurrent);
- ABI_PopAllCalleeSavedRegsAndAdjustStack();
//MOVZX(32, 16, ECX, M(&g_dsp.pc));
XOR(32, R(EAX), R(EAX)); // Return 0 cycles executed
- RET();
+ JMP(returnDispatcher);
return entryPoint;
}
@@ -412,18 +399,6 @@ void DSPEmitter::CompileDispatcher()
enterDispatcher = AlignCode16();
ABI_PushAllCalleeSavedRegsAndAdjustStack();
- // Cache pointers into registers
-#ifdef _M_IX86
- MOV(16, R(ESI), M(&cyclesLeft));
- MOV(32, R(EBX), ImmPtr(blocks));
-#else
- // Using R12 here since it is callee save register on both
- // linux and windows 64.
- MOV(64, R(R12), ImmPtr(&cyclesLeft));
- MOV(16, R(R12), MatR(R12));
- MOV(64, R(RBX), ImmPtr(blocks));
-#endif
-
const u8 *dispatcherLoop = GetCodePtr();
// Check for DSP halt
@@ -444,16 +419,21 @@ void DSPEmitter::CompileDispatcher()
// Execute block. Cycles executed returned in EAX.
#ifdef _M_IX86
- CALLptr(MComplex(EBX, ECX, SCALE_4, 0));
+ MOV(32, R(EBX), ImmPtr(blocks));
+ JMPptr(MComplex(EBX, ECX, SCALE_4, 0));
#else
- CALLptr(MComplex(RBX, RCX, SCALE_8, 0));
+ MOV(64, R(RBX), ImmPtr(blocks));
+ JMPptr(MComplex(RBX, RCX, SCALE_8, 0));
#endif
+ returnDispatcher = GetCodePtr();
+
// Decrement cyclesLeft
#ifdef _M_IX86
- SUB(16, R(ESI), R(EAX));
+ SUB(16, M(&cyclesLeft), R(EAX));
#else
- SUB(16, R(R12), R(EAX));
+ MOV(64, R(R12), ImmPtr(&cyclesLeft));
+ SUB(16, MatR(R12), R(EAX));
#endif
J_CC(CC_A, dispatcherLoop);
@@ -464,35 +444,3 @@ void DSPEmitter::CompileDispatcher()
ABI_PopAllCalleeSavedRegsAndAdjustStack();
RET();
}
-
-// Don't use the % operator in the inner loop. It's slow.
-int STACKALIGN DSPEmitter::RunForCycles(int cycles)
-{
- while (!(g_dsp.cr & CR_HALT))
- {
- // Compile the block if needed
- u16 block_addr = g_dsp.pc;
- int block_size = blockSize[block_addr];
- if (!block_size)
- {
- CompileCurrent();
- block_size = blockSize[block_addr];
- }
-
- // Execute the block if we have enough cycles
- if (cycles > block_size)
- {
- cycles -= blocks[block_addr]();
- }
- else
- {
- break;
- }
- }
-
- // DSP gave up the remaining cycles.
- if (g_dsp.cr & CR_HALT || cycles < 0)
- return 0;
-
- return cycles;
-}
diff --git a/Source/Core/DSPCore/Src/DSPEmitter.h b/Source/Core/DSPCore/Src/DSPEmitter.h
index 401c89ae03..17f1850001 100644
--- a/Source/Core/DSPCore/Src/DSPEmitter.h
+++ b/Source/Core/DSPCore/Src/DSPEmitter.h
@@ -50,8 +50,6 @@ public:
void Default(UDSPInstruction inst);
- int STACKALIGN RunForCycles(int cycles);
-
// CC Util
void Update_SR_Register64(Gen::X64Reg val = Gen::EAX);
void Update_SR_Register64_Carry(Gen::X64Reg val = Gen::EAX);
@@ -253,6 +251,7 @@ public:
// CALL this to start the dispatcher
const u8 *enterDispatcher;
const u8 *stubEntryPoint;
+ const u8 *returnDispatcher;
u16 compilePC;
u16 startAddr;
Block *blockLinks;
diff --git a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp
index 56f5edcd9a..4dd2476e70 100644
--- a/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp
+++ b/Source/Core/DSPCore/Src/Jit/DSPJitBranch.cpp
@@ -122,7 +122,6 @@ static void ReJitConditional(const UDSPInstruction opc, DSPEmitter& emitter)
static void WriteBranchExit(DSPEmitter& emitter)
{
emitter.SaveDSPRegs();
- emitter.ABI_PopAllCalleeSavedRegsAndAdjustStack();
if (DSPAnalyzer::code_flags[emitter.startAddr] & DSPAnalyzer::CODE_IDLE_SKIP)
{
emitter.MOV(16, R(EAX), Imm16(0x1000));
@@ -131,7 +130,7 @@ static void WriteBranchExit(DSPEmitter& emitter)
{
emitter.MOV(16, R(EAX), Imm16(emitter.blockSize[emitter.startAddr]));
}
- emitter.RET();
+ emitter.JMP(emitter.returnDispatcher, true);
}
static void WriteBlockLink(DSPEmitter& emitter, u16 dest)
@@ -152,10 +151,11 @@ static void WriteBlockLink(DSPEmitter& emitter, u16 dest)
emitter.MOV(16, M(&cyclesLeft), R(ESI));
#else
// Check if we have enough cycles to execute the next block
- emitter.CMP(16, R(R12), Imm16(emitter.blockSize[emitter.startAddr] + emitter.blockSize[dest]));
+ emitter.MOV(64, R(R12), ImmPtr(&cyclesLeft));
+ emitter.CMP(16, MatR(R12), Imm16(emitter.blockSize[emitter.startAddr] + emitter.blockSize[dest]));
FixupBranch notEnoughCycles = emitter.J_CC(CC_BE);
- emitter.SUB(16, R(R12), Imm16(emitter.blockSize[emitter.startAddr]));
+ emitter.SUB(16, MatR(R12), Imm16(emitter.blockSize[emitter.startAddr]));
#endif
emitter.JMP(emitter.blockLinks[dest], true);
emitter.SetJumpTarget(notEnoughCycles);