diff options
| author | skidau <skidau@gmail.com> | 2010-12-21 14:48:05 +0000 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2010-12-21 14:48:05 +0000 |
| commit | 6cb78515c64101824d35ee7478d8d30e8dcc6879 (patch) | |
| tree | c3623ff71d2c647f9fc0d1dcce9339b6cc5c508d /Source/Core/DSPCore/Src/DSPAnalyzer.cpp | |
| parent | 0030d5572590743525947a630797a1c11a885912 (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.cpp | 25 |
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() |
