summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
diff options
context:
space:
mode:
authorSoren Jorvang <soren.jorvang@gmail.com>2011-01-29 14:06:48 +0000
committerSoren Jorvang <soren.jorvang@gmail.com>2011-01-29 14:06:48 +0000
commitb3a183dffefc1cb1701ee2a8a2cbe0080774aced (patch)
treeaeb7b14894e6b17dc70f2bb71e28d1c3f6156f09 /Source/Core/DSPCore/Src/DSPAnalyzer.cpp
parent10675ba3c02295cb61f785840ac75e8e65cfb549 (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.cpp173
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