check IRQ first then Idle loop
apparently I put it this way for a reason
This commit is contained in:
parent
ea734084ca
commit
f56aa60eb6
46
src/ARM.cpp
46
src/ARM.cpp
|
@ -660,19 +660,20 @@ void ARMv5::ExecuteJIT()
|
||||||
|
|
||||||
if (StopExecution)
|
if (StopExecution)
|
||||||
{
|
{
|
||||||
if (Halted || IdleLoop)
|
// this order is crucial otherwise idle loops waiting for an IRQ won't function
|
||||||
{
|
|
||||||
bool idleLoop = IdleLoop;
|
|
||||||
IdleLoop = 0;
|
|
||||||
if ((Halted == 1 || idleLoop) && NDS::ARM9Timestamp < NDS::ARM9Target)
|
|
||||||
{
|
|
||||||
NDS::ARM9Timestamp = NDS::ARM9Target;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IRQ)
|
if (IRQ)
|
||||||
TriggerIRQ();
|
TriggerIRQ();
|
||||||
|
|
||||||
|
if (Halted || IdleLoop)
|
||||||
|
{
|
||||||
|
if ((Halted == 1 || IdleLoop) && NDS::ARM9Timestamp < NDS::ARM9Target)
|
||||||
|
{
|
||||||
|
Cycles = 0;
|
||||||
|
NDS::ARM9Timestamp = NDS::ARM9Target;
|
||||||
|
}
|
||||||
|
IdleLoop = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDS::ARM9Timestamp += Cycles;
|
NDS::ARM9Timestamp += Cycles;
|
||||||
|
@ -808,22 +809,21 @@ void ARMv4::ExecuteJIT()
|
||||||
else
|
else
|
||||||
ARMJIT::CompileBlock(this);
|
ARMJIT::CompileBlock(this);
|
||||||
|
|
||||||
// TODO optimize this shit!!!
|
|
||||||
if (StopExecution)
|
if (StopExecution)
|
||||||
{
|
{
|
||||||
if (Halted || IdleLoop)
|
|
||||||
{
|
|
||||||
bool idleLoop = IdleLoop;
|
|
||||||
IdleLoop = 0;
|
|
||||||
if ((Halted == 1 || idleLoop) && NDS::ARM7Timestamp < NDS::ARM7Target)
|
|
||||||
{
|
|
||||||
NDS::ARM7Timestamp = NDS::ARM7Target;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IRQ)
|
if (IRQ)
|
||||||
TriggerIRQ();
|
TriggerIRQ();
|
||||||
|
|
||||||
|
if (Halted || IdleLoop)
|
||||||
|
{
|
||||||
|
if ((Halted == 1 || IdleLoop) && NDS::ARM7Timestamp < NDS::ARM7Target)
|
||||||
|
{
|
||||||
|
Cycles = 0;
|
||||||
|
NDS::ARM7Timestamp = NDS::ARM7Target;
|
||||||
|
}
|
||||||
|
IdleLoop = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NDS::ARM7Timestamp += Cycles;
|
NDS::ARM7Timestamp += Cycles;
|
||||||
|
|
|
@ -504,7 +504,7 @@ bool DecodeBranch(bool thumb, const FetchedInstr& instr, u32& cond, bool hasLink
|
||||||
return false;
|
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
|
// 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
|
// 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;
|
u16 regsDisallowedToWrite = 0;
|
||||||
for (int i = 0; i < instrsCount; i++)
|
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)
|
if (instrs[i].Info.SpecialKind == ARMInstrInfo::special_WriteMem)
|
||||||
return false;
|
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())
|
if (i < instrsCount - 1 && instrs[i].Info.Branches())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -852,10 +854,10 @@ void CompileBlock(ARM* cpu)
|
||||||
{
|
{
|
||||||
// we might have an idle loop
|
// we might have an idle loop
|
||||||
u32 backwardsOffset = (instrs[i].Addr - target) / (thumb ? 2 : 4);
|
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;
|
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)
|
else if (hasBranched && !isBackJump && i + 1 < Config::JIT_MaxBlockSize)
|
||||||
|
|
Loading…
Reference in New Issue