mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-28 01:49:33 -06:00
DSP/Jit: Don't return to dispatcher if no exception was generated
This commit is contained in:
@ -224,11 +224,11 @@ void SDSP::CheckExternalInterrupt()
|
|||||||
control_reg &= ~CR_EXTERNAL_INT;
|
control_reg &= ~CR_EXTERNAL_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDSP::CheckExceptions()
|
bool SDSP::CheckExceptions()
|
||||||
{
|
{
|
||||||
// Early out to skip the loop in the common case.
|
// Early out to skip the loop in the common case.
|
||||||
if (exceptions == 0)
|
if (exceptions == 0)
|
||||||
return;
|
return false;
|
||||||
|
|
||||||
for (int i = 7; i > 0; i--)
|
for (int i = 7; i > 0; i--)
|
||||||
{
|
{
|
||||||
@ -247,7 +247,7 @@ void SDSP::CheckExceptions()
|
|||||||
r.sr &= ~SR_EXT_INT_ENABLE;
|
r.sr &= ~SR_EXT_INT_ENABLE;
|
||||||
else
|
else
|
||||||
r.sr &= ~SR_INT_ENABLE;
|
r.sr &= ~SR_INT_ENABLE;
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -257,6 +257,8 @@ void SDSP::CheckExceptions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 SDSP::ReadRegister(size_t reg) const
|
u16 SDSP::ReadRegister(size_t reg) const
|
||||||
@ -541,9 +543,9 @@ void DSPCore::CheckExternalInterrupt()
|
|||||||
m_dsp.CheckExternalInterrupt();
|
m_dsp.CheckExternalInterrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSPCore::CheckExceptions()
|
bool DSPCore::CheckExceptions()
|
||||||
{
|
{
|
||||||
m_dsp.CheckExceptions();
|
return m_dsp.CheckExceptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 DSPCore::ReadRegister(size_t reg) const
|
u16 DSPCore::ReadRegister(size_t reg) const
|
||||||
|
@ -383,7 +383,7 @@ struct SDSP
|
|||||||
void SetException(ExceptionType exception);
|
void SetException(ExceptionType exception);
|
||||||
|
|
||||||
// Checks if any exceptions occurred an updates the DSP state as appropriate.
|
// 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)
|
// Notify that an external interrupt is pending (used by thread mode)
|
||||||
void SetExternalInterrupt(bool val);
|
void SetExternalInterrupt(bool val);
|
||||||
@ -530,7 +530,7 @@ public:
|
|||||||
void CheckExternalInterrupt();
|
void CheckExternalInterrupt();
|
||||||
|
|
||||||
// Checks if any exceptions occurred an updates the DSP state as appropriate.
|
// Checks if any exceptions occurred an updates the DSP state as appropriate.
|
||||||
void CheckExceptions();
|
bool CheckExceptions();
|
||||||
|
|
||||||
// Reads the current value from a particular register.
|
// Reads the current value from a particular register.
|
||||||
u16 ReadRegister(size_t reg) const;
|
u16 ReadRegister(size_t reg) const;
|
||||||
|
@ -99,9 +99,9 @@ void DSPEmitter::ClearIRAMandDSPJITCodespaceReset()
|
|||||||
m_dsp_core.DSPState().reset_dspjit_codespace = false;
|
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
|
// Must go out of block if exception is detected
|
||||||
@ -116,8 +116,11 @@ void DSPEmitter::checkExceptions(u32 retval)
|
|||||||
DSPJitRegCache c(m_gpr);
|
DSPJitRegCache c(m_gpr);
|
||||||
m_gpr.SaveRegs();
|
m_gpr.SaveRegs();
|
||||||
ABI_CallFunctionP(CheckExceptionsThunk, &m_dsp_core);
|
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));
|
MOV(32, R(EAX), Imm32(retval));
|
||||||
JMP(m_return_dispatcher, Jump::Near);
|
JMP(m_return_dispatcher, Jump::Near);
|
||||||
|
SetJumpTarget(skip_return);
|
||||||
m_gpr.LoadRegs(false);
|
m_gpr.LoadRegs(false);
|
||||||
m_gpr.FlushRegs(c, false);
|
m_gpr.FlushRegs(c, false);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user