Core/DSPCore: Only check for internal exceptions in DSPEmitter::checkException, but
call it for every instruction, like in DSPInterpreter::Step. Fix the analysis lookups for DSP_IDLE_SKIP and DSP_LOOP_END. After this patch, the block_size and the return value from the block always match, except when an internal exception is detected. This will change in a later patch, so we actually get some benefits from checking if we need to call HandleLoop(). git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6280 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
6e6a0be8c4
commit
47eb5c3416
|
@ -71,24 +71,6 @@ void DSPEmitter::ClearIRAM() {
|
|||
|
||||
// Must go out of block if exception is detected
|
||||
void DSPEmitter::checkExceptions(u32 retval) {
|
||||
/*
|
||||
// check if there is an external interrupt
|
||||
if (! dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
|
||||
return;
|
||||
|
||||
if (! (g_dsp.cr & CR_EXTERNAL_INT))
|
||||
return;
|
||||
|
||||
g_dsp.cr &= ~CR_EXTERNAL_INT;
|
||||
|
||||
// Check for other exceptions
|
||||
if (dsp_SR_is_flag_set(SR_INT_ENABLE))
|
||||
return;
|
||||
|
||||
if (g_dsp.exceptions == 0)
|
||||
return;
|
||||
*/
|
||||
ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt);
|
||||
// Check for interrupts and exceptions
|
||||
#ifdef _M_IX86 // All32
|
||||
TEST(8, M(&g_dsp.exceptions), Imm8(0xff));
|
||||
|
@ -167,11 +149,31 @@ const u8 *DSPEmitter::Compile(int start_addr) {
|
|||
ABI_PushAllCalleeSavedRegsAndAdjustStack();
|
||||
// ABI_AlignStack(0);
|
||||
|
||||
/*
|
||||
// check if there is an external interrupt
|
||||
if (! dsp_SR_is_flag_set(SR_EXT_INT_ENABLE))
|
||||
return;
|
||||
|
||||
if (! (g_dsp.cr & CR_EXTERNAL_INT))
|
||||
return;
|
||||
|
||||
g_dsp.cr &= ~CR_EXTERNAL_INT;
|
||||
|
||||
// Check for other exceptions
|
||||
if (dsp_SR_is_flag_set(SR_INT_ENABLE))
|
||||
return;
|
||||
|
||||
if (g_dsp.exceptions == 0)
|
||||
return;
|
||||
*/
|
||||
ABI_CallFunction((void *)&DSPCore_CheckExternalInterrupt);
|
||||
|
||||
int addr = start_addr;
|
||||
blockSize[start_addr] = 0;
|
||||
checkExceptions(blockSize[start_addr]);
|
||||
while (addr < start_addr + MAX_BLOCK_SIZE)
|
||||
{
|
||||
checkExceptions(blockSize[start_addr]);
|
||||
|
||||
UDSPInstruction inst = dsp_imem_read(addr);
|
||||
const DSPOPCTemplate *opcode = GetOpTemplate(inst);
|
||||
|
||||
|
@ -187,12 +189,11 @@ const u8 *DSPEmitter::Compile(int start_addr) {
|
|||
EmitInstruction(inst);
|
||||
|
||||
blockSize[start_addr]++;
|
||||
addr += opcode->size;
|
||||
|
||||
// Handle loop condition, only if current instruction was flagged as a loop destination
|
||||
// by the analyzer. COMMENTED OUT - this breaks Zelda TP. Bah.
|
||||
//probably just misses a +opcode->size-1
|
||||
|
||||
// if (DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_LOOP_END)
|
||||
// by the analyzer.
|
||||
if (DSPAnalyzer::code_flags[addr-1] & DSPAnalyzer::CODE_LOOP_END)
|
||||
{
|
||||
// TODO: Change to TEST for some reason (who added this comment?)
|
||||
#ifdef _M_IX86 // All32
|
||||
|
@ -226,11 +227,10 @@ const u8 *DSPEmitter::Compile(int start_addr) {
|
|||
|
||||
// End the block if we're at a loop end.
|
||||
if (opcode->branch ||
|
||||
(DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_LOOP_END) ||
|
||||
(DSPAnalyzer::code_flags[addr-1] & DSPAnalyzer::CODE_LOOP_END) ||
|
||||
(DSPAnalyzer::code_flags[addr] & DSPAnalyzer::CODE_IDLE_SKIP)) {
|
||||
break;
|
||||
}
|
||||
addr += opcode->size;
|
||||
}
|
||||
|
||||
blocks[start_addr] = (CompiledCode)entryPoint;
|
||||
|
|
Loading…
Reference in New Issue