diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 5403a8520..805bb03d4 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -6836,6 +6836,10 @@ void CX86RecompilerOps::SPECIAL_DADD() } else { + if (m_Opcode.rd == 0) + { + return; + } if (m_RegWorkingSet.IsMapped(m_Opcode.rd)) { m_RegWorkingSet.UnMap_GPR(m_Opcode.rd, false); @@ -6865,10 +6869,25 @@ void CX86RecompilerOps::SPECIAL_DADD() asmjit::x86::Gp RegLo = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, source1, false, false); asmjit::x86::Gp RegHi = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, source1, true, false); + bool OverFlowCheck = true; if (m_RegWorkingSet.IsConst(source2)) { - m_Assembler.AddConstToX86Reg(RegLo, m_RegWorkingSet.GetMipsRegLo(source2)); - m_Assembler.adc(RegHi, m_RegWorkingSet.GetMipsRegHi(source2)); + if (m_RegWorkingSet.GetMipsReg(source2) != 0) + { + if (m_RegWorkingSet.GetMipsRegLo(source2) != 0) + { + m_Assembler.AddConstToX86Reg(RegLo, m_RegWorkingSet.GetMipsRegLo(source2)); + m_Assembler.adc(RegHi, m_RegWorkingSet.GetMipsRegHi(source2)); + } + else + { + m_Assembler.AddConstToX86Reg(RegHi, m_RegWorkingSet.GetMipsRegHi(source2)); + } + } + else + { + OverFlowCheck = false; + } } else if (m_RegWorkingSet.IsMapped(source2)) { @@ -6881,14 +6900,17 @@ void CX86RecompilerOps::SPECIAL_DADD() m_Assembler.AddVariableToX86reg(RegLo, &m_Reg.m_GPR[source2].W[0], CRegName::GPR_Lo[source2]); m_Assembler.AdcVariableToX86reg(RegHi, &m_Reg.m_GPR[source2].W[1], CRegName::GPR_Hi[source2]); } - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); - CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_ExceptionOverflow, false, &CX86Ops::JoLabel); - m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + if (OverFlowCheck) + { + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + CompileExit(m_CompilePC, m_CompilePC, m_RegWorkingSet, ExitReason_ExceptionOverflow, false, &CX86Ops::JoLabel); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + } if (m_Opcode.rd != 0) { m_RegWorkingSet.UnProtectGPR(source1); m_RegWorkingSet.UnProtectGPR(source2); - m_RegWorkingSet.Map_GPR_64bit(m_Opcode.rd, source1); + m_RegWorkingSet.Map_GPR_64bit(m_Opcode.rd, -1); m_Assembler.mov(m_RegWorkingSet.GetMipsRegMapLo(m_Opcode.rd), RegLo); m_Assembler.mov(m_RegWorkingSet.GetMipsRegMapHi(m_Opcode.rd), RegHi); }