diff --git a/Source/Core/Core/DSP/DSPAnalyzer.cpp b/Source/Core/Core/DSP/DSPAnalyzer.cpp index 19d563f4b2..a62de02771 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.cpp +++ b/Source/Core/Core/DSP/DSPAnalyzer.cpp @@ -91,7 +91,9 @@ void Analyzer::FindInstructionStarts(const SDSP& dsp, u16 start_addr, u16 end_ad { // This may not be 100% accurate in case of jump tables! // It could get desynced, which would be bad. We'll see if that's an issue. +#ifndef DISABLE_UPDATE_SR_ANALYSIS u16 last_arithmetic = 0; +#endif for (u16 addr = start_addr; addr < end_addr;) { const UDSPInstruction inst = dsp.ReadIMEM(addr); @@ -117,6 +119,7 @@ void Analyzer::FindInstructionStarts(const SDSP& dsp, u16 start_addr, u16 end_ad m_code_flags[static_cast(addr + 1u)] |= CODE_LOOP_END; } +#ifndef DISABLE_UPDATE_SR_ANALYSIS // Mark the last arithmetic/multiplier instruction before a branch. // We must update the SR reg at these instructions if (opcode->updates_sr) @@ -128,6 +131,7 @@ void Analyzer::FindInstructionStarts(const SDSP& dsp, u16 start_addr, u16 end_ad { m_code_flags[last_arithmetic] |= CODE_UPDATE_SR; } +#endif // If an instruction potentially raises exceptions, mark the following // instruction as needing to check for exceptions diff --git a/Source/Core/Core/DSP/DSPAnalyzer.h b/Source/Core/Core/DSP/DSPAnalyzer.h index c5875e3701..5f172f48be 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.h +++ b/Source/Core/Core/DSP/DSPAnalyzer.h @@ -6,6 +6,13 @@ #include #include "Common/CommonTypes.h" +// The update SR analysis is not perfect: it does not properly handle modified SR values if SR is +// only read within a function call, and it's possible that a previous instruction sets SR (e.g. the +// logical zero bit, or the sticky overflow bit) but is marked as not changing SR as a later +// instruction sets it. When this flag is set, we always treat instructions as updating SR, and +// disable the analysis for if SR needs to be set. +#define DISABLE_UPDATE_SR_ANALYSIS + namespace DSP { struct SDSP; @@ -63,7 +70,11 @@ public: // Whether or not the address describes an instruction that requires updating the SR register. [[nodiscard]] bool IsUpdateSR(u16 address) const { +#ifdef DISABLE_UPDATE_SR_ANALYSIS + return true; +#else return (GetCodeFlags(address) & CODE_UPDATE_SR) != 0; +#endif } // Whether or not the address describes instructions that potentially raise exceptions.