From cc512a75241352929101c6d31fd10b285362f4f5 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 28 Dec 2020 11:51:25 -0500 Subject: [PATCH] DSPAnalyzer: Break tight coupling to SDSP Allows the analyzer to exist independently of the DSP structure. This allows for unit-tests to be created in a nicer manner. SDSP is only necessary during the analysis phase, so we only need to keep a reference around to it then as opposed to the entire lifecycle of the analyzer. This also allows the copy/move assignment operators to be defaulted, as a reference member variable prevents that. --- Source/Core/Core/DSP/DSPAnalyzer.cpp | 19 ++++++++----------- Source/Core/Core/DSP/DSPAnalyzer.h | 13 +++++-------- Source/Core/Core/DSP/DSPCore.cpp | 4 ++-- Source/Core/Core/HW/DSPLLE/DSPHost.cpp | 2 +- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/Source/Core/Core/DSP/DSPAnalyzer.cpp b/Source/Core/Core/DSP/DSPAnalyzer.cpp index ccafaebc51..ae81357b19 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.cpp +++ b/Source/Core/Core/DSP/DSPAnalyzer.cpp @@ -61,17 +61,14 @@ constexpr u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = { 0, 0}, }; -Analyzer::Analyzer(const SDSP& dsp) : m_dsp{dsp} -{ -} - +Analyzer::Analyzer() = default; Analyzer::~Analyzer() = default; -void Analyzer::Analyze() +void Analyzer::Analyze(const SDSP& dsp) { Reset(); - AnalyzeRange(0x0000, 0x1000); // IRAM - AnalyzeRange(0x8000, 0x9000); // IROM + AnalyzeRange(dsp, 0x0000, 0x1000); // IRAM + AnalyzeRange(dsp, 0x8000, 0x9000); // IROM } void Analyzer::Reset() @@ -79,7 +76,7 @@ void Analyzer::Reset() m_code_flags.fill(0); } -void Analyzer::AnalyzeRange(u16 start_addr, u16 end_addr) +void Analyzer::AnalyzeRange(const SDSP& dsp, u16 start_addr, u16 end_addr) { // First we run an extremely simplified version of a disassembler to find // where all instructions start. @@ -89,7 +86,7 @@ void Analyzer::AnalyzeRange(u16 start_addr, u16 end_addr) u16 last_arithmetic = 0; for (u16 addr = start_addr; addr < end_addr;) { - const UDSPInstruction inst = m_dsp.ReadIMEM(addr); + const UDSPInstruction inst = dsp.ReadIMEM(addr); const DSPOPCTemplate* opcode = GetOpTemplate(inst); if (!opcode) { @@ -101,7 +98,7 @@ void Analyzer::AnalyzeRange(u16 start_addr, u16 end_addr) if ((inst & 0xffe0) == 0x0060 || (inst & 0xff00) == 0x1100) { // BLOOP, BLOOPI - const u16 loop_end = m_dsp.ReadIMEM(addr + 1); + const u16 loop_end = dsp.ReadIMEM(addr + 1); m_code_flags[addr] |= CODE_LOOP_START; m_code_flags[loop_end] |= CODE_LOOP_END; } @@ -148,7 +145,7 @@ void Analyzer::AnalyzeRange(u16 start_addr, u16 end_addr) found = true; if (idle_skip_sigs[s][i] == 0xFFFF) continue; - if (idle_skip_sigs[s][i] != m_dsp.ReadIMEM(static_cast(addr + i))) + if (idle_skip_sigs[s][i] != dsp.ReadIMEM(static_cast(addr + i))) break; } if (found) diff --git a/Source/Core/Core/DSP/DSPAnalyzer.h b/Source/Core/Core/DSP/DSPAnalyzer.h index d3077fc48b..c48199aa24 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.h +++ b/Source/Core/Core/DSP/DSPAnalyzer.h @@ -20,14 +20,14 @@ namespace DSP class Analyzer { public: - explicit Analyzer(const SDSP& dsp); + explicit Analyzer(); ~Analyzer(); Analyzer(const Analyzer&) = default; - Analyzer& operator=(const Analyzer&) = delete; + Analyzer& operator=(const Analyzer&) = default; Analyzer(Analyzer&&) = default; - Analyzer& operator=(Analyzer&&) = delete; + Analyzer& operator=(Analyzer&&) = default; // This one should be called every time IRAM changes - which is basically // every time that a new ucode gets uploaded, and never else. At that point, @@ -35,7 +35,7 @@ public: // all old analysis away. Luckily the entire address space is only 64K code // words and the actual code space 8K instructions in total, so we can do // some pretty expensive analysis if necessary. - void Analyze(); + void Analyze(const SDSP& dsp); // Whether or not the given address indicates the start of an instruction. [[nodiscard]] bool IsStartOfInstruction(u16 address) const @@ -90,15 +90,12 @@ private: // Analyzes a region of DSP memory. // Note: start is inclusive, end is exclusive. - void AnalyzeRange(u16 start_addr, u16 end_addr); + void AnalyzeRange(const SDSP& dsp, u16 start_addr, u16 end_addr); // Retrieves the flags set during analysis for code in memory. [[nodiscard]] u8 GetCodeFlags(u16 address) const { return m_code_flags[address]; } // Holds data about all instructions in RAM. std::array m_code_flags{}; - - // DSP context for analysis to be run under. - const SDSP& m_dsp; }; } // namespace DSP diff --git a/Source/Core/Core/DSP/DSPCore.cpp b/Source/Core/Core/DSP/DSPCore.cpp index 7be3350ae6..40c7c20cb4 100644 --- a/Source/Core/Core/DSP/DSPCore.cpp +++ b/Source/Core/Core/DSP/DSPCore.cpp @@ -115,7 +115,7 @@ private: SDSP& m_dsp; }; -SDSP::SDSP(DSPCore& core) : m_dsp_core{core}, m_analyzer{*this} +SDSP::SDSP(DSPCore& core) : m_dsp_core{core} { } @@ -487,7 +487,7 @@ void DSPCore::Step() void DSPCore::Reset() { m_dsp.Reset(); - m_dsp.GetAnalyzer().Analyze(); + m_dsp.GetAnalyzer().Analyze(m_dsp); } void DSPCore::ClearIRAM() diff --git a/Source/Core/Core/HW/DSPLLE/DSPHost.cpp b/Source/Core/Core/HW/DSPLLE/DSPHost.cpp index b0e06edca5..65e26ce238 100644 --- a/Source/Core/Core/HW/DSPLLE/DSPHost.cpp +++ b/Source/Core/Core/HW/DSPLLE/DSPHost.cpp @@ -93,7 +93,7 @@ void CodeLoaded(DSPCore& dsp, const u8* ptr, size_t size) UpdateDebugger(); dsp.ClearIRAM(); - state.GetAnalyzer().Analyze(); + state.GetAnalyzer().Analyze(state); } void UpdateDebugger()