Core: Handle div/0 better
This commit is contained in:
parent
9e1d69bcb5
commit
52a30b78fb
|
@ -250,7 +250,6 @@ CJniBridegSettings::CJniBridegSettings()
|
|||
ADD_SETTING(Debugger_BreakOnAddressError);
|
||||
ADD_SETTING(Debugger_StepOnBreakOpCode);
|
||||
ADD_SETTING(Debugger_ShowPifErrors);
|
||||
ADD_SETTING(Debugger_ShowDivByZero);
|
||||
ADD_SETTING(Debugger_RecordRecompilerAsm);
|
||||
ADD_SETTING(Debugger_DisableGameFixes);
|
||||
ADD_SETTING(Debugger_AppLogLevel);
|
||||
|
|
|
@ -1409,17 +1409,21 @@ void R4300iOp::SPECIAL_DIV()
|
|||
{
|
||||
if (_GPR[m_Opcode.rt].W[0] != 0)
|
||||
{
|
||||
_RegLO->DW = _GPR[m_Opcode.rs].W[0] / _GPR[m_Opcode.rt].W[0];
|
||||
_RegHI->DW = _GPR[m_Opcode.rs].W[0] % _GPR[m_Opcode.rt].W[0];
|
||||
if (_GPR[m_Opcode.rs].W[0] != 0x80000000 || _GPR[m_Opcode.rt].W[0] != -1)
|
||||
{
|
||||
_RegLO->DW = _GPR[m_Opcode.rs].W[0] / _GPR[m_Opcode.rt].W[0];
|
||||
_RegHI->DW = _GPR[m_Opcode.rs].W[0] % _GPR[m_Opcode.rt].W[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
_RegLO->DW = 0xFFFFFFFF80000000;
|
||||
_RegHI->DW = 0x0000000000000000;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bShowDivByZero())
|
||||
{
|
||||
g_Notify->DisplayError("DIV by 0");
|
||||
}
|
||||
_RegLO->DW = 0;
|
||||
_RegHI->DW = 0;
|
||||
_RegLO->DW = _GPR[m_Opcode.rs].W[0] < 0 ? 0x0000000000000001 : 0xFFFFFFFFFFFFFFFF;
|
||||
_RegHI->DW = _GPR[m_Opcode.rs].W[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1432,12 +1436,8 @@ void R4300iOp::SPECIAL_DIVU()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (bShowDivByZero())
|
||||
{
|
||||
g_Notify->DisplayError("DIVU by 0");
|
||||
}
|
||||
_RegLO->DW = 0;
|
||||
_RegHI->DW = 0;
|
||||
_RegLO->DW = 0xFFFFFFFFFFFFFFFF;
|
||||
_RegHI->DW = _GPR[m_Opcode.rs].W[0];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1478,10 +1478,8 @@ void R4300iOp::SPECIAL_DDIV()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError("DDIV by 0");
|
||||
}
|
||||
_RegLO->DW = _GPR[m_Opcode.rs].DW < 0 ? 0x0000000000000001 : 0xFFFFFFFFFFFFFFFF;
|
||||
_RegHI->DW = _GPR[m_Opcode.rs].DW;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1494,10 +1492,8 @@ void R4300iOp::SPECIAL_DDIVU()
|
|||
}
|
||||
else
|
||||
{
|
||||
if (HaveDebugger())
|
||||
{
|
||||
g_Notify->DisplayError("DDIVU by 0");
|
||||
}
|
||||
_RegLO->DW = 0xFFFFFFFFFFFFFFFF;
|
||||
_RegHI->DW = _GPR[m_Opcode.rs].DW;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@ struct CExitInfo
|
|||
DoSysCall = 4,
|
||||
TLBReadMiss = 5,
|
||||
TLBWriteMiss = 6,
|
||||
DivByZero = 7,
|
||||
ExitResetRecompCode = 8,
|
||||
};
|
||||
|
||||
|
|
|
@ -4773,129 +4773,308 @@ void CX86RecompilerOps::SPECIAL_MULTU()
|
|||
|
||||
void CX86RecompilerOps::SPECIAL_DIV()
|
||||
{
|
||||
if (IsConst(m_Opcode.rt))
|
||||
CX86Ops::x86Reg RegRs = CX86Ops::x86_Unknown, RegRsHi = CX86Ops::x86_Unknown, DivReg = CX86Ops::x86_Unknown;
|
||||
uint8_t * JumpNotDiv0 = nullptr;
|
||||
uint8_t * JumpEnd = nullptr;
|
||||
uint8_t * JumpEnd2 = nullptr;
|
||||
|
||||
if (IsConst(m_Opcode.rt) && GetMipsRegLo(m_Opcode.rt) == 0)
|
||||
{
|
||||
if (GetMipsRegLo(m_Opcode.rt) == 0)
|
||||
if (IsConst(m_Opcode.rs))
|
||||
{
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsMapped(m_Opcode.rt))
|
||||
{
|
||||
m_Assembler.CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0);
|
||||
m_Assembler.MoveConstToVariable(GetMipsRegLo_S(m_Opcode.rs) < 0 ? 0x00000001 : 0xFFFFFFFF, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(GetMipsRegLo_S(m_Opcode.rs) < 0 ? 0x00000000 : 0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(GetMipsRegLo_S(m_Opcode.rs) < 0 ? 0xFFFFFFFF : 0x00000000, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]);
|
||||
CX86Ops::x86Reg Reg = IsMapped(m_Opcode.rs) ? GetMipsRegMapLo(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, false);
|
||||
m_Assembler.CompConstToX86reg(Reg, 0);
|
||||
m_Assembler.JgeLabel8(stdstr_f("RsPositive_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpPositive = *g_RecompPos - 1;
|
||||
m_Assembler.MoveConstToVariable(0x00000001, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.JmpLabel8(stdstr_f("LoSet_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpLoSet = *g_RecompPos - 1;
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" RsPositive_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpPositive, *g_RecompPos);
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" LoSet_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpLoSet, *g_RecompPos);
|
||||
m_Assembler.MoveX86regToVariable(Reg, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
if (IsMapped(m_Opcode.rs))
|
||||
{
|
||||
Reg = Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.ShiftRightSignImmed(Reg, 31);
|
||||
}
|
||||
m_Assembler.MoveX86regToVariable(Reg, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
}
|
||||
CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, CExitInfo::DivByZero, false, &CX86Ops::JeLabel32);
|
||||
return;
|
||||
}
|
||||
/* lo = (SD)rs / (SD)rt;
|
||||
hi = (SD)rs % (SD)rt; */
|
||||
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EDX, true);
|
||||
Map_TempReg(CX86Ops::x86_EAX, m_Opcode.rs, false);
|
||||
|
||||
// EDX is the signed portion to EAX
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EDX, false);
|
||||
Map_TempReg(CX86Ops::x86_EDX, -1, false);
|
||||
|
||||
m_Assembler.MoveX86RegToX86Reg(CX86Ops::x86_EAX, CX86Ops::x86_EDX);
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EDX, 31);
|
||||
|
||||
if (IsMapped(m_Opcode.rt))
|
||||
else if (IsConst(m_Opcode.rt) && GetMipsRegLo(m_Opcode.rt) == -1)
|
||||
{
|
||||
m_Assembler.idivX86reg(GetMipsRegMapLo(m_Opcode.rt));
|
||||
if (IsConst(m_Opcode.rs) && GetMipsRegLo(m_Opcode.rs) == 0x80000000)
|
||||
{
|
||||
m_Assembler.MoveConstToVariable(0x80000000, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
return;
|
||||
}
|
||||
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EDX);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, false);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EDX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EAX);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
RegRs = IsMapped(m_Opcode.rs) ? GetMipsRegMapLo(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, false);
|
||||
m_RegWorkingSet.SetX86Protected(RegRs, true);
|
||||
RegRsHi = IsMapped(m_Opcode.rs) && Is64Bit(m_Opcode.rs) ? GetMipsRegMapHi(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, IsMapped(m_Opcode.rs) ? m_Opcode.rs : -1, true);
|
||||
DivReg = IsMapped(m_Opcode.rt) ? GetMipsRegMapLo(m_Opcode.rt) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rt, false);
|
||||
|
||||
if (!IsConst(m_Opcode.rs))
|
||||
{
|
||||
m_Assembler.CompConstToX86reg(RegRs, 0x80000000);
|
||||
m_Assembler.JneLabel8(stdstr_f("ValidDiv_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpValid = *g_RecompPos - 1;
|
||||
m_Assembler.MoveConstToVariable(0x80000000, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
m_Assembler.JmpLabel8(stdstr_f("EndDiv_%08X", m_CompilePC).c_str(), 0);
|
||||
JumpEnd = *g_RecompPos - 1;
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" ValidDiv_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpValid, *g_RecompPos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.idivX86reg(Map_TempReg(CX86Ops::x86_Any, m_Opcode.rt, false));
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EDX);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, false);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EDX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EAX);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
RegRs = IsMapped(m_Opcode.rs) ? GetMipsRegMapLo(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, false);
|
||||
m_RegWorkingSet.SetX86Protected(RegRs, true);
|
||||
RegRsHi = IsMapped(m_Opcode.rs) && Is64Bit(m_Opcode.rs) ? GetMipsRegMapHi(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, IsMapped(m_Opcode.rs) ? m_Opcode.rs : -1, true);
|
||||
DivReg = IsMapped(m_Opcode.rt) ? GetMipsRegMapLo(m_Opcode.rt) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rt, false);
|
||||
|
||||
if (!IsConst(m_Opcode.rs))
|
||||
{
|
||||
if (IsMapped(m_Opcode.rt))
|
||||
{
|
||||
m_Assembler.CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]);
|
||||
}
|
||||
m_Assembler.JneLabel8(stdstr_f("NotDiv0_%08X", m_CompilePC).c_str(), 0);
|
||||
JumpNotDiv0 = *g_RecompPos - 1;
|
||||
|
||||
m_Assembler.CompConstToX86reg(RegRs, 0);
|
||||
m_Assembler.JgeLabel8(stdstr_f("RsPositive_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpPositive = *g_RecompPos - 1;
|
||||
m_Assembler.MoveConstToVariable(0x00000001, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.JmpLabel8(stdstr_f("LoSet_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpLoSet = *g_RecompPos - 1;
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" RsPositive_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpPositive, *g_RecompPos);
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" LoSet_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpLoSet, *g_RecompPos);
|
||||
m_Assembler.MoveX86regToVariable(RegRs, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
if (!IsMapped(m_Opcode.rs))
|
||||
{
|
||||
m_Assembler.ShiftRightSignImmed(RegRsHi, 31);
|
||||
}
|
||||
m_Assembler.MoveX86regToVariable(RegRsHi, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
m_Assembler.JmpLabel8(stdstr_f("EndDiv_%08X", m_CompilePC).c_str(), 0);
|
||||
JumpEnd = *g_RecompPos - 1;
|
||||
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" NotDiv0_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpNotDiv0, *g_RecompPos);
|
||||
if (IsMapped(m_Opcode.rt))
|
||||
{
|
||||
m_Assembler.CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), (uint32_t)-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.CompConstToVariable((uint32_t)-1, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]);
|
||||
}
|
||||
m_Assembler.JneLabel8(stdstr_f("ValidDiv0_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpValidDiv0 = *g_RecompPos - 1;
|
||||
|
||||
m_Assembler.MoveConstToVariable(0x80000000, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
m_Assembler.JmpLabel8(stdstr_f("EndDiv_%08X", m_CompilePC).c_str(), 0);
|
||||
JumpEnd2 = *g_RecompPos - 1;
|
||||
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" ValidDiv0_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpValidDiv0, *g_RecompPos);
|
||||
}
|
||||
}
|
||||
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EDX);
|
||||
Map_TempReg(CX86Ops::x86_EDX, -1, false);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, false);
|
||||
Map_TempReg(CX86Ops::x86_EAX, m_Opcode.rs, false);
|
||||
|
||||
if (IsConst(m_Opcode.rs))
|
||||
{
|
||||
m_Assembler.MoveConstToX86reg(GetMipsRegLo_S(m_Opcode.rs) >> 31, CX86Ops::x86_EDX);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.MoveX86RegToX86Reg(CX86Ops::x86_EAX, CX86Ops::x86_EDX);
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EDX, 31);
|
||||
}
|
||||
|
||||
m_Assembler.idivX86reg(DivReg);
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EAX, 31); // Paired
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EAX, 31);
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EDX, 31);
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
|
||||
if (JumpEnd != nullptr || JumpEnd2 != nullptr)
|
||||
{
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" EndDiv_%08X:", m_CompilePC);
|
||||
if (JumpEnd != nullptr)
|
||||
{
|
||||
m_Assembler.SetJump8(JumpEnd, *g_RecompPos);
|
||||
}
|
||||
if (JumpEnd2 != nullptr)
|
||||
{
|
||||
m_Assembler.SetJump8(JumpEnd2, *g_RecompPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CX86RecompilerOps::SPECIAL_DIVU()
|
||||
{
|
||||
uint8_t *Jump[2];
|
||||
CX86Ops::x86Reg Reg;
|
||||
|
||||
if (IsConst(m_Opcode.rt))
|
||||
uint8_t * JumpEndDivu = nullptr;
|
||||
if (IsConst(m_Opcode.rt) && GetMipsRegLo(m_Opcode.rt) == 0)
|
||||
{
|
||||
if (GetMipsRegLo(m_Opcode.rt) == 0)
|
||||
if (IsConst(m_Opcode.rs))
|
||||
{
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
return;
|
||||
}
|
||||
Jump[1] = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsMapped(m_Opcode.rt))
|
||||
{
|
||||
m_Assembler.CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0);
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(GetMipsRegLo(m_Opcode.rs), &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(GetMipsRegLo_S(m_Opcode.rs) < 0 ? 0xFFFFFFFF : 0x00000000, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]);
|
||||
CX86Ops::x86Reg RegRs = IsMapped(m_Opcode.rs) ? GetMipsRegMapLo(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, false);
|
||||
m_Assembler.CompConstToX86reg(RegRs, 0);
|
||||
m_Assembler.JgeLabel8(stdstr_f("RsPositive_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpPositive = *g_RecompPos - 1;
|
||||
m_Assembler.MoveConstToVariable(0x00000001, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0x00000000, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.JmpLabel8(stdstr_f("LoSet_%08X", m_CompilePC).c_str(), 0);
|
||||
uint8_t * JumpLoSet = *g_RecompPos - 1;
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" RsPositive_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpPositive, *g_RecompPos);
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" LoSet_%08X:", m_CompilePC);
|
||||
m_Assembler.SetJump8(JumpLoSet, *g_RecompPos);
|
||||
m_Assembler.MoveX86regToVariable(RegRs, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
if (IsMapped(m_Opcode.rs))
|
||||
{
|
||||
RegRs = Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.ShiftRightSignImmed(RegRs, 31);
|
||||
}
|
||||
m_Assembler.MoveX86regToVariable(RegRs, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
}
|
||||
m_Assembler.JneLabel8("NoExcept", 0);
|
||||
Jump[0] = *g_RecompPos - 1;
|
||||
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
|
||||
m_Assembler.JmpLabel8("EndDivu", 0);
|
||||
Jump[1] = *g_RecompPos - 1;
|
||||
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" NoExcept:");
|
||||
m_Assembler.SetJump8(Jump[0], *g_RecompPos);
|
||||
}
|
||||
|
||||
/* lo = (UD)rs / (UD)rt;
|
||||
hi = (UD)rs % (UD)rt; */
|
||||
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
Map_TempReg(CX86Ops::x86_EDX, 0, false);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, false);
|
||||
|
||||
Map_TempReg(CX86Ops::x86_EAX, m_Opcode.rs, false);
|
||||
Reg = Map_TempReg(CX86Ops::x86_Any, m_Opcode.rt, false);
|
||||
|
||||
m_Assembler.DivX86reg(Reg);
|
||||
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
|
||||
// Wouldn't these be zero?
|
||||
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EAX, 31); // Paired
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EDX, 31);
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
|
||||
if (Jump[1] != nullptr)
|
||||
else
|
||||
{
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" EndDivu:");
|
||||
m_Assembler.SetJump8(Jump[1], *g_RecompPos);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EDX);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, false);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EDX, true);
|
||||
UnMap_X86reg(CX86Ops::x86_EAX);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
CX86Ops::x86Reg RegRsLo = IsMapped(m_Opcode.rs) ? GetMipsRegMapLo(m_Opcode.rs) : Map_TempReg(CX86Ops::x86_Any, m_Opcode.rs, false);
|
||||
CX86Ops::x86Reg RegRsHi = IsMapped(m_Opcode.rs) ? Map_TempReg(CX86Ops::x86_Any, IsMapped(m_Opcode.rs), true) : CX86Ops::x86_Unknown;
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, true);
|
||||
Map_TempReg(CX86Ops::x86_EDX, 0, false);
|
||||
m_RegWorkingSet.SetX86Protected(CX86Ops::x86_EAX, false);
|
||||
|
||||
Map_TempReg(CX86Ops::x86_EAX, m_Opcode.rs, false);
|
||||
CX86Ops::x86Reg DivReg = Map_TempReg(CX86Ops::x86_Any, m_Opcode.rt, false);
|
||||
|
||||
if (!IsConst(m_Opcode.rt))
|
||||
{
|
||||
if (IsMapped(m_Opcode.rt))
|
||||
{
|
||||
m_Assembler.CompConstToX86reg(GetMipsRegMapLo(m_Opcode.rt), 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Assembler.CompConstToVariable(0, &_GPR[m_Opcode.rt].W[0], CRegName::GPR_Lo[m_Opcode.rt]);
|
||||
}
|
||||
m_Assembler.JneLabel8("NoExcept", 0);
|
||||
uint8_t * JumpNoExcept = *g_RecompPos - 1;
|
||||
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0xFFFFFFFF, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveX86regToVariable(RegRsLo, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
if (!IsMapped(m_Opcode.rs))
|
||||
{
|
||||
RegRsHi = RegRsLo;
|
||||
m_Assembler.ShiftRightSignImmed(RegRsHi, 31);
|
||||
}
|
||||
m_Assembler.MoveX86regToVariable(RegRsHi, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
|
||||
m_Assembler.JmpLabel8("EndDivu", 0);
|
||||
JumpEndDivu = *g_RecompPos - 1;
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" NoExcept:");
|
||||
m_Assembler.SetJump8(JumpNoExcept, *g_RecompPos);
|
||||
}
|
||||
m_Assembler.DivX86reg(DivReg);
|
||||
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EAX, 31);
|
||||
m_Assembler.ShiftRightSignImmed(CX86Ops::x86_EDX, 31);
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EAX, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
m_Assembler.MoveX86regToVariable(CX86Ops::x86_EDX, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
|
||||
if (JumpEndDivu != nullptr)
|
||||
{
|
||||
m_CodeBlock.Log("");
|
||||
m_CodeBlock.Log(" EndDivu:");
|
||||
m_Assembler.SetJump8(JumpEndDivu, *g_RecompPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9621,17 +9800,6 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
m_Assembler.X86BreakPoint(__FILE__, __LINE__);
|
||||
ExitCodeBlock();
|
||||
break;
|
||||
case CExitInfo::DivByZero:
|
||||
m_Assembler.AddConstToVariable(4, _PROGRAM_COUNTER, "PROGRAM_COUNTER");
|
||||
if (!g_System->b32BitCore())
|
||||
{
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[1], "_RegHI->UW[1]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[1], "_RegLO->UW[1]");
|
||||
}
|
||||
m_Assembler.MoveConstToVariable(0, &_RegHI->UW[0], "_RegHI->UW[0]");
|
||||
m_Assembler.MoveConstToVariable(0, &_RegLO->UW[0], "_RegLO->UW[0]");
|
||||
ExitCodeBlock();
|
||||
break;
|
||||
default:
|
||||
WriteTrace(TraceRecompiler, TraceError, "How did you want to exit on reason (%d) ???", reason);
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
|
|
|
@ -467,6 +467,13 @@ void CX86Ops::JeLabel32(const char * Label, uint32_t Value)
|
|||
AddCode32(Value);
|
||||
}
|
||||
|
||||
void CX86Ops::JgeLabel8(const char * Label, uint8_t Value)
|
||||
{
|
||||
CodeLog(" jge $%s", Label);
|
||||
AddCode8(0x7D);
|
||||
AddCode8(Value);
|
||||
}
|
||||
|
||||
void CX86Ops::JgeLabel32(const char * Label, uint32_t Value)
|
||||
{
|
||||
CodeLog(" jge $%s", Label);
|
||||
|
|
|
@ -97,6 +97,7 @@ public:
|
|||
void JecxzLabel8(const char * Label, uint8_t Value);
|
||||
void JeLabel8(const char * Label, uint8_t Value);
|
||||
void JeLabel32(const char * Label, uint32_t Value);
|
||||
void JgeLabel8(const char * Label, uint8_t Value);
|
||||
void JgeLabel32(const char * Label, uint32_t Value);
|
||||
void JgLabel8(const char * Label, uint8_t Value);
|
||||
void JgLabel32(const char * Label, uint32_t Value);
|
||||
|
|
|
@ -342,7 +342,6 @@ void CSettings::AddHowToHandleSetting(const char * BaseDirectory)
|
|||
AddHandler(Debugger_IntrBreakpoints, new CSettingTypeApplication("Debugger", "Interrupt Breakpoints", (uint32_t)0));
|
||||
AddHandler(Debugger_RcpIntrBreakpoints, new CSettingTypeApplication("Debugger", "RCP Interrupt Breakpoints", (uint32_t)0));
|
||||
AddHandler(Debugger_DebugLanguage, new CSettingTypeApplication("Debugger", "Debug Language", false));
|
||||
AddHandler(Debugger_ShowDivByZero, new CSettingTypeApplication("Debugger", "Show Div by zero", false));
|
||||
AddHandler(Debugger_AppLogFlush, new CSettingTypeApplication("Logging", "Log Auto Flush", (uint32_t)false));
|
||||
AddHandler(Debugger_RecordRecompilerAsm, new CSettingTypeApplication("Debugger", "Record Recompiler Asm", false));
|
||||
AddHandler(Debugger_AutorunScripts, new CSettingTypeApplication("Debugger", "Autorun Scripts", ""));
|
||||
|
|
|
@ -12,7 +12,6 @@ bool CDebugSettings::m_SkipOp = false;
|
|||
bool CDebugSettings::m_WaitingForStep = false;
|
||||
bool CDebugSettings::m_bRecordRecompilerAsm = false;
|
||||
bool CDebugSettings::m_bShowTLBMisses = false;
|
||||
bool CDebugSettings::m_bShowDivByZero = false;
|
||||
bool CDebugSettings::m_RecordExecutionTimes = false;
|
||||
bool CDebugSettings::m_HaveExecutionBP = false;
|
||||
bool CDebugSettings::m_HaveWriteBP = false;
|
||||
|
@ -36,7 +35,6 @@ CDebugSettings::CDebugSettings()
|
|||
m_Registered = true;
|
||||
g_Settings->RegisterChangeCB(Debugger_Enabled, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->RegisterChangeCB(Debugger_RecordRecompilerAsm, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->RegisterChangeCB(Debugger_ShowDivByZero, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->RegisterChangeCB(Debugger_RecordExecutionTimes, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->RegisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->RegisterChangeCB(Debugger_SkipOp, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
|
@ -66,7 +64,6 @@ CDebugSettings::~CDebugSettings()
|
|||
{
|
||||
g_Settings->UnregisterChangeCB(Debugger_Enabled, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->UnregisterChangeCB(Debugger_RecordRecompilerAsm, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->UnregisterChangeCB(Debugger_ShowDivByZero, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->UnregisterChangeCB(Debugger_RecordExecutionTimes, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->UnregisterChangeCB(Debugger_SteppingOps, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
g_Settings->UnregisterChangeCB(Debugger_SkipOp, this, (CSettings::SettingChangedFunc)StaticRefreshSettings);
|
||||
|
@ -90,7 +87,6 @@ void CDebugSettings::RefreshSettings()
|
|||
{
|
||||
m_HaveDebugger = g_Settings->LoadBool(Debugger_Enabled);
|
||||
m_bRecordRecompilerAsm = m_HaveDebugger && g_Settings->LoadBool(Debugger_RecordRecompilerAsm);
|
||||
m_bShowDivByZero = m_HaveDebugger && g_Settings->LoadBool(Debugger_ShowDivByZero);
|
||||
m_RecordExecutionTimes = m_HaveDebugger && g_Settings->LoadBool(Debugger_RecordExecutionTimes);
|
||||
m_Stepping = m_HaveDebugger && g_Settings->LoadBool(Debugger_SteppingOps);
|
||||
m_SkipOp = m_HaveDebugger && g_Settings->LoadBool(Debugger_SkipOp);
|
||||
|
|
|
@ -15,7 +15,6 @@ public:
|
|||
static inline bool WaitingForStep(void) { return m_WaitingForStep; }
|
||||
static inline bool bRecordRecompilerAsm(void) { return m_bRecordRecompilerAsm; }
|
||||
static inline bool bShowTLBMisses(void) { return m_bShowTLBMisses; }
|
||||
static inline bool bShowDivByZero(void) { return m_bShowDivByZero; }
|
||||
static inline bool bRecordExecutionTimes(void) { return m_RecordExecutionTimes; }
|
||||
static inline bool HaveExecutionBP(void) { return m_HaveExecutionBP; }
|
||||
static inline bool HaveWriteBP(void) { return m_HaveWriteBP; }
|
||||
|
@ -46,7 +45,6 @@ private:
|
|||
static bool m_WaitingForStep;
|
||||
static bool m_bRecordRecompilerAsm;
|
||||
static bool m_bShowTLBMisses;
|
||||
static bool m_bShowDivByZero;
|
||||
static bool m_RecordExecutionTimes;
|
||||
static bool m_HaveExecutionBP;
|
||||
static bool m_HaveWriteBP;
|
||||
|
|
|
@ -241,7 +241,6 @@ enum SettingID
|
|||
Debugger_BreakOnAddressError,
|
||||
Debugger_StepOnBreakOpCode,
|
||||
Debugger_ShowPifErrors,
|
||||
Debugger_ShowDivByZero,
|
||||
Debugger_RecordRecompilerAsm,
|
||||
Debugger_DisableGameFixes,
|
||||
Debugger_AppLogLevel,
|
||||
|
|
|
@ -32,7 +32,6 @@ CMainMenu::CMainMenu(CMainGui * hMainWindow) :
|
|||
m_ChangeSettingList.push_back(Debugger_ShowDListAListCount);
|
||||
m_ChangeSettingList.push_back(Debugger_DebugLanguage);
|
||||
m_ChangeSettingList.push_back(Debugger_ShowRecompMemSize);
|
||||
m_ChangeSettingList.push_back(Debugger_ShowDivByZero);
|
||||
m_ChangeSettingList.push_back(Debugger_RecordRecompilerAsm);
|
||||
m_ChangeSettingList.push_back(Debugger_DisableGameFixes);
|
||||
m_ChangeSettingList.push_back(Debugger_TraceMD5);
|
||||
|
@ -527,9 +526,6 @@ bool CMainMenu::ProcessMessage(HWND hWnd, DWORD /*FromAccelerator*/, DWORD MenuI
|
|||
g_Settings->SaveBool(Debugger_ShowRecompMemSize, !g_Settings->LoadBool(Debugger_ShowRecompMemSize));
|
||||
g_Notify->DisplayMessage(0, EMPTY_STRING);
|
||||
break;
|
||||
case ID_DEBUG_SHOW_DIV_BY_ZERO:
|
||||
g_Settings->SaveBool(Debugger_ShowDivByZero, !g_Settings->LoadBool(Debugger_ShowDivByZero));
|
||||
break;
|
||||
case ID_DEBUG_RECORD_RECOMPILER_ASM:
|
||||
g_Settings->SaveBool(Debugger_RecordRecompilerAsm, !g_Settings->LoadBool(Debugger_RecordRecompilerAsm));
|
||||
break;
|
||||
|
@ -1257,12 +1253,6 @@ void CMainMenu::FillOutMenu(HMENU hMenu)
|
|||
Item.SetItemTicked(true);
|
||||
}
|
||||
DebugNotificationMenu.push_back(Item);
|
||||
Item.Reset(ID_DEBUG_SHOW_DIV_BY_ZERO, EMPTY_STRING, EMPTY_STDSTR, nullptr, L"On division by zero errors");
|
||||
if (g_Settings->LoadBool(Debugger_ShowDivByZero))
|
||||
{
|
||||
Item.SetItemTicked(true);
|
||||
}
|
||||
DebugNotificationMenu.push_back(Item);
|
||||
|
||||
DebugMenu.push_back(MENU_ITEM(SPLITER));
|
||||
Item.Reset(SUB_MENU, EMPTY_STRING, EMPTY_STDSTR, &DebugProfileMenu, L"Profile");
|
||||
|
|
|
@ -35,7 +35,7 @@ enum MainMenuID
|
|||
// Debugger menu
|
||||
ID_DEBUG_END_ON_PERM_LOOP, ID_DEBUG_STEP_ON_BREAK_OPCODE,
|
||||
ID_DEBUG_BREAK_ON_UNHANDLED_MEM, ID_DEBUG_BREAK_ON_ADDRESS_ERROR, ID_DEBUG_SHOW_PIF_ERRORS,
|
||||
ID_DEBUG_SHOW_DLIST_COUNT, ID_DEBUG_SHOW_RECOMP_MEM_SIZE, ID_DEBUG_SHOW_DIV_BY_ZERO,
|
||||
ID_DEBUG_SHOW_DLIST_COUNT, ID_DEBUG_SHOW_RECOMP_MEM_SIZE,
|
||||
ID_DEBUG_RECORD_RECOMPILER_ASM, ID_DEBUG_DISABLE_GAMEFIX, ID_DEBUG_LANGUAGE,
|
||||
ID_DEBUGGER_LOGOPTIONS, ID_DEBUGGER_GENERATELOG, ID_DEBUGGER_DUMPMEMORY, ID_DEBUGGER_SEARCHMEMORY,
|
||||
ID_DEBUGGER_TLBENTRIES, ID_DEBUGGER_BREAKPOINTS, ID_DEBUGGER_MEMORY, ID_DEBUGGER_R4300REGISTERS,
|
||||
|
|
Loading…
Reference in New Issue