improve stm timings

need to verify if they apply to all store instructions
This commit is contained in:
Jaklyy 2024-06-24 22:50:04 -04:00
parent 109bbed3d0
commit dbe00e72dd
3 changed files with 40 additions and 29 deletions

View File

@ -1259,6 +1259,31 @@ bool ARMv4::DataWrite32S(u32 addr, u32 val, bool dataabort)
} }
void ARMv5::AddCycles_CD()
{
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
s32 numD = DataCycles;
s32 early;
if (DataRegion == Mem9_ITCM)
{
early = (CodeRegion == Mem9_ITCM) ? -1 : 0;
}
else if (DataRegion == Mem9_DTCM)
{
early = 2;
}
else if (DataRegion == Mem9_MainRAM)
{
early = (CodeRegion == Mem9_MainRAM) ? 0 : 18; // CHECKME: how early can main ram be?
}
else early = (DataRegion == CodeRegion) ? 4 : 6;
s32 code = numC - early;
if (code < 0) code = 0;
Cycles += std::max(code + numD, numC);
}
void ARMv5::AddCycles_CDI() void ARMv5::AddCycles_CDI()
{ {
// LDR/LDM cycles. ARM9 seems to skip the internal cycle there. // LDR/LDM cycles. ARM9 seems to skip the internal cycle there.
@ -1269,7 +1294,7 @@ void ARMv5::AddCycles_CDI()
s32 early; s32 early;
switch (DataRegion) switch (DataRegion)
{ {
case 0: // background region; CHECKME case 0: // background region;
case Mem9_DTCM: case Mem9_DTCM:
case Mem9_BIOS: case Mem9_BIOS:
case Mem9_WRAM: case Mem9_WRAM:
@ -1297,17 +1322,10 @@ void ARMv5::AddCycles_CDI()
early = (CodeRegion == Mem9_ITCM) ? -1 : 0; early = (CodeRegion == Mem9_ITCM) ? -1 : 0;
break; break;
} }
if (numD > early) s32 code = numC - early;
{ if (code < 0) code = 0;
numC -= early; Cycles += std::max(code + numD, numC);
if (numC < 0) numC = 0;
Cycles += numC + numD;
}
else
{
Cycles += numC;
}
} }
void ARMv4::AddCycles_C() void ARMv4::AddCycles_C()

View File

@ -327,17 +327,7 @@ public:
void AddCycles_CDI() override; void AddCycles_CDI() override;
void AddCycles_CD() override void AddCycles_CD() override;
{
// TODO: ITCM data fetches shouldn't be parallelized, they say
s32 numC = (R[15] & 0x2) ? 0 : CodeCycles;
s32 numD = DataCycles;
//if (DataRegion != CodeRegion)
Cycles += std::max(numC + numD - 6, std::max(numC, numD));
//else
// Cycles += numC + numD;
}
#ifdef INTERLOCK #ifdef INTERLOCK
// fetch the value of a register while handling any interlock cycles // fetch the value of a register while handling any interlock cycles

View File

@ -934,10 +934,9 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
return false; return false;
} }
DataRegion = addr;
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = Mem9_ITCM;
DataCycles = 1; DataCycles = 1;
*(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; *(u8*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
@ -945,12 +944,14 @@ bool ARMv5::DataWrite8(u32 addr, u8 val)
} }
if ((addr & DTCMMask) == DTCMBase) if ((addr & DTCMMask) == DTCMBase)
{ {
DataRegion = Mem9_DTCM;
DataCycles = 1; DataCycles = 1;
*(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; *(u8*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true; return true;
} }
BusWrite8(addr, val); BusWrite8(addr, val);
DataRegion = NDS.ARM9Regions[addr >> 14];
DataCycles = MemTimings[addr >> 12][1]; DataCycles = MemTimings[addr >> 12][1];
return true; return true;
} }
@ -963,12 +964,11 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
return false; return false;
} }
DataRegion = addr;
addr &= ~1; addr &= ~1;
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = Mem9_ITCM;
DataCycles = 1; DataCycles = 1;
*(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; *(u16*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
@ -976,12 +976,14 @@ bool ARMv5::DataWrite16(u32 addr, u16 val)
} }
if ((addr & DTCMMask) == DTCMBase) if ((addr & DTCMMask) == DTCMBase)
{ {
DataRegion = Mem9_DTCM;
DataCycles = 1; DataCycles = 1;
*(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; *(u16*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true; return true;
} }
BusWrite16(addr, val); BusWrite16(addr, val);
DataRegion = NDS.ARM9Regions[addr >> 14];
DataCycles = MemTimings[addr >> 12][1]; DataCycles = MemTimings[addr >> 12][1];
return true; return true;
} }
@ -994,12 +996,11 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
return false; return false;
} }
DataRegion = addr;
addr &= ~3; addr &= ~3;
if (addr < ITCMSize) if (addr < ITCMSize)
{ {
DataRegion = Mem9_ITCM;
DataCycles = 1; DataCycles = 1;
*(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val; *(u32*)&ITCM[addr & (ITCMPhysicalSize - 1)] = val;
NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr); NDS.JIT.CheckAndInvalidate<0, ARMJIT_Memory::memregion_ITCM>(addr);
@ -1007,12 +1008,14 @@ bool ARMv5::DataWrite32(u32 addr, u32 val)
} }
if ((addr & DTCMMask) == DTCMBase) if ((addr & DTCMMask) == DTCMBase)
{ {
DataRegion = Mem9_DTCM;
DataCycles = 1; DataCycles = 1;
*(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val; *(u32*)&DTCM[addr & (DTCMPhysicalSize - 1)] = val;
return true; return true;
} }
BusWrite32(addr, val); BusWrite32(addr, val);
DataRegion = NDS.ARM9Regions[addr >> 14];
DataCycles = MemTimings[addr >> 12][2]; DataCycles = MemTimings[addr >> 12][2];
return true; return true;
} }