From a8459fc1893d2cedf5fc8c24f32c8dd7e61477cc Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 26 Dec 2016 20:52:09 -0500 Subject: [PATCH] DSPAnalyzer: Hide implementation details Makes accessing flags a part of the function interface instead of exposing an internal variable. --- Source/Core/Core/DSP/DSPAnalyzer.cpp | 23 ++++++++++++++----- Source/Core/Core/DSP/DSPAnalyzer.h | 13 ++++------- .../Core/DSP/Interpreter/DSPInterpreter.cpp | 6 ++--- Source/Core/Core/DSP/Jit/DSPEmitter.cpp | 21 ++++++++--------- Source/Core/Core/DSP/Jit/DSPJitBranch.cpp | 2 +- 5 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Source/Core/Core/DSP/DSPAnalyzer.cpp b/Source/Core/Core/DSP/DSPAnalyzer.cpp index 1de95acf3a..50ab837c14 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.cpp +++ b/Source/Core/Core/DSP/DSPAnalyzer.cpp @@ -5,6 +5,7 @@ #include "Core/DSP/DSPAnalyzer.h" #include +#include #include "Common/Logging/Log.h" @@ -13,6 +14,10 @@ namespace DSPAnalyzer { +namespace +{ +constexpr size_t ISPACE = 65536; + // Holds data about all instructions in RAM. std::array code_flags; @@ -21,11 +26,11 @@ std::array code_flags; // as well give up its time slice immediately, after executing once. // Max signature length is 6. A 0 in a signature is ignored. -#define NUM_IDLE_SIGS 8 -#define MAX_IDLE_SIG_SIZE 6 +constexpr size_t NUM_IDLE_SIGS = 8; +constexpr size_t MAX_IDLE_SIG_SIZE = 6; // 0xFFFF means ignore. -const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = { +constexpr u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = { // From AX: {0x26fc, // LRS $30, @DMBH 0x02c0, 0x8000, // ANDCF $30, #0x8000 @@ -62,12 +67,12 @@ const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = { 0x0295, 0xFFFF, // JZ 0x???? 0, 0}}; -static void Reset() +void Reset() { code_flags.fill(0); } -static void AnalyzeRange(u16 start_addr, u16 end_addr) +void AnalyzeRange(u16 start_addr, u16 end_addr) { // First we run an extremely simplified version of a disassembler to find // where all instructions start. @@ -146,6 +151,7 @@ static void AnalyzeRange(u16 start_addr, u16 end_addr) } INFO_LOG(DSPLLE, "Finished analysis."); } +} // Anonymous namespace void Analyze() { @@ -154,4 +160,9 @@ void Analyze() AnalyzeRange(0x8000, 0x9000); // IROM } -} // namespace +u8 GetCodeFlags(u16 address) +{ + return code_flags[address]; +} + +} // namespace DSPAnalyzer diff --git a/Source/Core/Core/DSP/DSPAnalyzer.h b/Source/Core/Core/DSP/DSPAnalyzer.h index 1eea140400..387e97ce38 100644 --- a/Source/Core/Core/DSP/DSPAnalyzer.h +++ b/Source/Core/Core/DSP/DSPAnalyzer.h @@ -4,14 +4,11 @@ #pragma once -#include #include "Common/CommonTypes.h" // Basic code analysis. namespace DSPAnalyzer { -#define ISPACE 65536 - // Useful things to detect: // * Loop endpoints - so that we can avoid checking for loops every cycle. @@ -25,11 +22,6 @@ enum CODE_CHECK_INT = 32, }; -// Easy to query array covering the whole of instruction memory. -// Just index by address. -// This one will be helpful for debuggers and jits. -extern std::array code_flags; - // 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 @@ -38,4 +30,7 @@ extern std::array code_flags; // some pretty expensive analysis if necessary. void Analyze(); -} // namespace +// Retrieves the flags set during analysis for code in memory. +u8 GetCodeFlags(u16 address); + +} // namespace DSPAnalyzer diff --git a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp index b30eccc519..72c650171d 100644 --- a/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp +++ b/Source/Core/Core/DSP/Interpreter/DSPInterpreter.cpp @@ -100,7 +100,7 @@ void Step() u16 opc = dsp_fetch_code(); ExecuteInstruction(UDSPInstruction(opc)); - if (DSPAnalyzer::code_flags[static_cast(g_dsp.pc - 1u)] & DSPAnalyzer::CODE_LOOP_END) + if (DSPAnalyzer::GetCodeFlags(static_cast(g_dsp.pc - 1u)) & DSPAnalyzer::CODE_LOOP_END) HandleLoop(); } @@ -158,7 +158,7 @@ int RunCyclesDebug(int cycles) return cycles; } // Idle skipping. - if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) + if (DSPAnalyzer::GetCodeFlags(g_dsp.pc) & DSPAnalyzer::CODE_IDLE_SKIP) return 0; Step(); cycles--; @@ -208,7 +208,7 @@ int RunCycles(int cycles) if (g_dsp.cr & CR_HALT) return 0; // Idle skipping. - if (DSPAnalyzer::code_flags[g_dsp.pc] & DSPAnalyzer::CODE_IDLE_SKIP) + if (DSPAnalyzer::GetCodeFlags(g_dsp.pc) & DSPAnalyzer::CODE_IDLE_SKIP) return 0; Step(); cycles--; diff --git a/Source/Core/Core/DSP/Jit/DSPEmitter.cpp b/Source/Core/Core/DSP/Jit/DSPEmitter.cpp index 4e4076b2ed..f5bb9e6db0 100644 --- a/Source/Core/Core/DSP/Jit/DSPEmitter.cpp +++ b/Source/Core/Core/DSP/Jit/DSPEmitter.cpp @@ -92,11 +92,9 @@ void DSPEmitter::checkExceptions(u32 retval) bool DSPEmitter::FlagsNeeded() { - if (!(DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_START_OF_INST) || - (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_UPDATE_SR)) - return true; - else - return false; + const u8 flags = DSPAnalyzer::GetCodeFlags(compilePC); + + return !(flags & DSPAnalyzer::CODE_START_OF_INST) || (flags & DSPAnalyzer::CODE_UPDATE_SR); } void DSPEmitter::FallBackToInterpreter(UDSPInstruction inst) @@ -217,7 +215,7 @@ void DSPEmitter::Compile(u16 start_addr) while (compilePC < start_addr + MAX_BLOCK_SIZE) { - if (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_CHECK_INT) + if (DSPAnalyzer::GetCodeFlags(compilePC) & DSPAnalyzer::CODE_CHECK_INT) checkExceptions(blockSize[start_addr]); UDSPInstruction inst = dsp_imem_read(compilePC); @@ -235,7 +233,7 @@ void DSPEmitter::Compile(u16 start_addr) // Handle loop condition, only if current instruction was flagged as a loop destination // by the analyzer. - if (DSPAnalyzer::code_flags[static_cast(compilePC - 1u)] & DSPAnalyzer::CODE_LOOP_END) + if (DSPAnalyzer::GetCodeFlags(static_cast(compilePC - 1u)) & DSPAnalyzer::CODE_LOOP_END) { MOVZX(32, 16, EAX, M(&(g_dsp.r.st[2]))); TEST(32, R(EAX), R(EAX)); @@ -256,7 +254,8 @@ void DSPEmitter::Compile(u16 start_addr) DSPJitRegCache c(gpr); HandleLoop(); gpr.SaveRegs(); - if (!DSPHost::OnThread() && DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + if (!DSPHost::OnThread() && + DSPAnalyzer::GetCodeFlags(start_addr) & DSPAnalyzer::CODE_IDLE_SKIP) { MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES)); } @@ -291,7 +290,7 @@ void DSPEmitter::Compile(u16 start_addr) // don't update g_dsp.pc -- the branch insn already did gpr.SaveRegs(); if (!DSPHost::OnThread() && - DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + DSPAnalyzer::GetCodeFlags(start_addr) & DSPAnalyzer::CODE_IDLE_SKIP) { MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES)); } @@ -308,7 +307,7 @@ void DSPEmitter::Compile(u16 start_addr) } // End the block if we're before an idle skip address - if (DSPAnalyzer::code_flags[compilePC] & DSPAnalyzer::CODE_IDLE_SKIP) + if (DSPAnalyzer::GetCodeFlags(compilePC) & DSPAnalyzer::CODE_IDLE_SKIP) { break; } @@ -354,7 +353,7 @@ void DSPEmitter::Compile(u16 start_addr) } gpr.SaveRegs(); - if (!DSPHost::OnThread() && DSPAnalyzer::code_flags[start_addr] & DSPAnalyzer::CODE_IDLE_SKIP) + if (!DSPHost::OnThread() && DSPAnalyzer::GetCodeFlags(start_addr) & DSPAnalyzer::CODE_IDLE_SKIP) { MOV(16, R(EAX), Imm16(DSP_IDLE_SKIP_CYCLES)); } diff --git a/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp b/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp index 5cc72548a2..97e0a26a35 100644 --- a/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp +++ b/Source/Core/Core/DSP/Jit/DSPJitBranch.cpp @@ -81,7 +81,7 @@ static void WriteBranchExit(DSPEmitter& emitter) { DSPJitRegCache c(emitter.gpr); emitter.gpr.SaveRegs(); - if (DSPAnalyzer::code_flags[emitter.startAddr] & DSPAnalyzer::CODE_IDLE_SKIP) + if (DSPAnalyzer::GetCodeFlags(emitter.startAddr) & DSPAnalyzer::CODE_IDLE_SKIP) { emitter.MOV(16, R(EAX), Imm16(0x1000)); }