diff --git a/Source/Core/Core/DSP/DSPCore.cpp b/Source/Core/Core/DSP/DSPCore.cpp index b6d89064b5..1c3cc19709 100644 --- a/Source/Core/Core/DSP/DSPCore.cpp +++ b/Source/Core/Core/DSP/DSPCore.cpp @@ -213,11 +213,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--) { @@ -236,7 +236,7 @@ void SDSP::CheckExceptions() r.sr &= ~SR_EXT_INT_ENABLE; else r.sr &= ~SR_INT_ENABLE; - break; + return true; } else { @@ -246,6 +246,8 @@ void SDSP::CheckExceptions() } } } + + return false; } u16 SDSP::ReadRegister(size_t reg) const @@ -530,9 +532,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 a12f49270d..fa2e2632c8 100644 --- a/Source/Core/Core/DSP/DSPCore.h +++ b/Source/Core/Core/DSP/DSPCore.h @@ -382,8 +382,9 @@ struct SDSP // and sets a flag in the pending exception register. void SetException(ExceptionType exception); - // Checks if any exceptions occurred an updates the DSP state as appropriate. - void CheckExceptions(); + // Checks if any exceptions occurred and updates the DSP state as appropriate. + // Returns true if PC changed. + bool CheckExceptions(); // Notify that an external interrupt is pending (used by thread mode) void SetExternalInterrupt(bool val); @@ -529,8 +530,9 @@ public: // Coming from the CPU void CheckExternalInterrupt(); - // Checks if any exceptions occurred an updates the DSP state as appropriate. - void CheckExceptions(); + // Checks if any exceptions occurred and updates the DSP state as appropriate. + // Returns true if PC changed. + 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 7e3c41a42e..8bcda1800a 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp +++ b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.cpp @@ -99,13 +99,13 @@ void DSPEmitter::ClearIRAMandDSPJITCodespaceReset() m_dsp_core.DSPState().reset_dspjit_codespace = false; } -static void CheckExceptionsThunk(DSPCore& dsp) +static bool CheckExceptionsThunk(DSPCore& dsp) { - dsp.CheckExceptions(); + return dsp.CheckExceptions(); } // Must go out of block if exception is detected -void DSPEmitter::checkExceptions(u32 retval) +void DSPEmitter::checkExceptions(u16 retval) { // Check for interrupts and exceptions TEST(8, M_SDSP_exceptions(), Imm8(0xff)); @@ -116,9 +116,10 @@ void DSPEmitter::checkExceptions(u32 retval) DSPJitRegCache c(m_gpr); m_gpr.SaveRegs(); ABI_CallFunctionP(CheckExceptionsThunk, &m_dsp_core); - MOV(32, R(EAX), Imm32(retval)); - JMP(m_return_dispatcher, Jump::Near); - m_gpr.LoadRegs(false); + TEST(8, R(ABI_RETURN), R(ABI_RETURN)); + MOV(16, R(EAX), Imm16(retval)); + J_CC(CC_NZ, m_return_dispatcher); + m_gpr.LoadRegs(false); // TODO: Does this still make sense? m_gpr.FlushRegs(c, false); SetJumpTarget(skipCheck); diff --git a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h index 840c77cff8..e4a97d2336 100644 --- a/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h +++ b/Source/Core/Core/DSP/Jit/x64/DSPEmitter.h @@ -263,7 +263,7 @@ private: // Register helpers void setCompileSR(u16 bit); void clrCompileSR(u16 bit); - void checkExceptions(u32 retval); + void checkExceptions(u16 retval); // Memory helper functions void increment_addr_reg(int reg);