core: Create instruction region to update after a block

This commit is contained in:
zilmar 2025-02-06 16:09:31 +10:30
parent 4a68941c08
commit b8a514a483
3 changed files with 64 additions and 23 deletions

View File

@ -45,7 +45,10 @@ R4300iOp::R4300iOp(CN64System & System, bool Force32bit) :
m_FPR_S_L(System.m_Reg.m_FPR_S_L),
m_FPR_D(System.m_Reg.m_FPR_D),
m_FPCR(System.m_Reg.m_FPCR),
m_LLBit(System.m_Reg.m_LLBit)
m_LLBit(System.m_Reg.m_LLBit),
m_InstructionRegion(0),
m_InstructionMemory(nullptr),
m_InstructionPtr(nullptr)
{
m_Opcode.Value = 0;
BuildInterpreter(Force32bit);
@ -91,29 +94,10 @@ void R4300iOp::ExecuteOps(uint32_t Cycles)
int32_t & NextTimer = *g_NextTimer;
bool CheckTimer = false;
UpdateInstructionMemory();
while (!Done && Cycles > 0)
{
if ((uint64_t)((int32_t)m_PROGRAM_COUNTER) != m_PROGRAM_COUNTER)
{
uint32_t PAddr;
bool MemoryUnused;
if (!m_TLB.VAddrToPAddr(m_PROGRAM_COUNTER, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(m_PROGRAM_COUNTER, MemoryUnused ? EXC_RADE : EXC_RMISS);
m_PROGRAM_COUNTER = JumpToLocation;
PipelineStage = PIPELINE_STAGE_NORMAL;
continue;
}
m_MMU.LW_PhysicalAddress(PAddr, m_Opcode.Value);
}
else if (!m_MMU.MemoryValue32((uint32_t)m_PROGRAM_COUNTER, m_Opcode.Value))
{
m_Reg.TriggerAddressException((int32_t)m_PROGRAM_COUNTER, EXC_RMISS);
m_PROGRAM_COUNTER = JumpToLocation;
PipelineStage = PIPELINE_STAGE_NORMAL;
continue;
}
m_Opcode.Value = *m_InstructionPtr;
if (HaveDebugger())
{
if (HaveExecutionBP() && g_Debugger->ExecutionBP((uint32_t)m_PROGRAM_COUNTER))
@ -159,6 +143,8 @@ void R4300iOp::ExecuteOps(uint32_t Cycles)
}
m_PROGRAM_COUNTER += 4;
m_InstructionPtr++;
switch (PipelineStage)
{
case PIPELINE_STAGE_NORMAL:
@ -191,11 +177,13 @@ void R4300iOp::ExecuteOps(uint32_t Cycles)
SystemEvents.ExecuteEvents();
}
}
UpdateInstructionMemory();
break;
case PIPELINE_STAGE_JUMP_DELAY_SLOT:
PipelineStage = PIPELINE_STAGE_JUMP;
m_PROGRAM_COUNTER = JumpToLocation;
JumpToLocation = JumpDelayLocation;
UpdateInstructionMemory();
break;
case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
m_PROGRAM_COUNTER = JumpToLocation;
@ -206,10 +194,16 @@ void R4300iOp::ExecuteOps(uint32_t Cycles)
{
SystemEvents.ExecuteEvents();
}
UpdateInstructionMemory();
break;
default:
g_Notify->BreakPoint(__FILE__, __LINE__);
}
if ((((uint32_t)m_PROGRAM_COUNTER) & 0xFFFUL) == 0)
{
UpdateInstructionMemory();
}
}
g_SystemTimer->UpdateTimers();
}
@ -3962,3 +3956,43 @@ bool R4300iOp::SetFPUException(void)
}
return Res;
}
void R4300iOp::UpdateInstructionMemory()
{
if (m_InstructionRegion != (m_PROGRAM_COUNTER & ~0xFFFLL))
{
m_InstructionRegion = m_PROGRAM_COUNTER & ~0xFFFLL;
if ((uint64_t)((int32_t)m_PROGRAM_COUNTER) != m_PROGRAM_COUNTER)
{
uint32_t PAddr;
bool MemoryUnused;
if (!m_TLB.VAddrToPAddr(m_InstructionRegion, PAddr, MemoryUnused))
{
m_Reg.TriggerAddressException(m_PROGRAM_COUNTER, MemoryUnused ? EXC_RADE : EXC_RMISS);
m_PROGRAM_COUNTER = m_System.m_JumpToLocation;
m_System.m_PipelineStage = PIPELINE_STAGE_NORMAL;
UpdateInstructionMemory();
return;
}
if (PAddr >= m_MMU.RdramSize())
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
m_InstructionMemory = &m_MMU.Rdram()[PAddr];
}
else
{
m_InstructionMemory = m_MMU.MemoryPtr((uint32_t)m_InstructionRegion, 4, true);
if (m_InstructionMemory == nullptr)
{
m_Reg.TriggerAddressException((int32_t)m_PROGRAM_COUNTER, EXC_RMISS);
m_PROGRAM_COUNTER = m_System.m_JumpToLocation;
m_System.m_PipelineStage = PIPELINE_STAGE_NORMAL;
UpdateInstructionMemory();
return;
}
}
}
m_InstructionPtr = (uint32_t *)(((uint8_t *)m_InstructionMemory) + (m_PROGRAM_COUNTER & 0xFFFLL));
}

View File

@ -302,6 +302,9 @@ private:
double ** m_FPR_D;
uint32_t * m_FPCR;
uint32_t & m_LLBit;
uint64_t m_InstructionRegion;
uint8_t * m_InstructionMemory;
uint32_t * m_InstructionPtr;
Func Jump_Opcode[64];
Func Jump_Special[64];
@ -328,6 +331,7 @@ private:
bool CheckFPUInvalidException(void);
bool InitFpuOperation(FPRoundingMode RoundingModel);
bool SetFPUException(void);
void UpdateInstructionMemory();
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];

View File

@ -64,7 +64,10 @@ void CProfiling::ShowCPU_Usage()
{
PROFILE_TIMERS PreviousType = StopTimer();
uint64_t TotalTime = m_Timers[Timer_R4300] + m_Timers[Timer_RSP_Dlist] + m_Timers[Timer_RSP_Alist] + m_Timers[Timer_Idel];
if (TotalTime == 0)
{
return;
}
if (m_CurrentDisplayCount > 0)
{
m_CurrentDisplayCount -= 1;