core: Create instruction region to update after a block
This commit is contained in:
parent
4a68941c08
commit
b8a514a483
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue