Merge pull request #3800 from phire/unexceptional-exceptions
Make exceptions consistent across all JITs/Interpreters (Fixes Pokemon Box)
This commit is contained in:
commit
b99b685f22
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue