Core: replace GenerateTLBReadException and void GenerateTLBWriteException with CRegisters::DoTLBReadMiss/CRegisters::DoTLBWriteMiss

This commit is contained in:
zilmar 2023-09-14 13:09:11 +09:30
parent 8b14b6d7d1
commit ae4af8746b
10 changed files with 66 additions and 89 deletions

View File

@ -69,7 +69,7 @@ void CInterpreterCPU::ExecuteCPU()
{
if (!g_MMU->MemoryValue32(PROGRAM_COUNTER, Opcode.Value))
{
g_Reg->DoTLBReadMiss(PipelineStage == PIPELINE_STAGE_JUMP, PROGRAM_COUNTER);
g_Reg->DoTLBReadMiss(PROGRAM_COUNTER);
PROGRAM_COUNTER = JumpToLocation;
PipelineStage = PIPELINE_STAGE_NORMAL;
continue;
@ -133,7 +133,7 @@ void CInterpreterCPU::ExecuteCPU()
PipelineStage = PIPELINE_STAGE_NORMAL;
if ((PROGRAM_COUNTER & 0x3) != 0)
{
GenerateAddressErrorException((int32_t)JumpToLocation, true);
g_Reg->DoAddressError((int32_t)JumpToLocation, true);
PROGRAM_COUNTER = JumpToLocation;
PipelineStage = PIPELINE_STAGE_NORMAL;
}
@ -281,7 +281,7 @@ void CInterpreterCPU::ExecuteOps(int32_t Cycles)
}
else
{
g_Reg->DoTLBReadMiss(PipelineStage == PIPELINE_STAGE_JUMP, PROGRAM_COUNTER);
g_Reg->DoTLBReadMiss(PROGRAM_COUNTER);
PROGRAM_COUNTER = JumpToLocation;
PipelineStage = PIPELINE_STAGE_NORMAL;
}

View File

@ -1091,7 +1091,7 @@ void R4300iOp::SWL()
}
else
{
GenerateTLBWriteException(Address, __FUNCTION__);
g_Reg->DoTLBWriteMiss(Address);
}
}
@ -1124,7 +1124,7 @@ void R4300iOp::SDL()
}
else
{
GenerateTLBWriteException(Address, __FUNCTION__);
g_Reg->DoTLBWriteMiss(Address);
}
}
@ -1152,7 +1152,7 @@ void R4300iOp::SDR()
}
else
{
GenerateTLBWriteException(Address, __FUNCTION__);
g_Reg->DoTLBWriteMiss(Address);
}
}
@ -1170,7 +1170,7 @@ void R4300iOp::SWR()
}
else
{
GenerateTLBWriteException(Address, __FUNCTION__);
g_Reg->DoTLBWriteMiss(Address);
}
}
@ -3043,31 +3043,6 @@ bool R4300iOp::MemoryBreakpoint()
return false;
}
void R4300iOp::GenerateAddressErrorException(uint64_t VAddr, bool FromRead)
{
g_Reg->DoAddressError(VAddr, FromRead);
}
void R4300iOp::GenerateTLBReadException(uint64_t VAddr, const char * function)
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, (uint32_t)VAddr).c_str());
}
g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr);
}
void R4300iOp::GenerateTLBWriteException(uint64_t VAddr, const char * function)
{
if (bShowTLBMisses())
{
g_Notify->DisplayError(stdstr_f("%s TLB: %X", function, (uint32_t)VAddr).c_str());
}
g_Reg->DoTLBWriteMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr);
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
}
bool R4300iOp::TestCop1UsableException(void)
{
if (g_Reg->STATUS_REGISTER.CU1 == 0)

View File

@ -260,9 +260,6 @@ protected:
static Func Jump_CoP1_L[64];
static Func Jump_CoP2[32];
static void GenerateAddressErrorException(uint64_t VAddr, bool FromRead);
static void GenerateTLBReadException(uint64_t VAddr, const char * function);
static void GenerateTLBWriteException(uint64_t VAddr, const char * function);
static bool TestCop1UsableException(void);
static bool CheckFPUInput32(const float & Value);
static bool CheckFPUInput32Conv(const float & Value);

View File

@ -365,7 +365,7 @@ bool CMipsMemoryVM::LB_Memory(uint64_t VAddr, uint8_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
@ -387,14 +387,14 @@ bool CMipsMemoryVM::LH_Memory(uint64_t VAddr, uint16_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 1) != 0)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
if (HaveReadBP() && g_Debugger->ReadBP16(VAddr32) && MemoryBreakpoint())
@ -414,13 +414,13 @@ bool CMipsMemoryVM::LW_Memory(uint64_t VAddr, uint32_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 3) != 0)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
if (HaveReadBP() && g_Debugger->ReadBP32(VAddr32) && MemoryBreakpoint())
@ -436,7 +436,7 @@ bool CMipsMemoryVM::LW_Memory(uint64_t VAddr, uint32_t & Value)
uint32_t BaseAddress = m_TLB_ReadMap[VAddr32 >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
m_Reg.DoTLBReadMiss(VAddr);
return false;
}
return LW_NonMemory(VAddr32, Value);
@ -446,14 +446,14 @@ bool CMipsMemoryVM::LD_Memory(uint64_t VAddr, uint64_t & Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 7) != 0)
{
GenerateAddressErrorException(VAddr, true);
m_Reg.DoAddressError(VAddr, true);
return false;
}
if (HaveReadBP() && g_Debugger->ReadBP64(VAddr32) && MemoryBreakpoint())
@ -479,7 +479,7 @@ bool CMipsMemoryVM::SB_Memory(uint64_t VAddr, uint32_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
@ -501,14 +501,14 @@ bool CMipsMemoryVM::SH_Memory(uint64_t VAddr, uint32_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 1) != 0)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
if (HaveWriteBP() && g_Debugger->WriteBP16(VAddr32) && MemoryBreakpoint())
@ -528,14 +528,14 @@ bool CMipsMemoryVM::SW_Memory(uint64_t VAddr, uint32_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr32 & 3) != 0)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
if (HaveWriteBP() && g_Debugger->WriteBP32(VAddr32) && MemoryBreakpoint())
@ -555,14 +555,14 @@ bool CMipsMemoryVM::SD_Memory(uint64_t VAddr, uint64_t Value)
{
if (!b32BitCore() && (uint64_t)((int32_t)VAddr) != VAddr)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
uint32_t VAddr32 = (uint32_t)VAddr;
if ((VAddr & 7) != 0)
{
GenerateAddressErrorException(VAddr, false);
m_Reg.DoAddressError(VAddr, false);
return false;
}
if (HaveWriteBP() && g_Debugger->WriteBP64(VAddr32) && MemoryBreakpoint())
@ -600,7 +600,7 @@ bool CMipsMemoryVM::LB_NonMemory(uint32_t VAddr, uint8_t & Value)
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
m_Reg.DoTLBReadMiss(VAddr);
return false;
}
@ -638,7 +638,7 @@ bool CMipsMemoryVM::LH_NonMemory(uint32_t VAddr, uint16_t & Value)
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
m_Reg.DoTLBReadMiss(VAddr);
return false;
}
@ -676,7 +676,7 @@ bool CMipsMemoryVM::LW_NonMemory(uint32_t VAddr, uint32_t & Value)
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
m_Reg.DoTLBReadMiss(VAddr);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
@ -720,7 +720,7 @@ bool CMipsMemoryVM::LD_NonMemory(uint32_t VAddr, uint64_t & Value)
uint32_t BaseAddress = m_TLB_ReadMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBReadException(VAddr, __FUNCTION__);
m_Reg.DoTLBReadMiss(VAddr);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
@ -740,7 +740,7 @@ bool CMipsMemoryVM::SB_NonMemory(uint32_t VAddr, uint32_t Value)
uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
m_Reg.DoTLBWriteMiss(VAddr);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
@ -781,7 +781,7 @@ bool CMipsMemoryVM::SH_NonMemory(uint32_t VAddr, uint32_t Value)
uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
m_Reg.DoTLBWriteMiss(VAddr);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
@ -834,7 +834,7 @@ bool CMipsMemoryVM::SW_NonMemory(uint32_t VAddr, uint32_t Value)
uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException((int64_t)((int32_t)VAddr), __FUNCTION__);
m_Reg.DoTLBWriteMiss((int64_t)((int32_t)VAddr));
return false;
}
uint32_t PAddr = BaseAddress + VAddr;
@ -904,7 +904,7 @@ bool CMipsMemoryVM::SD_NonMemory(uint32_t VAddr, uint64_t Value)
uint32_t BaseAddress = m_TLB_WriteMap[VAddr >> 12];
if (BaseAddress == -1)
{
GenerateTLBWriteException(VAddr, __FUNCTION__);
m_Reg.DoTLBWriteMiss(VAddr);
return false;
}
uint32_t PAddr = BaseAddress + VAddr;

View File

@ -806,7 +806,7 @@ bool CRegisters::DoIntrException()
return true;
}
void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr)
void CRegisters::DoTLBReadMiss(uint64_t BadVaddr)
{
CAUSE_REGISTER.ExceptionCode = EXC_RMISS;
CAUSE_REGISTER.CoprocessorUnitNumber = 0;
@ -815,7 +815,7 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr)
ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000);
if ((STATUS_REGISTER.ExceptionLevel) == 0)
{
if (DelaySlot)
if (m_System.m_PipelineStage == PIPELINE_STAGE_JUMP)
{
CAUSE_REGISTER.BranchDelay = 1;
EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - 4);
@ -837,16 +837,12 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr)
}
else
{
if (HaveDebugger())
{
g_Notify->DisplayError(stdstr_f("TLBMiss - EXL set\nBadVaddr = %X\nAddress defined: %s", (uint32_t)BadVaddr, g_TLB->AddressDefined((uint32_t)BadVaddr) ? "true" : "false").c_str());
}
m_System.m_JumpToLocation = 0x80000180;
}
m_System.m_PipelineStage = PIPELINE_STAGE_JUMP;
}
void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr)
void CRegisters::DoTLBWriteMiss(uint64_t BadVaddr)
{
CAUSE_REGISTER.ExceptionCode = EXC_WMISS;
CAUSE_REGISTER.CoprocessorUnitNumber = 0;
@ -855,7 +851,7 @@ void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr)
ENTRYHI_REGISTER = (BadVaddr & 0xFFFFE000);
if ((STATUS_REGISTER.ExceptionLevel) == 0)
{
if (DelaySlot)
if (g_System->m_PipelineStage == PIPELINE_STAGE_JUMP)
{
CAUSE_REGISTER.BranchDelay = 1;
EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - 4);
@ -867,25 +863,22 @@ void CRegisters::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr)
}
if (g_TLB->AddressDefined((uint32_t)BadVaddr))
{
m_PROGRAM_COUNTER = 0x80000180;
m_System.m_JumpToLocation = 0x80000180;
}
else
{
m_PROGRAM_COUNTER = 0x80000000;
m_System.m_JumpToLocation = 0x80000000;
}
STATUS_REGISTER.ExceptionLevel = 1;
}
else
{
if (HaveDebugger())
{
g_Notify->DisplayError(stdstr_f("TLBMiss - EXL set\nBadVaddr = %X\nAddress defined: %s", (uint32_t)BadVaddr, g_TLB->AddressDefined((uint32_t)BadVaddr) ? "true" : "false").c_str());
}
m_PROGRAM_COUNTER = 0x80000180;
m_System.m_JumpToLocation = 0x80000180;
}
m_System.m_PipelineStage = PIPELINE_STAGE_JUMP;
}
void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor)
void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor, bool SpecialOffset)
{
if (GenerateLog() && LogExceptions())
{
@ -899,11 +892,29 @@ void CRegisters::TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor)
}
}
uint32_t ExceptionBase = 0x80000000;
uint16_t ExceptionOffset = 0x0180;
if (SpecialOffset && STATUS_REGISTER.ExceptionLevel == 0)
{
switch (STATUS_REGISTER.PrivilegeMode)
{
case PrivilegeMode_Kernel:
ExceptionOffset = STATUS_REGISTER.KernelExtendedAddressing == 0 ? 0x0000 : 0x0080;
break;
case PrivilegeMode_Supervisor:
ExceptionOffset = STATUS_REGISTER.SupervisorExtendedAddressing == 0 ? 0x0000 : 0x0080;
break;
case PrivilegeMode_User:
ExceptionOffset = STATUS_REGISTER.UserExtendedAddressing == 0 ? 0x0000 : 0x0080;
break;
}
}
CAUSE_REGISTER.ExceptionCode = ExceptionCode;
CAUSE_REGISTER.CoprocessorUnitNumber = Coprocessor;
CAUSE_REGISTER.BranchDelay = m_System.m_PipelineStage == PIPELINE_STAGE_JUMP;
EPC_REGISTER = (int64_t)((int32_t)m_PROGRAM_COUNTER - (CAUSE_REGISTER.BranchDelay ? 4 : 0));
STATUS_REGISTER.ExceptionLevel = 1;
m_System.m_PipelineStage = PIPELINE_STAGE_JUMP;
m_System.m_JumpToLocation = 0x80000180;
m_System.m_JumpToLocation = ExceptionBase | ExceptionOffset;
}

View File

@ -453,12 +453,12 @@ public:
void CheckInterrupts();
void DoAddressError(uint64_t BadVaddr, bool FromRead);
bool DoIntrException();
void DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr);
void DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr);
void DoTLBReadMiss(uint64_t BadVaddr);
void DoTLBWriteMiss(uint64_t BadVaddr);
void FixFpuLocations();
void Reset(bool bPostPif, CMipsMemoryVM & MMU);
void SetAsCurrentSystem();
void TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor = 0);
void TriggerException(uint32_t ExceptionCode, uint32_t Coprocessor = 0, bool SpecialOffset = false);
uint64_t Cop0_MF(COP0Reg Reg);
void Cop0_MT(COP0Reg Reg, uint64_t Value);

View File

@ -87,7 +87,7 @@ void CRecompiler::RecompilerMain_VirtualTable()
{
if (!m_MMU.ValidVaddr(PC))
{
m_Registers.DoTLBReadMiss(false, PC);
m_Registers.DoTLBReadMiss(PC);
PC = g_System->m_JumpToLocation;
g_System->m_PipelineStage = PIPELINE_STAGE_NORMAL;
if (!m_MMU.ValidVaddr(PC))
@ -149,7 +149,7 @@ void CRecompiler::RecompilerMain_Lookup()
{
if (!m_MMU.VAddrToPAddr(PROGRAM_COUNTER, PhysicalAddr))
{
m_Registers.DoTLBReadMiss(false, PROGRAM_COUNTER);
m_Registers.DoTLBReadMiss(PROGRAM_COUNTER);
if (!m_MMU.VAddrToPAddr(PROGRAM_COUNTER, PhysicalAddr))
{
g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PROGRAM_COUNTER).c_str());
@ -209,7 +209,7 @@ void CRecompiler::RecompilerMain_Lookup_validate()
{
if (!m_MMU.VAddrToPAddr(PC, PhysicalAddr))
{
m_Registers.DoTLBReadMiss(false, PC);
m_Registers.DoTLBReadMiss(PC);
if (!m_MMU.VAddrToPAddr(PC, PhysicalAddr))
{
g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PC).c_str());

View File

@ -50,7 +50,7 @@ void CX86RecompilerOps::x86CompilerBreakPoint()
uint32_t OpcodeValue;
if (!g_MMU->MemoryValue32(g_Reg->m_PROGRAM_COUNTER, OpcodeValue))
{
g_Reg->DoTLBReadMiss(false, g_Reg->m_PROGRAM_COUNTER);
g_Reg->DoTLBReadMiss(g_Reg->m_PROGRAM_COUNTER);
g_Reg->m_PROGRAM_COUNTER = g_System->JumpToLocation();
g_System->m_PipelineStage = PIPELINE_STAGE_NORMAL;
continue;
@ -9693,9 +9693,9 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
ExitCodeBlock();
break;
case ExitReason_TLBReadMiss:
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
m_Assembler.MoveVariableToX86reg(asmjit::x86::edx, g_TLBLoadAddress, "g_TLBLoadAddress");
m_Assembler.push(asmjit::x86::edx);
m_Assembler.PushImm32(InDelaySlot ? "true" : "false", InDelaySlot);
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoTLBReadMiss), "CRegisters::DoTLBReadMiss", 12);
m_Assembler.MoveVariableToX86reg(asmjit::x86::edx, &g_System->m_JumpToLocation, "System->m_JumpToLocation");
m_Assembler.MoveX86regToVariable(&g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER", asmjit::x86::edx);

View File

@ -12,7 +12,6 @@ bool CDebugSettings::m_Stepping = false;
bool CDebugSettings::m_SkipOp = false;
bool CDebugSettings::m_WaitingForStep = false;
bool CDebugSettings::m_bRecordRecompilerAsm = false;
bool CDebugSettings::m_bShowTLBMisses = false;
bool CDebugSettings::m_RecordExecutionTimes = false;
bool CDebugSettings::m_HaveExecutionBP = false;
bool CDebugSettings::m_HaveWriteBP = false;

View File

@ -32,10 +32,6 @@ public:
{
return m_bRecordRecompilerAsm;
}
static inline bool bShowTLBMisses(void)
{
return m_bShowTLBMisses;
}
static inline bool bRecordExecutionTimes(void)
{
return m_RecordExecutionTimes;
@ -111,7 +107,6 @@ private:
static bool m_SkipOp;
static bool m_WaitingForStep;
static bool m_bRecordRecompilerAsm;
static bool m_bShowTLBMisses;
static bool m_RecordExecutionTimes;
static bool m_HaveExecutionBP;
static bool m_HaveWriteBP;