mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2024-11-14 21:37:52 -07:00
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
This commit is contained in:
parent
a6637c257f
commit
ae71e63872
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -278,6 +278,15 @@ u16 DSP_WriteControlRegister(u16 _uFlag)
|
||||
}
|
||||
}
|
||||
DSPInterpreter::WriteCR(_uFlag);
|
||||
|
||||
// Check if the CPU has set an external interrupt (CR_EXTERNAL_INT)
|
||||
// and immediately process it, if it has.
|
||||
if (_uFlag & 2)
|
||||
{
|
||||
DSPCore_CheckExternalInterrupt();
|
||||
DSPCore_CheckExceptions();
|
||||
}
|
||||
|
||||
return DSPInterpreter::ReadCR();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user