Core: Handle div/0 better

This commit is contained in:
zilmar 2022-08-22 22:13:53 +09:30
parent 9e1d69bcb5
commit 52a30b78fb
12 changed files with 299 additions and 147 deletions

View File

@ -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);

View File

@ -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;
}
}

View File

@ -16,7 +16,6 @@ struct CExitInfo
DoSysCall = 4,
TLBReadMiss = 5,
TLBWriteMiss = 6,
DivByZero = 7,
ExitResetRecompCode = 8,
};

View File

@ -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__);

View File

@ -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);

View File

@ -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);

View File

@ -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", ""));

View File

@ -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);

View File

@ -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;

View File

@ -241,7 +241,6 @@ enum SettingID
Debugger_BreakOnAddressError,
Debugger_StepOnBreakOpCode,
Debugger_ShowPifErrors,
Debugger_ShowDivByZero,
Debugger_RecordRecompilerAsm,
Debugger_DisableGameFixes,
Debugger_AppLogLevel,

View File

@ -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");

View File

@ -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,