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;
|
g_slicelength = maxslicelength;
|
||||||
PowerPC::ppcState.downcount = CyclesToDowncount(g_slicelength);
|
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()
|
void LogPendingEvents()
|
||||||
|
|
|
@ -76,7 +76,6 @@ void CachedInterpreter::SingleStep()
|
||||||
static void EndBlock(UGeckoInstruction data)
|
static void EndBlock(UGeckoInstruction data)
|
||||||
{
|
{
|
||||||
PC = NPC;
|
PC = NPC;
|
||||||
PowerPC::CheckExceptions();
|
|
||||||
PowerPC::ppcState.downcount -= data.hex;
|
PowerPC::ppcState.downcount -= data.hex;
|
||||||
if (PowerPC::ppcState.downcount <= 0)
|
if (PowerPC::ppcState.downcount <= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -278,12 +278,6 @@ void Interpreter::Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreTiming::Advance();
|
CoreTiming::Advance();
|
||||||
|
|
||||||
if (PowerPC::ppcState.Exceptions)
|
|
||||||
{
|
|
||||||
PowerPC::CheckExceptions();
|
|
||||||
PC = NPC;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let the waiting thread know we are done leaving
|
// Let the waiting thread know we are done leaving
|
||||||
|
|
|
@ -202,16 +202,12 @@ void Jit64AsmRoutineManager::Generate()
|
||||||
SetJumpTarget(bail);
|
SetJumpTarget(bail);
|
||||||
doTiming = GetCodePtr();
|
doTiming = GetCodePtr();
|
||||||
|
|
||||||
// Test external exceptions.
|
// make sure npc contains the next pc (needed for exception checking in CoreTiming::Advance)
|
||||||
TEST(32, PPCSTATE(Exceptions), Imm32(EXCEPTION_EXTERNAL_INT | EXCEPTION_PERFORMANCE_MONITOR | EXCEPTION_DECREMENTER));
|
|
||||||
FixupBranch noExtException = J_CC(CC_Z);
|
|
||||||
MOV(32, R(RSCRATCH), PPCSTATE(pc));
|
MOV(32, R(RSCRATCH), PPCSTATE(pc));
|
||||||
MOV(32, PPCSTATE(npc), R(RSCRATCH));
|
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));
|
TEST(32, M(PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF));
|
||||||
J_CC(CC_Z, outerLoop);
|
J_CC(CC_Z, outerLoop);
|
||||||
|
|
||||||
|
|
|
@ -73,21 +73,18 @@ void JitArm64AsmRoutineManager::Generate()
|
||||||
|
|
||||||
SetJumpTarget(bail);
|
SetJumpTarget(bail);
|
||||||
doTiming = GetCodePtr();
|
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);
|
MOVI2R(X30, (u64)&CoreTiming::Advance);
|
||||||
BLR(X30);
|
BLR(X30);
|
||||||
|
|
||||||
// Does exception checking
|
// Load the PC back into DISPATCHER_PC (the exception handler might have changed it)
|
||||||
LDR(INDEX_UNSIGNED, W0, PPC_REG, PPCSTATE_OFF(Exceptions));
|
LDR(INDEX_UNSIGNED, DISPATCHER_PC, PPC_REG, PPCSTATE_OFF(pc));
|
||||||
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);
|
|
||||||
|
|
||||||
// Check the state pointer to see if we are exiting
|
// 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());
|
MOVI2R(X0, (u64)PowerPC::GetStatePtr());
|
||||||
LDR(INDEX_UNSIGNED, W0, X0, 0);
|
LDR(INDEX_UNSIGNED, W0, X0, 0);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue