Make exceptions consistant across all JITs/Interpeters.

They all handled it diffrently, so I've just moved it into Advance()

This fixes Pokemon Box booting in JIT/JITIL which shared a bug where
exceptions set in a scheduled event would be ignored untill the next
slice (upto 20,000 cycles).
This commit is contained in:
Scott Mansell 2016-04-27 11:59:29 +12:00
parent 3033096223
commit eb5819f88a
5 changed files with 15 additions and 24 deletions

View File

@ -453,6 +453,11 @@ void Advance()
g_slicelength = maxslicelength;
PowerPC::ppcState.downcount = CyclesToDowncount(g_slicelength);
}
// Check for any external exceptions.
// It's important to do this after processing events otherwise any exceptions will be delayed until the next slice:
// Pokemon Box refuses to boot if the first exception from the audio DMA is received late
PowerPC::CheckExternalExceptions();
}
void LogPendingEvents()

View File

@ -76,7 +76,6 @@ void CachedInterpreter::SingleStep()
static void EndBlock(UGeckoInstruction data)
{
PC = NPC;
PowerPC::CheckExceptions();
PowerPC::ppcState.downcount -= data.hex;
if (PowerPC::ppcState.downcount <= 0)
{

View File

@ -278,12 +278,6 @@ void Interpreter::Run()
}
CoreTiming::Advance();
if (PowerPC::ppcState.Exceptions)
{
PowerPC::CheckExceptions();
PC = NPC;
}
}
// Let the waiting thread know we are done leaving

View File

@ -202,16 +202,12 @@ void Jit64AsmRoutineManager::Generate()
SetJumpTarget(bail);
doTiming = GetCodePtr();
// Test external exceptions.
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_EXTERNAL_INT | EXCEPTION_PERFORMANCE_MONITOR | EXCEPTION_DECREMENTER));
FixupBranch noExtException = J_CC(CC_Z);
// make sure npc contains the next pc (needed for exception checking in CoreTiming::Advance)
MOV(32, R(RSCRATCH), PPCSTATE(pc));
MOV(32, PPCSTATE(npc), R(RSCRATCH));
ABI_PushRegistersAndAdjustStack({}, 0);
ABI_CallFunction(reinterpret_cast<void *>(&PowerPC::CheckExternalExceptions));
ABI_PopRegistersAndAdjustStack({}, 0);
SetJumpTarget(noExtException);
// Check the state pointer to see if we are exiting
// Gets checked on at the end of every slice
TEST(32, M(PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
J_CC(CC_Z, outerLoop);

View File

@ -73,21 +73,18 @@ void JitArm64AsmRoutineManager::Generate()
SetJumpTarget(bail);
doTiming = GetCodePtr();
// Write the current PC out to PPCSTATE
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
MOVI2R(X30, (u64)&CoreTiming::Advance);
BLR(X30);
// Does exception checking
LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(Exceptions));
FixupBranch no_exceptions = CBZ(W0);
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
STR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
MOVI2R(X30, (u64)&PowerPC::CheckExceptions);
BLR(X30);
LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(npc));
SetJumpTarget(no_exceptions);
// Load the PC back into DISPATCHER_PC (the exception handler might have changed it)
LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
// Check the state pointer to see if we are exiting
// Gets checked on every exception check
// Gets checked on at the end of every slice
MOVI2R(X0, (u64)PowerPC::GetStatePtr());
LDR(INDEX_UNSIGNED, W0, X0, 0);