summaryrefslogtreecommitdiff
path: root/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
diff options
context:
space:
mode:
authorskidau <skidau@gmail.com>2010-12-21 14:48:05 +0000
committerskidau <skidau@gmail.com>2010-12-21 14:48:05 +0000
commit6cb78515c64101824d35ee7478d8d30e8dcc6879 (patch)
treec3623ff71d2c647f9fc0d1dcce9339b6cc5c508d /Source/Core/DSPCore/Src/DSPAnalyzer.cpp
parent0030d5572590743525947a630797a1c11a885912 (diff)
LLE JIT:
* Added 21 Arithmetic instructions to the JIT * Used the DSPAnalyser to identify arithmetic/multiplier instructions that precede a conditional branch. This allows the JIT to skip updating the SR when nothing would read from it. Marked all arithmetic/multiplier instructions in the DSPTable for this purpose. * Converted CheckExternalInterrupt into ASM * Fixed a couple instructions in DSP Load/Store git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6633 8ced0084-cf51-0410-be5f-012b33b47a6e
Diffstat (limited to 'Source/Core/DSPCore/Src/DSPAnalyzer.cpp')
-rw-r--r--Source/Core/DSPCore/Src/DSPAnalyzer.cpp25
1 files changed, 21 insertions, 4 deletions
diff --git a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
index 7319ba7a14..b4300867ac 100644
--- a/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
+++ b/Source/Core/DSPCore/Src/DSPAnalyzer.cpp
@@ -85,6 +85,7 @@ void AnalyzeRange(int start_addr, int end_addr)
// 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);
@@ -96,16 +97,32 @@ void AnalyzeRange(int start_addr, int end_addr)
}
code_flags[addr] |= CODE_START_OF_INST;
// Look for loops.
- if ((inst & 0xffe0) == 0x0060 || (inst & 0xff00) == 0x1100) {
+ 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) {
+ }
+ 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;
+ }
+
addr += opcode->size;
}
@@ -126,12 +143,12 @@ void AnalyzeRange(int start_addr, int end_addr)
}
if (found)
{
- NOTICE_LOG(DSPLLE, "Idle skip location found at %02x (sigNum:%d)", addr, s+1);
+ INFO_LOG(DSPLLE, "Idle skip location found at %02x (sigNum:%d)", addr, s+1);
code_flags[addr] |= CODE_IDLE_SKIP;
}
}
}
- NOTICE_LOG(DSPLLE, "Finished analysis.");
+ INFO_LOG(DSPLLE, "Finished analysis.");
}
void Analyze()