diff options
author | RSDuck <rsduck@users.noreply.github.com> | 2020-07-28 00:44:58 +0200 |
---|---|---|
committer | RSDuck <rsduck@users.noreply.github.com> | 2020-07-28 00:44:58 +0200 |
commit | f56aa60eb693ed41212960db60e01ceecf5d64c5 (patch) | |
tree | e61479f88a19c13b68bcf07a5a2c781649da00a8 /src | |
parent | ea734084cad4334e0a1247be99320e37f3bd2ee1 (diff) |
check IRQ first then Idle loop
apparently I put it this way for a reason
Diffstat (limited to 'src')
-rw-r--r-- | src/ARM.cpp | 26 | ||||
-rw-r--r-- | src/ARMJIT.cpp | 10 |
2 files changed, 19 insertions, 17 deletions
diff --git a/src/ARM.cpp b/src/ARM.cpp index c1743ea..7eeacb7 100644 --- a/src/ARM.cpp +++ b/src/ARM.cpp @@ -660,19 +660,20 @@ void ARMv5::ExecuteJIT() if (StopExecution) { + // this order is crucial otherwise idle loops waiting for an IRQ won't function + if (IRQ) + TriggerIRQ(); + if (Halted || IdleLoop) { - bool idleLoop = IdleLoop; - IdleLoop = 0; - if ((Halted == 1 || idleLoop) && NDS::ARM9Timestamp < NDS::ARM9Target) + if ((Halted == 1 || IdleLoop) && NDS::ARM9Timestamp < NDS::ARM9Target) { + Cycles = 0; NDS::ARM9Timestamp = NDS::ARM9Target; } + IdleLoop = 0; break; } - - if (IRQ) - TriggerIRQ(); } NDS::ARM9Timestamp += Cycles; @@ -808,22 +809,21 @@ void ARMv4::ExecuteJIT() else ARMJIT::CompileBlock(this); - // TODO optimize this shit!!! if (StopExecution) { + if (IRQ) + TriggerIRQ(); + if (Halted || IdleLoop) { - bool idleLoop = IdleLoop; - IdleLoop = 0; - if ((Halted == 1 || idleLoop) && NDS::ARM7Timestamp < NDS::ARM7Target) + if ((Halted == 1 || IdleLoop) && NDS::ARM7Timestamp < NDS::ARM7Target) { + Cycles = 0; NDS::ARM7Timestamp = NDS::ARM7Target; } + IdleLoop = 0; break; } - - if (IRQ) - TriggerIRQ(); } NDS::ARM7Timestamp += Cycles; diff --git a/src/ARMJIT.cpp b/src/ARMJIT.cpp index 72a3179..5b827e2 100644 --- a/src/ARMJIT.cpp +++ b/src/ARMJIT.cpp @@ -504,7 +504,7 @@ bool DecodeBranch(bool thumb, const FetchedInstr& instr, u32& cond, bool hasLink return false; } -bool IsIdleLoop(FetchedInstr* instrs, int instrsCount) +bool IsIdleLoop(bool thumb, FetchedInstr* instrs, int instrsCount) { // see https://github.com/dolphin-emu/dolphin/blob/master/Source/Core/Core/PowerPC/PPCAnalyst.cpp#L678 // it basically checks if one iteration of a loop depends on another @@ -515,9 +515,11 @@ bool IsIdleLoop(FetchedInstr* instrs, int instrsCount) u16 regsDisallowedToWrite = 0; for (int i = 0; i < instrsCount; i++) { - JIT_DEBUGPRINT("instr %d %x regs(%x %x) %x %x\n", i, instrs[i].Instr, instrs[i].Info.DstRegs, instrs[i].Info.SrcRegs, regsWrittenTo, regsDisallowedToWrite); + JIT_DEBUGPRINT("instr %d %08x regs(%x %x) %x %x\n", i, instrs[i].Instr, instrs[i].Info.DstRegs, instrs[i].Info.SrcRegs, regsWrittenTo, regsDisallowedToWrite); if (instrs[i].Info.SpecialKind == ARMInstrInfo::special_WriteMem) return false; + if (!thumb && instrs[i].Info.Kind >= ARMInstrInfo::ak_MSR_IMM && instrs[i].Info.Kind <= ARMInstrInfo::ak_MRC) + return false; if (i < instrsCount - 1 && instrs[i].Info.Branches()) return false; @@ -852,10 +854,10 @@ void CompileBlock(ARM* cpu) { // we might have an idle loop u32 backwardsOffset = (instrs[i].Addr - target) / (thumb ? 2 : 4); - if (IsIdleLoop(&instrs[i - backwardsOffset], backwardsOffset + 1)) + if (IsIdleLoop(thumb, &instrs[i - backwardsOffset], backwardsOffset + 1)) { instrs[i].BranchFlags |= branch_IdleBranch; - JIT_DEBUGPRINT("found %s idle loop %d in block %x\n", thumb ? "thumb" : "arm", cpu->Num, blockAddr); + JIT_DEBUGPRINT("found %s idle loop %d in block %08x\n", thumb ? "thumb" : "arm", cpu->Num, blockAddr); } } else if (hasBranched && !isBackJump && i + 1 < Config::JIT_MaxBlockSize) |