diff options
| author | Soren Jorvang <soren.jorvang@gmail.com> | 2011-01-29 14:06:48 +0000 |
|---|---|---|
| committer | Soren Jorvang <soren.jorvang@gmail.com> | 2011-01-29 14:06:48 +0000 |
| commit | b3a183dffefc1cb1701ee2a8a2cbe0080774aced (patch) | |
| tree | aeb7b14894e6b17dc70f2bb71e28d1c3f6156f09 /Source/Core/DSPCore/Src/DSPAnalyzer.cpp | |
| parent | 10675ba3c02295cb61f785840ac75e8e65cfb549 (diff) | |
Core and DSPCore now have mutual dependencies, which breaks the
assumption on the part of many linkers that static libraries make
up a DAG, so merge libdspcore into libcore.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6967 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DSPCore/Src/DSPAnalyzer.cpp')
| -rw-r--r-- | Source/Core/DSPCore/Src/DSPAnalyzer.cpp | 173 |
1 files changed, 0 insertions, 173 deletions
diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp deleted file mode 100644 index 8f6b0d4e35..0000000000 --- a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright (C) 2003 Dolphin Project. - -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, version 2.0. - -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License 2.0 for more details. - -// A copy of the GPL 2.0 should have been included with the program. -// If not, see http://www.gnu.org/licenses/ - -// Official SVN repository and contact information can be found at -// http://code.google.com/p/dolphin-emu/ - -#include "DSPAnalyzer.h" -#include "DSPInterpreter.h" -#include "DSPTables.h" -#include "DSPMemoryMap.h" - -namespace DSPAnalyzer { - -// Holds data about all instructions in RAM. -u8 code_flags[ISPACE]; - -// Good candidates for idle skipping is mail wait loops. If we're time slicing -// between the main CPU and the DSP, if the DSP runs into one of these, it might -// 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 - -// 0xFFFF means ignore. -const u16 idle_skip_sigs[NUM_IDLE_SIGS][MAX_IDLE_SIG_SIZE + 1] = -{ - // From AX: - { 0x26fc, // LRS $30, @DMBH - 0x02c0, 0x8000, // ANDCF $30, #0x8000 - 0x029d, 0xFFFF, // JLZ 0x027a - 0, 0 }, // RET - { 0x27fc, // LRS $31, @DMBH - 0x03c0, 0x8000, // ANDCF $31, #0x8000 - 0x029d, 0xFFFF, // JLZ 0x027a - 0, 0 }, // RET - { 0x26fe, // LRS $30, @CMBH - 0x02c0, 0x8000, // ANDCF $30, #0x8000 - 0x029c, 0xFFFF, // JLNZ 0x0280 - 0, 0 }, // RET - { 0x27fe, // LRS $31, @CMBH - 0x03c0, 0x8000, // ANDCF $31, #0x8000 - 0x029c, 0xFFFF, // JLNZ 0x0280 - 0, 0 }, // RET - { 0x26fc, // lrs $AC0.M, @DMBH - 0x02a0, 0x8000, // andf $AC0.M, #0x8000 - 0x029c, 0xFFFF, // jlnz 0x???? - 0, 0 }, - { 0x27fc, // lrs $AC1.M, @DMBH - 0x03a0, 0x8000, // andf $AC1.M, #0x8000 - 0x029c, 0xFFFF, // jlnz 0x???? - 0, 0 }, - // From Zelda: - { 0x00de, 0xFFFE, // LR $AC0.M, @CMBH - 0x02c0, 0x8000, // ANDCF $AC0.M, #0x8000 - 0x029c, 0xFFFF, // JLNZ 0x05cf - 0 }, - // From Zelda - experimental - { 0x00da, 0x0352, // lr $AX0.H, @0x0352 - 0x8600, // tstaxh $AX0.H - 0x0295, 0xFFFF, // jz 0x???? - 0, 0 } -}; - -void Reset() -{ - memset(code_flags, 0, sizeof(code_flags)); -} - -void AnalyzeRange(int start_addr, int end_addr) -{ - // First we run an extremely simplified version of a disassembler to find - // where all instructions start. - - // 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. - u16 last_arithmetic = 0; - for (int addr = start_addr; addr < end_addr;) - { - UDSPInstruction inst = dsp_imem_read(addr); - const DSPOPCTemplate *opcode = GetOpTemplate(inst); - if (!opcode) - { - addr++; - continue; - } - code_flags[addr] |= CODE_START_OF_INST; - // Look for loops. - if ((inst & 0xffe0) == 0x0060 || (inst & 0xff00) == 0x1100) - { - // BLOOP, BLOOPI - u16 loop_end = dsp_imem_read(addr + 1); - code_flags[addr] |= CODE_LOOP_START; - code_flags[loop_end] |= CODE_LOOP_END; - } - else if ((inst & 0xffe0) == 0x0040 || (inst & 0xff00) == 0x1000) - { - // LOOP, LOOPI - code_flags[addr] |= CODE_LOOP_START; - code_flags[addr + 1] |= CODE_LOOP_END; - } - - // Mark the last arithmetic/multiplier instruction before a branch. - // We must update the SR reg at these instructions - if (opcode->updates_sr) - { - last_arithmetic = addr; - } - - if (opcode->branch && !opcode->uncond_branch) - { - code_flags[last_arithmetic] |= CODE_UPDATE_SR; - } - - // If an instruction potentially raises exceptions, mark the following - // instruction as needing to check for exceptions - if (opcode->opcode == 0x00c0 || - opcode->opcode == 0x1800 || - opcode->opcode == 0x1880 || - opcode->opcode == 0x1900 || - opcode->opcode == 0x1980 || - opcode->opcode == 0x2000 || - opcode->extended - ) - code_flags[addr + opcode->size] |= CODE_CHECK_INT; - - addr += opcode->size; - } - - // Next, we'll scan for potential idle skips. - for (int s = 0; s < NUM_IDLE_SIGS; s++) - { - for (int addr = start_addr; addr < end_addr; addr++) - { - bool found = false; - for (int i = 0; i < MAX_IDLE_SIG_SIZE + 1; i++) - { - if (idle_skip_sigs[s][i] == 0) - found = true; - if (idle_skip_sigs[s][i] == 0xFFFF) - continue; - if (idle_skip_sigs[s][i] != dsp_imem_read(addr + i)) - break; - } - if (found) - { - INFO_LOG(DSPLLE, "Idle skip location found at %02x (sigNum:%d)", addr, s+1); - code_flags[addr] |= CODE_IDLE_SKIP; - } - } - } - INFO_LOG(DSPLLE, "Finished analysis."); -} - -void Analyze() -{ - Reset(); - AnalyzeRange(0x0000, 0x1000); // IRAM - AnalyzeRange(0x8000, 0x9000); // IROM -} - -} // namespace |
