summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2011-01-03 14:19:11 +0000
committerskidau <skidau@gmail.com>2011-01-03 14:19:11 +0000
commitae71e63872dac1e8cfedccfc3529b86e67439270 (patch)
tree8217f34f177f6d9b59237981c9eecca738316f88 /Source/Core/DSPCore
parenta6637c257f3bdaa740b19ba4590ae42a3d45f62b (diff)
LLE JIT: Minimised exception checking. Instructions which need to check for exceptions are now marked in the analyser. Moved the checking for external interrupts to the point where the CPU writes to the control register.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6729 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DSPCore')
-rw-r--r--Source/Core/DSPCore/Src/DSPAnalyzer.cpp12
-rw-r--r--Source/Core/DSPCore/Src/DSPAnalyzer.h1
-rw-r--r--Source/Core/DSPCore/Src/DSPEmitter.cpp31
3 files changed, 15 insertions, 29 deletions
diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
index b4300867ac..8f6b0d4e35 100644
--- a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
+++ b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
@@ -123,6 +123,18 @@ void AnalyzeRange(int start_addr, int end_addr)
code_flags[last_arithmetic] |= CODE_UPDATE_SR;
}
+ // If an instruction potentially raises exceptions, mark the following
+ // instruction as needing to check for exceptions
+ if (opcode->opcode == 0x00c0 ||
+ opcode->opcode == 0x1800 ||
+ opcode->opcode == 0x1880 ||
+ opcode->opcode == 0x1900 ||
+ opcode->opcode == 0x1980 ||
+ opcode->opcode == 0x2000 ||
+ opcode->extended
+ )
+ code_flags[addr + opcode->size] |= CODE_CHECK_INT;
+
addr += opcode->size;
}
diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.h b/Source/Core/DSPCore/Src/DSPAnalyzer.h
index aeb3b9e480..9c05dae708 100644
--- a/Source/Core/DSPCore/Src/DSPAnalyzer.h
+++ b/Source/Core/DSPCore/Src/DSPAnalyzer.h
@@ -33,6 +33,7 @@ enum
CODE_LOOP_START = 4,
CODE_LOOP_END = 8,
CODE_UPDATE_SR = 16,
+ CODE_CHECK_INT = 32,
};
// Easy to query array covering the whole of instruction memory.
diff --git a/Source/Core/DSPCore/Src/DSPEmitter.cpp b/Source/Core/DSPCore/Src/DSPEmitter.cpp
index 5835196a60..8d36465ee8 100644
--- a/Source/Core/DSPCore/Src/DSPEmitter.cpp
+++ b/Source/Core/DSPCore/Src/DSPEmitter.cpp
@@ -210,34 +210,6 @@ void DSPEmitter::Compile(u16 start_addr)
blockLinkEntry = GetCodePtr();
-// ASM version of DSPCore_CheckExternalInterrupt.
-#ifdef _M_IX86 // All32
- TEST(16, M(&g_dsp.cr), Imm16(CR_EXTERNAL_INT));
- FixupBranch noExternalInterrupt = J_CC(CC_Z);
- TEST(16, M(&g_dsp.r.sr), Imm16(SR_EXT_INT_ENABLE));
- FixupBranch externalInterruptDisabled = J_CC(CC_Z);
- OR(8, M(&g_dsp.exceptions), Imm8(1 << EXP_INT));
- AND(16, M(&g_dsp.cr), Imm16(~CR_EXTERNAL_INT));
- SetJumpTarget(externalInterruptDisabled);
- SetJumpTarget(noExternalInterrupt);
-#else
- /* // TODO: Needs to be optimised
- MOV(64, R(RAX), ImmPtr(&g_dsp.cr));
- TEST(16, MatR(RAX), Imm16(CR_EXTERNAL_INT));
- FixupBranch noExternalInterrupt = J_CC(CC_Z);
- MOV(64, R(RAX), ImmPtr(&g_dsp.r.sr));
- TEST(16, MatR(RAX), Imm16(SR_EXT_INT_ENABLE));
- FixupBranch externalInterruptDisabled = J_CC(CC_Z);
- MOV(64, R(RAX), ImmPtr(&g_dsp.exceptions));
- OR(8, MatR(RAX), Imm8(1 << EXP_INT));
- MOV(64, R(RAX), ImmPtr(&g_dsp.cr));
- AND(16, MatR(RAX), Imm16(~CR_EXTERNAL_INT));
- SetJumpTarget(externalInterruptDisabled);
- SetJumpTarget(noExternalInterrupt);
- */
- ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt);
-#endif
-
compilePC = start_addr;
bool fixup_pc = false;
blockSize[start_addr] = 0;
@@ -246,7 +218,8 @@ void DSPEmitter::Compile(u16 start_addr)
while (compilePC < start_addr + MAX_BLOCK_SIZE)
{
- checkExceptions(blockSize[start_addr]);
+ if (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_CHECK_INT)
+ checkExceptions(blockSize[start_addr]);
UDSPInstruction inst = dsp_imem_read(compilePC);
const DSPOPCTemplate *opcode = GetOpTemplate(inst);