diff --git a/Source/Core/Core/DSP/DSPCore.cpp b/Source/Core/Core/DSP/DSPCore.cpp index 731d71e023..41c10b2428 100644 --- a/Source/Core/Core/DSP/DSPCore.cpp +++ b/Source/Core/Core/DSP/DSPCore.cpp @@ -224,11 +224,11 @@ void SDSP::CheckExternalInterrupt() control_reg &= ~CR_EXTERNAL_INT; } -void SDSP::CheckExceptions() +bool SDSP::CheckExceptions() { // Early out to skip the loop in the common case. if (exceptions == 0) - return; + return false; for (int i = 7; i > 0; i--) { @@ -247,7 +247,7 @@ void SDSP::CheckExceptions() r.sr &= ~SR_EXT_INT_ENABLE; else r.sr &= ~SR_INT_ENABLE; - break; + return true; } else { @@ -257,6 +257,8 @@ void SDSP::CheckExceptions() } } } + + return false; } u16 SDSP::ReadRegister(size_t reg) const @@ -541,9 +543,9 @@ void DSPCore::CheckExternalInterrupt() m_dsp.CheckExternalInterrupt(); } -void DSPCore::CheckExceptions() +bool DSPCore::CheckExceptions() { - m_dsp.CheckExceptions(); + return m_dsp.CheckExceptions(); } u16 DSPCore::ReadRegister(size_t reg) const diff --git a/Source/Core/Core/DSP/DSPCore.h b/Source/Core/Core/DSP/DSPCore.h index c0a5c0dba7..29bded217a 100644 --- a/Source/Core/Core/DSP/DSPCore.h +++ b/Source/Core/Core/DSP/DSPCore.h @@ -383,7 +383,7 @@ struct SDSP void SetException(ExceptionType exception); // Checks if any exceptions occurred an updates the DSP state as appropriate. - void CheckExceptions(); + bool CheckExceptions(); // Notify that an external interrupt is pending (used by thread mode) void SetExternalInterrupt(bool val); @@ -530,7 +530,7 @@ public: void CheckExternalInterrupt(); // Checks if any exceptions occurred an updates the DSP state as appropriate. - void CheckExceptions(); + bool CheckExceptions(); // Reads the current value from a particular register. u16 ReadRegister(size_t reg) const; diff --git a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp index 7066209530..f1b57ea504 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp @@ -99,9 +99,9 @@ void DSPEmitter::ClearIRAMandDSPJITCodespaceReset() m_dsp_core.DSPState().reset_dspjit_codespace = false; } -static void CheckExceptionsThunk(DSPCore& dsp) +static u32 CheckExceptionsThunk(DSPCore& dsp) { - dsp.CheckExceptions(); + return dsp.CheckExceptions() ? 1u : 0u; } // Must go out of block if exception is detected @@ -116,8 +116,11 @@ void DSPEmitter::checkExceptions(u32 retval) DSPJitRegCache c(m_gpr); m_gpr.SaveRegs(); ABI_CallFunctionP(CheckExceptionsThunk, &m_dsp_core); + TEST(32, R(ABI_RETURN), R(ABI_RETURN)); + FixupBranch skip_return = J_CC(CC_Z, Jump::Short); MOV(32, R(EAX), Imm32(retval)); JMP(m_return_dispatcher, Jump::Near); + SetJumpTarget(skip_return); m_gpr.LoadRegs(false); m_gpr.FlushRegs(c, false);