From 8f4c6ad7b102244e056875b30c2fb2243b70f74f Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 28 Dec 2020 09:59:45 -0500 Subject: [PATCH] DSPAnalyzer: Add basic class skeleton Adds the non-functional skeleton for the to-be Analyzer interface with deglobalized components. --- Source/Core/Core/DSP/DSPAnalyzer.h | 42 +++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/Source/Core/Core/DSP/DSPAnalyzer.h b/Source/Core/Core/DSP/DSPAnalyzer.h index dab41baadc..5cf80b88fe 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.h +++ b/Source/Core/Core/DSP/DSPAnalyzer.h @@ -4,6 +4,7 @@ #pragma once +#include #include "Common/CommonTypes.h" namespace DSP @@ -17,8 +18,9 @@ namespace DSP::Analyzer // Useful things to detect: // * Loop endpoints - so that we can avoid checking for loops every cycle. -enum +enum CodeFlags : u8 { + CODE_NONE = 0, CODE_START_OF_INST = 1, CODE_IDLE_SKIP = 2, CODE_LOOP_START = 4, @@ -27,6 +29,44 @@ enum CODE_CHECK_INT = 32, }; +class Analyzer +{ +public: + explicit Analyzer(const SDSP& dsp); + ~Analyzer(); + + Analyzer(const Analyzer&) = default; + Analyzer& operator=(const Analyzer&) = delete; + + Analyzer(Analyzer&&) = default; + Analyzer& operator=(Analyzer&&) = delete; + + // 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, + // we can do as much static analysis as we want - but we should always throw + // 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(); + + // Retrieves the flags set during analysis for code in memory. + [[nodiscard]] u8 GetCodeFlags(u16 address) const { return m_code_flags[address]; } + +private: + // Flushes all analyzed state. + void Reset(); + + // Analyzes a region of DSP memory. + // Note: start is inclusive, end is exclusive. + void AnalyzeRange(u16 start_addr, u16 end_addr); + + // Holds data about all instructions in RAM. + std::array m_code_flags{}; + + // DSP context for analysis to be run under. + const SDSP& m_dsp; +}; + // 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, // we can do as much static analysis as we want - but we should always throw