Core: Handle more with LW and invalid addresses
This commit is contained in:
parent
082ec9c22e
commit
801a3e29fc
|
@ -17,7 +17,8 @@ enum ExitReason
|
||||||
ExitReason_TLBWriteMiss,
|
ExitReason_TLBWriteMiss,
|
||||||
ExitReason_ResetRecompCode,
|
ExitReason_ResetRecompCode,
|
||||||
ExitReason_ExceptionOverflow,
|
ExitReason_ExceptionOverflow,
|
||||||
ExitReason_AddressErrorExceptionRead,
|
ExitReason_AddressErrorExceptionRead32,
|
||||||
|
ExitReason_AddressErrorExceptionRead64,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CExitInfo
|
struct CExitInfo
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
uint32_t CX86RecompilerOps::m_TempValue32 = 0;
|
uint32_t CX86RecompilerOps::m_TempValue32 = 0;
|
||||||
|
uint64_t CX86RecompilerOps::m_TempValue64 = 0;
|
||||||
uint32_t CX86RecompilerOps::m_BranchCompare = 0;
|
uint32_t CX86RecompilerOps::m_BranchCompare = 0;
|
||||||
|
|
||||||
/*int TestValue = 0;
|
/*int TestValue = 0;
|
||||||
|
@ -3163,8 +3164,7 @@ void CX86RecompilerOps::LW(bool ResultSigned, bool bRecordLLBit)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PreReadInstruction();
|
PreReadInstruction();
|
||||||
Map_GPR_32bit(m_Opcode.rt, ResultSigned, m_Opcode.base == m_Opcode.rt ? m_Opcode.rt : -1);
|
CompileLoadMemoryValue(CX86Ops::x86_Unknown, CX86Ops::x86_Unknown, CX86Ops::x86_Unknown, 32, false);
|
||||||
CompileLoadMemoryValue(CX86Ops::x86_Unknown, GetMipsRegMapLo(m_Opcode.rt), CX86Ops::x86_Unknown, 32, false);
|
|
||||||
if (bRecordLLBit)
|
if (bRecordLLBit)
|
||||||
{
|
{
|
||||||
m_Assembler.MoveConstToVariable(1, _LLBit, "LLBit");
|
m_Assembler.MoveConstToVariable(1, _LLBit, "LLBit");
|
||||||
|
@ -9615,7 +9615,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
||||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoOverflowException), "CRegisters::DoOverflowException", 12);
|
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoOverflowException), "CRegisters::DoOverflowException", 12);
|
||||||
ExitCodeBlock();
|
ExitCodeBlock();
|
||||||
break;
|
break;
|
||||||
case ExitReason_AddressErrorExceptionRead:
|
case ExitReason_AddressErrorExceptionRead32:
|
||||||
m_Assembler.PushImm32("1", 1);
|
m_Assembler.PushImm32("1", 1);
|
||||||
m_Assembler.MoveVariableToX86reg(&m_TempValue32, "TempValue32", CX86Ops::x86_EDX);
|
m_Assembler.MoveVariableToX86reg(&m_TempValue32, "TempValue32", CX86Ops::x86_EDX);
|
||||||
m_Assembler.MoveX86RegToX86Reg(CX86Ops::x86_EDX, CX86Ops::x86_EAX);
|
m_Assembler.MoveX86RegToX86Reg(CX86Ops::x86_EDX, CX86Ops::x86_EAX);
|
||||||
|
@ -9626,6 +9626,16 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
||||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoAddressError), "CRegisters::DoAddressError", 12);
|
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoAddressError), "CRegisters::DoAddressError", 12);
|
||||||
ExitCodeBlock();
|
ExitCodeBlock();
|
||||||
break;
|
break;
|
||||||
|
case ExitReason_AddressErrorExceptionRead64:
|
||||||
|
m_Assembler.PushImm32("1", 1);
|
||||||
|
m_Assembler.MoveVariableToX86reg(&m_TempValue64, "TempValue64", CX86Ops::x86_EDX);
|
||||||
|
m_Assembler.MoveVariableToX86reg(&m_TempValue64 + 4, "TempValue64+4", CX86Ops::x86_EAX);
|
||||||
|
m_Assembler.Push(CX86Ops::x86_EAX);
|
||||||
|
m_Assembler.Push(CX86Ops::x86_EDX);
|
||||||
|
m_Assembler.PushImm32(InDelaySlot ? "true" : "false", InDelaySlot);
|
||||||
|
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoAddressError), "CRegisters::DoAddressError", 12);
|
||||||
|
ExitCodeBlock();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
WriteTrace(TraceRecompiler, TraceError, "How did you want to exit on reason (%d) ???", reason);
|
WriteTrace(TraceRecompiler, TraceError, "How did you want to exit on reason (%d) ???", reason);
|
||||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||||
|
@ -9663,6 +9673,37 @@ CX86Ops::x86Reg CX86RecompilerOps::BaseOffsetAddress(bool UseBaseRegister)
|
||||||
AddressReg = Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.base, false, false);
|
AddressReg = Map_TempReg(CX86Ops::x86_Unknown, m_Opcode.base, false, false);
|
||||||
m_Assembler.AddConstToX86Reg(AddressReg, (int16_t)m_Opcode.immediate);
|
m_Assembler.AddConstToX86Reg(AddressReg, (int16_t)m_Opcode.immediate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!b32BitCore() && ((IsKnown(m_Opcode.base) && Is64Bit(m_Opcode.base)) || IsUnknown(m_Opcode.base)))
|
||||||
|
{
|
||||||
|
m_Assembler.MoveX86regToVariable(AddressReg, &m_TempValue64, "TempValue64");
|
||||||
|
CX86Ops::x86Reg AddressRegHi = Map_TempReg(CX86Ops::x86_Unknown, -1, false, false);
|
||||||
|
m_Assembler.MoveX86RegToX86Reg(AddressReg, AddressRegHi);
|
||||||
|
m_Assembler.ShiftRightSignImmed(AddressRegHi, 31);
|
||||||
|
|
||||||
|
if (IsConst(m_Opcode.base))
|
||||||
|
{
|
||||||
|
m_Assembler.MoveConstToVariable(GetMipsRegHi(m_Opcode.base), &m_TempValue64 + 4, "TempValue64 + 4");
|
||||||
|
m_Assembler.CompConstToX86reg(AddressRegHi, GetMipsRegHi(m_Opcode.base));
|
||||||
|
}
|
||||||
|
else if (IsMapped(m_Opcode.base))
|
||||||
|
{
|
||||||
|
m_Assembler.MoveX86regToVariable(GetMipsRegMapHi(m_Opcode.base), &m_TempValue64 + 4, "TempValue64 + 4");
|
||||||
|
m_Assembler.CompX86RegToX86Reg(AddressRegHi, GetMipsRegMapHi(m_Opcode.base));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CX86Ops::x86Reg AddressMemoryHi = Map_TempReg(CX86Ops::x86_Unknown, -1, false, false);
|
||||||
|
m_Assembler.MoveVariableToX86reg(&_GPR[m_Opcode.base].W[1], CRegName::GPR_Hi[m_Opcode.base], AddressMemoryHi);
|
||||||
|
m_Assembler.MoveX86regToVariable(AddressMemoryHi, &m_TempValue64 + 4, "TempValue64 + 4");
|
||||||
|
m_Assembler.CompX86RegToX86Reg(AddressRegHi, AddressMemoryHi);
|
||||||
|
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(AddressMemoryHi), false);
|
||||||
|
}
|
||||||
|
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
|
||||||
|
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionRead64, false, &CX86Ops::JneLabel32);
|
||||||
|
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
|
||||||
|
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(AddressRegHi), false);
|
||||||
|
}
|
||||||
return AddressReg;
|
return AddressReg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9697,16 +9738,24 @@ void CX86RecompilerOps::CompileLoadMemoryValue(CX86Ops::x86Reg AddressReg, CX86O
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CX86Ops::x86Reg TempReg = Map_TempReg(CX86Ops::x86_Unknown, -1, false, false);
|
||||||
if (ValueSize == 16)
|
if (ValueSize == 16)
|
||||||
{
|
{
|
||||||
m_Assembler.TestConstToX86Reg(1, AddressReg);
|
|
||||||
m_Assembler.MoveX86regToVariable(AddressReg, &m_TempValue32, "TempValue32");
|
m_Assembler.MoveX86regToVariable(AddressReg, &m_TempValue32, "TempValue32");
|
||||||
|
m_Assembler.TestConstToX86Reg(1, AddressReg);
|
||||||
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
|
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
|
||||||
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionRead, false, &CX86Ops::JneLabel32);
|
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionRead32, false, &CX86Ops::JneLabel32);
|
||||||
|
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
|
||||||
|
}
|
||||||
|
else if (ValueSize == 32)
|
||||||
|
{
|
||||||
|
m_Assembler.MoveX86regToVariable(AddressReg, &m_TempValue32, "TempValue32");
|
||||||
|
m_Assembler.TestConstToX86Reg(3, AddressReg);
|
||||||
|
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp());
|
||||||
|
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_AddressErrorExceptionRead32, false, &CX86Ops::JneLabel32);
|
||||||
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
|
m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp());
|
||||||
}
|
}
|
||||||
|
|
||||||
CX86Ops::x86Reg TempReg = Map_TempReg(CX86Ops::x86_Unknown, -1, false, false);
|
|
||||||
m_Assembler.MoveX86RegToX86Reg(AddressReg, TempReg);
|
m_Assembler.MoveX86RegToX86Reg(AddressReg, TempReg);
|
||||||
m_Assembler.ShiftRightUnsignImmed(TempReg, 12);
|
m_Assembler.ShiftRightUnsignImmed(TempReg, 12);
|
||||||
m_Assembler.MoveVariableDispToX86Reg(g_MMU->m_MemoryReadMap, "MMU->m_MemoryReadMap", TempReg, TempReg, 4);
|
m_Assembler.MoveVariableDispToX86Reg(g_MMU->m_MemoryReadMap, "MMU->m_MemoryReadMap", TempReg, TempReg, 4);
|
||||||
|
@ -9791,7 +9840,7 @@ void CX86RecompilerOps::CompileLoadMemoryValue(CX86Ops::x86Reg AddressReg, CX86O
|
||||||
m_Assembler.XorConstToX86Reg(AddressReg, 2);
|
m_Assembler.XorConstToX86Reg(AddressReg, 2);
|
||||||
if (ValueReg == CX86Ops::x86_Unknown)
|
if (ValueReg == CX86Ops::x86_Unknown)
|
||||||
{
|
{
|
||||||
Map_GPR_32bit(m_Opcode.rt, true, m_Opcode.base == m_Opcode.rt ? m_Opcode.rt : -1);
|
Map_GPR_32bit(m_Opcode.rt, SignExtend, -1);
|
||||||
ValueReg = GetMipsRegMapLo(m_Opcode.rt);
|
ValueReg = GetMipsRegMapLo(m_Opcode.rt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9806,6 +9855,12 @@ void CX86RecompilerOps::CompileLoadMemoryValue(CX86Ops::x86Reg AddressReg, CX86O
|
||||||
}
|
}
|
||||||
else if (ValueSize == 32)
|
else if (ValueSize == 32)
|
||||||
{
|
{
|
||||||
|
if (ValueReg == CX86Ops::x86_Unknown)
|
||||||
|
{
|
||||||
|
Map_GPR_32bit(m_Opcode.rt, true, -1);
|
||||||
|
ValueReg = GetMipsRegMapLo(m_Opcode.rt);
|
||||||
|
}
|
||||||
|
|
||||||
if (ValueReg != CX86Ops::x86_Unknown)
|
if (ValueReg != CX86Ops::x86_Unknown)
|
||||||
{
|
{
|
||||||
m_Assembler.MoveX86regPointerToX86reg(AddressReg, TempReg, ValueReg);
|
m_Assembler.MoveX86regPointerToX86reg(AddressReg, TempReg, ValueReg);
|
||||||
|
|
|
@ -454,6 +454,7 @@ private:
|
||||||
CRegInfo m_RegBeforeDelay;
|
CRegInfo m_RegBeforeDelay;
|
||||||
bool m_EffectDelaySlot;
|
bool m_EffectDelaySlot;
|
||||||
static uint32_t m_TempValue32;
|
static uint32_t m_TempValue32;
|
||||||
|
static uint64_t m_TempValue64;
|
||||||
static uint32_t m_BranchCompare;
|
static uint32_t m_BranchCompare;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue