reimplement forced interlocks
This commit is contained in:
parent
9a4dc94910
commit
98f24d05c7
|
@ -1447,6 +1447,11 @@ void ARMv5::HandleInterlocksMemory_2()
|
||||||
ILPrevTime = 16;
|
ILPrevTime = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMv5::ForceInterlock_2()
|
||||||
|
{
|
||||||
|
NDS.ARM9Timestamp = TimestampMemory + ILForceDelay;
|
||||||
|
}
|
||||||
|
|
||||||
void ARMv4::CodeRead16(u32 addr)
|
void ARMv4::CodeRead16(u32 addr)
|
||||||
{
|
{
|
||||||
if ((addr >> 24) == 0x02)
|
if ((addr >> 24) == 0x02)
|
||||||
|
|
|
@ -372,6 +372,12 @@ public:
|
||||||
QueueFunction(&ARMv5::HandleInterlocksExecute_2);
|
QueueFunction(&ARMv5::HandleInterlocksExecute_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void ForceInterlock(s8 delay = 0)
|
||||||
|
{
|
||||||
|
ILForceDelay = delay;
|
||||||
|
QueueFunction(&ARMv5::ForceInterlock_2);
|
||||||
|
}
|
||||||
|
|
||||||
inline void HandleInterlocksMemory(u8 reg)
|
inline void HandleInterlocksMemory(u8 reg)
|
||||||
{
|
{
|
||||||
ILQueueMemReg = reg;
|
ILQueueMemReg = reg;
|
||||||
|
@ -726,6 +732,7 @@ public:
|
||||||
void SetupInterlock_2();
|
void SetupInterlock_2();
|
||||||
void HandleInterlocksExecute_2();
|
void HandleInterlocksExecute_2();
|
||||||
void HandleInterlocksMemory_2();
|
void HandleInterlocksMemory_2();
|
||||||
|
void ForceInterlock_2();
|
||||||
void QueueUpdateMode() { UpdateMode(QueueMode[0], QueueMode[1], true); }
|
void QueueUpdateMode() { UpdateMode(QueueMode[0], QueueMode[1], true); }
|
||||||
void SignExtend8() { R[ExtReg] = (s32)(s8)R[ExtReg]; }
|
void SignExtend8() { R[ExtReg] = (s32)(s8)R[ExtReg]; }
|
||||||
void SignExtend16() { R[ExtReg] = (s32)(s16)R[ExtReg]; }
|
void SignExtend16() { R[ExtReg] = (s32)(s16)R[ExtReg]; }
|
||||||
|
@ -812,6 +819,7 @@ public:
|
||||||
u64 ICacheStreamTimes[7];
|
u64 ICacheStreamTimes[7];
|
||||||
u64 DCacheStreamTimes[7];
|
u64 DCacheStreamTimes[7];
|
||||||
|
|
||||||
|
s8 ILForceDelay;
|
||||||
u8 WBWritePointer; // which entry to attempt to write next; should always be ANDed with 0xF after incrementing
|
u8 WBWritePointer; // which entry to attempt to write next; should always be ANDed with 0xF after incrementing
|
||||||
u8 WBFillPointer; // where the next entry should be added; should always be ANDed with 0xF after incrementing
|
u8 WBFillPointer; // where the next entry should be added; should always be ANDed with 0xF after incrementing
|
||||||
u8 WBWriting; // whether the buffer is actively trying to perform a write
|
u8 WBWriting; // whether the buffer is actively trying to perform a write
|
||||||
|
|
|
@ -170,7 +170,7 @@ void LoadSingle(ARM* cpu, const u8 rd, const u8 rn, const s32 offset, const u16
|
||||||
|
|
||||||
if (rd == 15)
|
if (rd == 15)
|
||||||
{
|
{
|
||||||
//if (cpu->Num==0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory + ((size<32) || (addr&0x3)); // force an interlock
|
if (cpu->Num==0) ((ARMv5*)cpu)->ForceInterlock((size<32) || (addr&0x3));
|
||||||
|
|
||||||
cpu->JumpTo(cpu->R[15], false, 1);
|
cpu->JumpTo(cpu->R[15], false, 1);
|
||||||
}
|
}
|
||||||
|
@ -373,7 +373,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
((ARMv5*)cpu)->DataAbort(); \
|
((ARMv5*)cpu)->DataAbort(); \
|
||||||
return; } \
|
return; } \
|
||||||
if (r+1 == 15) { \
|
if (r+1 == 15) { \
|
||||||
/*if (cpu->Num==0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory;*/ \
|
if (cpu->Num==0) ((ARMv5*)cpu)->ForceInterlock(); \
|
||||||
cpu->JumpTo(cpu->R[15], cpu->CurInstr & (1<<22), 1); } /* restores cpsr presumably due to shared dna with ldm */ \
|
cpu->JumpTo(cpu->R[15], cpu->CurInstr & (1<<22), 1); } /* restores cpsr presumably due to shared dna with ldm */ \
|
||||||
else { \
|
else { \
|
||||||
if (cpu->Num == 0) ((ARMv5*)cpu)->SetupInterlock(r+1); } \
|
if (cpu->Num == 0) ((ARMv5*)cpu)->SetupInterlock(r+1); } \
|
||||||
|
@ -395,7 +395,7 @@ A_IMPLEMENT_WB_LDRSTR(LDRB)
|
||||||
((ARMv5*)cpu)->DataAbort(); \
|
((ARMv5*)cpu)->DataAbort(); \
|
||||||
return; } \
|
return; } \
|
||||||
if (r+1 == 15) { \
|
if (r+1 == 15) { \
|
||||||
/*if (cpu->Num==0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory;*/ \
|
if (cpu->Num==0) ((ARMv5*)cpu)->ForceInterlock(); ; \
|
||||||
cpu->JumpTo(cpu->R[15], cpu->CurInstr & (1<<22), 1); } /* restores cpsr presumably due to shared dna with ldm */ \
|
cpu->JumpTo(cpu->R[15], cpu->CurInstr & (1<<22), 1); } /* restores cpsr presumably due to shared dna with ldm */ \
|
||||||
else { \
|
else { \
|
||||||
if (cpu->Num == 0) ((ARMv5*)cpu)->SetupInterlock(r+1); } \
|
if (cpu->Num == 0) ((ARMv5*)cpu)->SetupInterlock(r+1); } \
|
||||||
|
@ -681,7 +681,7 @@ void A_LDM(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CDI();
|
cpu->AddCycles_CDI();
|
||||||
if (cpu->Num == 0) ;//cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -739,7 +739,7 @@ void A_LDM(ARM* cpu)
|
||||||
// jump if pc got written
|
// jump if pc got written
|
||||||
if (cpu->CurInstr & (1<<15))
|
if (cpu->CurInstr & (1<<15))
|
||||||
{
|
{
|
||||||
//if (cpu->Num==0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // force an interlock
|
if (cpu->Num==0) ((ARMv5*)cpu)->ForceInterlock();
|
||||||
cpu->JumpTo(cpu->R[15], cpu->CurInstr & (1<<22), 1);
|
cpu->JumpTo(cpu->R[15], cpu->CurInstr & (1<<22), 1);
|
||||||
}
|
}
|
||||||
else if (cpu->Num == 0)
|
else if (cpu->Num == 0)
|
||||||
|
@ -831,7 +831,7 @@ void A_STM(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CD();
|
cpu->AddCycles_CD();
|
||||||
if (cpu->Num == 0);// cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1015,7 +1015,7 @@ void T_PUSH(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CD();
|
cpu->AddCycles_CD();
|
||||||
if (cpu->Num == 0);// cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1071,7 +1071,7 @@ void T_POP(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CDI();
|
cpu->AddCycles_CDI();
|
||||||
if (cpu->Num == 0);// cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1082,7 +1082,7 @@ void T_POP(ARM* cpu)
|
||||||
|
|
||||||
if (!dabort) [[likely]]
|
if (!dabort) [[likely]]
|
||||||
{
|
{
|
||||||
//if (cpu->Num==0) cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // force an interlock
|
if (cpu->Num==0) ((ARMv5*)cpu)->ForceInterlock();
|
||||||
|
|
||||||
cpu->JumpTo(cpu->R[15], false, 2);
|
cpu->JumpTo(cpu->R[15], false, 2);
|
||||||
base += 4;
|
base += 4;
|
||||||
|
@ -1101,7 +1101,7 @@ void T_POP(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CDI();
|
cpu->AddCycles_CDI();
|
||||||
if (cpu->Num == 0);// cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1162,7 +1162,7 @@ void T_STMIA(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CD();
|
cpu->AddCycles_CD();
|
||||||
if (cpu->Num == 0);// cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1212,7 +1212,7 @@ void T_LDMIA(ARM* cpu)
|
||||||
{
|
{
|
||||||
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
//if (cpu->Num == 0 && cpu->DataRegion == Mem9_ITCM) cpu->NDS.ARM9Timestamp += 1;
|
||||||
cpu->AddCycles_CDI();
|
cpu->AddCycles_CDI();
|
||||||
if (cpu->Num == 0);// cpu->NDS.ARM9Timestamp = ((ARMv5*)cpu)->TimestampMemory; // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
if (cpu->Num == 0) ((ARMv5*)cpu)->ForceInterlock(); // on arm9 single reg ldm/stm cannot overlap memory and fetch stages
|
||||||
else; // CHECKME: ARM7 timing behavior?
|
else; // CHECKME: ARM7 timing behavior?
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
Loading…
Reference in New Issue