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.
This commit is contained in:
Lioncash 2020-12-28 11:51:25 -05:00
parent f9c488f0d9
commit cc512a7524
4 changed files with 16 additions and 22 deletions

View File

@ -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<u16>(addr + i)))
if (idle_skip_sigs[s][i] != dsp.ReadIMEM(static_cast<u16>(addr + i)))
break;
}
if (found)

View File

@ -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<u8, 65536> m_code_flags{};
// DSP context for analysis to be run under.
const SDSP& m_dsp;
};
} // namespace DSP

View File

@ -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()

View File

@ -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()