Core: Have CRegisters::DoTLBReadMiss set the target pipe line to jump, not directly modify the PC
This commit is contained in:
parent
fcd7257adc
commit
5da5dab3c5
|
@ -70,6 +70,7 @@ void CInterpreterCPU::ExecuteCPU()
|
|||
if (!g_MMU->MemoryValue32(PROGRAM_COUNTER, Opcode.Value))
|
||||
{
|
||||
g_Reg->DoTLBReadMiss(PipelineStage == PIPELINE_STAGE_JUMP, PROGRAM_COUNTER);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
continue;
|
||||
}
|
||||
|
@ -279,6 +280,7 @@ void CInterpreterCPU::ExecuteOps(int32_t Cycles)
|
|||
else
|
||||
{
|
||||
g_Reg->DoTLBReadMiss(PipelineStage == PIPELINE_STAGE_JUMP, PROGRAM_COUNTER);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3057,8 +3057,6 @@ void R4300iOp::GenerateTLBReadException(uint64_t VAddr, const char * function)
|
|||
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);
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||
}
|
||||
|
||||
void R4300iOp::GenerateTLBWriteException(uint64_t VAddr, const char * function)
|
||||
|
|
|
@ -614,11 +614,11 @@ void CRegisters::DoTLBReadMiss(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;
|
||||
}
|
||||
|
@ -628,8 +628,9 @@ void CRegisters::DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr)
|
|||
{
|
||||
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::DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr)
|
||||
|
|
|
@ -88,6 +88,8 @@ void CRecompiler::RecompilerMain_VirtualTable()
|
|||
if (!m_MMU.ValidVaddr(PC))
|
||||
{
|
||||
m_Registers.DoTLBReadMiss(false, PC);
|
||||
PC = g_System->m_JumpToLocation;
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
if (!m_MMU.ValidVaddr(PC))
|
||||
{
|
||||
g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PC).c_str());
|
||||
|
@ -153,6 +155,8 @@ void CRecompiler::RecompilerMain_Lookup()
|
|||
g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PROGRAM_COUNTER).c_str());
|
||||
m_EndEmulation = true;
|
||||
}
|
||||
PROGRAM_COUNTER = g_System->m_JumpToLocation;
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
continue;
|
||||
}
|
||||
if (PhysicalAddr < g_System->RdramSize())
|
||||
|
@ -211,6 +215,8 @@ void CRecompiler::RecompilerMain_Lookup_validate()
|
|||
g_Notify->DisplayError(stdstr_f("Failed to translate PC to a PAddr: %X\n\nEmulation stopped", PC).c_str());
|
||||
Done = true;
|
||||
}
|
||||
PROGRAM_COUNTER = g_System->m_JumpToLocation;
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
continue;
|
||||
}
|
||||
if (PhysicalAddr < g_System->RdramSize())
|
||||
|
|
|
@ -35,7 +35,7 @@ g_Notify->BreakPoint(__FILE__, __LINE__);
|
|||
}
|
||||
}*/
|
||||
|
||||
static void x86_compiler_Break_Point()
|
||||
void CX86RecompilerOps::x86CompilerBreakPoint()
|
||||
{
|
||||
g_Settings->SaveBool(Debugger_SteppingOps, true);
|
||||
do
|
||||
|
@ -51,6 +51,8 @@ static void x86_compiler_Break_Point()
|
|||
if (!g_MMU->MemoryValue32(g_Reg->m_PROGRAM_COUNTER, OpcodeValue))
|
||||
{
|
||||
g_Reg->DoTLBReadMiss(false, g_Reg->m_PROGRAM_COUNTER);
|
||||
g_Reg->m_PROGRAM_COUNTER = g_System->JumpToLocation();
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
|
@ -75,7 +77,7 @@ static void x86_compiler_Break_Point()
|
|||
}
|
||||
}
|
||||
|
||||
static void x86_Break_Point_DelaySlot()
|
||||
void CX86RecompilerOps::x86BreakPointDelaySlot()
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
|
@ -85,7 +87,7 @@ static void x86_Break_Point_DelaySlot()
|
|||
}
|
||||
if (g_Debugger->ExecutionBP(g_Reg->m_PROGRAM_COUNTER))
|
||||
{
|
||||
x86_compiler_Break_Point();
|
||||
x86CompilerBreakPoint();
|
||||
}
|
||||
if (g_System->PipelineStage() != PIPELINE_STAGE_NORMAL)
|
||||
{
|
||||
|
@ -102,7 +104,7 @@ static uint32_t memory_access_address;
|
|||
static uint32_t memory_write_in_delayslot;
|
||||
static uint32_t memory_breakpoint_found = 0;
|
||||
|
||||
static void x86MemoryBreakpoint()
|
||||
void CX86RecompilerOps::x86MemoryBreakPoint()
|
||||
{
|
||||
memory_breakpoint_found = 1;
|
||||
if (memory_write_in_delayslot)
|
||||
|
@ -111,70 +113,70 @@ static void x86MemoryBreakpoint()
|
|||
*g_NextTimer += g_System->CountPerOp();
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
}
|
||||
x86_compiler_Break_Point();
|
||||
x86CompilerBreakPoint();
|
||||
}
|
||||
|
||||
static void x86TestReadBreakpoint8()
|
||||
void CX86RecompilerOps::x86TestReadBreakPoint8()
|
||||
{
|
||||
if (g_Debugger->ReadBP8(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestReadBreakpoint16()
|
||||
void CX86RecompilerOps::x86TestReadBreakPoint16()
|
||||
{
|
||||
if (g_Debugger->ReadBP16(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestReadBreakpoint32()
|
||||
void CX86RecompilerOps::x86TestReadBreakPoint32()
|
||||
{
|
||||
if (g_Debugger->ReadBP32(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestReadBreakpoint64()
|
||||
void CX86RecompilerOps::x86TestReadBreakPoint64()
|
||||
{
|
||||
if (g_Debugger->ReadBP64(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestWriteBreakpoint8()
|
||||
void CX86RecompilerOps::x86TestWriteBreakPoint8()
|
||||
{
|
||||
if (g_Debugger->WriteBP8(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestWriteBreakpoint16()
|
||||
void CX86RecompilerOps::x86TestWriteBreakPoint16()
|
||||
{
|
||||
if (g_Debugger->WriteBP16(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestWriteBreakpoint32()
|
||||
void CX86RecompilerOps::x86TestWriteBreakPoint32()
|
||||
{
|
||||
if (g_Debugger->WriteBP32(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
static void x86TestWriteBreakpoint64()
|
||||
void CX86RecompilerOps::x86TestWriteBreakPoint64()
|
||||
{
|
||||
if (g_Debugger->WriteBP64(memory_access_address))
|
||||
{
|
||||
x86MemoryBreakpoint();
|
||||
x86MemoryBreakPoint();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3215,7 +3217,7 @@ void CX86RecompilerOps::LWL()
|
|||
m_Assembler.mov(OffsetReg, AddressReg);
|
||||
m_Assembler.and_(OffsetReg, 3);
|
||||
m_Assembler.and_(AddressReg, (uint32_t)~3);
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakpoint32, "x86TestReadBreakpoint32");
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakPoint32, "x86TestReadBreakpoint32");
|
||||
CompileLoadMemoryValue(AddressReg, AddressReg, x86Reg_Unknown, 32, false);
|
||||
m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rt);
|
||||
m_Assembler.AndVariableDispToX86Reg(m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), (void *)R4300iOp::LWL_MASK, "LWL_MASK", OffsetReg, CX86Ops::Multip_x4);
|
||||
|
@ -3595,7 +3597,7 @@ void CX86RecompilerOps::LWR()
|
|||
m_Assembler.mov(OffsetReg, AddressReg);
|
||||
m_Assembler.and_(OffsetReg, 3);
|
||||
m_Assembler.and_(AddressReg, (uint32_t)~3);
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakpoint32, "x86TestReadBreakpoint32");
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakPoint32, "x86TestReadBreakpoint32");
|
||||
CompileLoadMemoryValue(AddressReg, AddressReg, x86Reg_Unknown, 32, false);
|
||||
m_RegWorkingSet.Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.rt);
|
||||
m_Assembler.AndVariableDispToX86Reg(m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rt), (void *)R4300iOp::LWR_MASK, "LWR_MASK", OffsetReg, CX86Ops::Multip_x4);
|
||||
|
@ -3719,7 +3721,7 @@ void CX86RecompilerOps::SWL()
|
|||
}
|
||||
PreWriteInstruction();
|
||||
asmjit::x86::Gp shift = m_RegWorkingSet.Map_TempReg(asmjit::x86::ecx, -1, false, false), AddressReg = BaseOffsetAddress(false);
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakpoint32, "x86TestWriteBreakpoint32");
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakPoint32, "x86TestWriteBreakpoint32");
|
||||
|
||||
asmjit::x86::Gp TempReg2 = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
asmjit::x86::Gp OffsetReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
|
@ -3882,7 +3884,7 @@ void CX86RecompilerOps::SWR()
|
|||
PreWriteInstruction();
|
||||
asmjit::x86::Gp shift = m_RegWorkingSet.Map_TempReg(asmjit::x86::ecx, -1, false, false);
|
||||
asmjit::x86::Gp AddressReg = BaseOffsetAddress(false);
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakpoint32, "x86TestWriteBreakpoint32");
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakPoint32, "x86TestWriteBreakpoint32");
|
||||
asmjit::x86::Gp TempReg2 = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
asmjit::x86::Gp OffsetReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
asmjit::x86::Gp ValueReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
|
||||
|
@ -8453,7 +8455,7 @@ void CX86RecompilerOps::FoundMemoryBreakpoint()
|
|||
{
|
||||
ClearCachedInstructionInfo();
|
||||
m_Assembler.MoveConstToVariable(&memory_write_in_delayslot, "memory_write_in_delayslot", (m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT) ? 1 : 0);
|
||||
m_Assembler.CallFunc((uint32_t)x86MemoryBreakpoint, "x86MemoryBreakpoint");
|
||||
m_Assembler.CallFunc((uint32_t)x86MemoryBreakPoint, "x86MemoryBreakPoint");
|
||||
m_Assembler.MoveConstToVariable(&memory_breakpoint_found, "memory_breakpoint_found", 0);
|
||||
ExitCodeBlock();
|
||||
m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
|
||||
|
@ -9519,7 +9521,7 @@ void CX86RecompilerOps::CompileExecuteBP(void)
|
|||
{
|
||||
m_Assembler.CallThis((uint32_t)g_BaseSystem, AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem", 4);
|
||||
}
|
||||
m_Assembler.CallFunc((uint32_t)x86_compiler_Break_Point, "x86_compiler_Break_Point");
|
||||
m_Assembler.CallFunc((uint32_t)x86CompilerBreakPoint, "x86CompilerBreakPoint");
|
||||
ExitCodeBlock();
|
||||
m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
|
||||
}
|
||||
|
@ -9539,7 +9541,7 @@ void CX86RecompilerOps::CompileExecuteDelaySlotBP(void)
|
|||
{
|
||||
m_Assembler.CallThis((uint32_t)g_BaseSystem, AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem", 4);
|
||||
}
|
||||
m_Assembler.CallFunc((uint32_t)x86_Break_Point_DelaySlot, "x86_Break_Point_DelaySlot");
|
||||
m_Assembler.CallFunc((uint32_t)x86BreakPointDelaySlot, "x86BreakPointDelaySlot");
|
||||
ExitCodeBlock();
|
||||
m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
|
||||
}
|
||||
|
@ -9695,6 +9697,9 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
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);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);
|
||||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_TLBWriteMiss:
|
||||
|
@ -9832,22 +9837,22 @@ void CX86RecompilerOps::CompileLoadMemoryValue(asmjit::x86::Gp AddressReg, asmji
|
|||
if (ValueSize == 8)
|
||||
{
|
||||
AddressReg = BaseOffsetAddress(false);
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakpoint8, "x86TestReadBreakpoint8");
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakPoint8, "x86TestReadBreakpoint8");
|
||||
}
|
||||
else if (ValueSize == 16)
|
||||
{
|
||||
AddressReg = BaseOffsetAddress(false);
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakpoint16, "x86TestReadBreakpoint16");
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakPoint16, "x86TestReadBreakpoint16");
|
||||
}
|
||||
else if (ValueSize == 32)
|
||||
{
|
||||
AddressReg = BaseOffsetAddress(true);
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakpoint32, "x86TestReadBreakpoint32");
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakPoint32, "x86TestReadBreakpoint32");
|
||||
}
|
||||
else if (ValueSize == 64)
|
||||
{
|
||||
AddressReg = BaseOffsetAddress(true);
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakpoint64, "x86TestReadBreakpoint64");
|
||||
TestReadBreakpoint(AddressReg, (uint32_t)x86TestReadBreakPoint64, "x86TestReadBreakpoint64");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10018,19 +10023,19 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
|
|||
AddressReg = BaseOffsetAddress(ValueSize == 32);
|
||||
if (ValueSize == 8)
|
||||
{
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakpoint8, "x86TestWriteBreakpoint8");
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakPoint8, "x86TestWriteBreakpoint8");
|
||||
}
|
||||
else if (ValueSize == 16)
|
||||
{
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakpoint16, "x86TestWriteBreakpoint16");
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakPoint16, "x86TestWriteBreakpoint16");
|
||||
}
|
||||
else if (ValueSize == 32)
|
||||
{
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakpoint32, "x86TestWriteBreakpoint32");
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakPoint32, "x86TestWriteBreakpoint32");
|
||||
}
|
||||
else if (ValueSize == 64)
|
||||
{
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakpoint64, "x86TestWriteBreakpoint64");
|
||||
TestWriteBreakpoint(AddressReg, (uint32_t)x86TestWriteBreakPoint64, "x86TestWriteBreakpoint64");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -286,6 +286,18 @@ private:
|
|||
void CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo & ExitRegSet, ExitReason Reason, bool CompileNow, void (CX86Ops::*x86Jmp)(const char * LabelName, asmjit::Label & JumpLabel));
|
||||
void ResetMemoryStack();
|
||||
|
||||
static void x86CompilerBreakPoint();
|
||||
static void x86BreakPointDelaySlot();
|
||||
static void x86MemoryBreakPoint();
|
||||
static void x86TestReadBreakPoint8();
|
||||
static void x86TestReadBreakPoint16();
|
||||
static void x86TestReadBreakPoint32();
|
||||
static void x86TestReadBreakPoint64();
|
||||
static void x86TestWriteBreakPoint8();
|
||||
static void x86TestWriteBreakPoint16();
|
||||
static void x86TestWriteBreakPoint32();
|
||||
static void x86TestWriteBreakPoint64();
|
||||
|
||||
EXIT_LIST m_ExitInfo;
|
||||
CX86Ops m_Assembler;
|
||||
PIPELINE_STAGE m_PipelineStage;
|
||||
|
|
Loading…
Reference in New Issue