From 91d1c6e2378c339885762679c22a273965cbb5b0 Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 31 Aug 2023 11:09:48 +0930 Subject: [PATCH] Core: Add fpu exceptions to COP1_S_MUL --- .../Recompiler/x86/x86RecompilerOps.cpp | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index cd4e2d9d3..88196f468 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -7710,24 +7710,49 @@ void CX86RecompilerOps::COP1_S_MUL() uint32_t Reg1 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.ft : m_Opcode.fs; uint32_t Reg2 = m_Opcode.ft == m_Opcode.fd ? m_Opcode.fs : m_Opcode.ft; - CompileCop1Test(); - m_RegWorkingSet.FixRoundModel(CRegInfo::RoundDefault); - - m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); - if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Float)) + if (FpuExceptionInRecompiler()) { - m_Assembler.fmul(asmjit::x86::st0, m_RegWorkingSet.StackPosition(Reg2)); + CompileInitFpuOperation(CRegInfo::RoundDefault); + if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Float)) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + return; + } + else + { + asmjit::x86::Gp TempReg = m_RegWorkingSet.FPRValuePointer(Reg1, CRegInfo::FPU_Float); + CompileCheckFPUInput32(TempReg); + m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(TempReg), false); + TempReg = m_RegWorkingSet.FPRValuePointer(Reg2, CRegInfo::FPU_Float); + CompileCheckFPUInput32(TempReg); + m_RegWorkingSet.PrepareFPTopToBe(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); + m_Assembler.fmul(asmjit::x86::dword_ptr(TempReg)); + m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(TempReg), false); + } + CompileCheckFPUResult32(m_Opcode.fd); + m_RegWorkingSet.SetFPTopAs(m_Opcode.fd); } else { - m_RegWorkingSet.UnMap_FPR(Reg2, true); - m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); + CompileCop1Test(); + m_RegWorkingSet.FixRoundModel(CRegInfo::RoundDefault); - asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); - m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str()); - m_Assembler.fmul(asmjit::x86::dword_ptr(TempReg)); + m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Float); + if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Float)) + { + m_Assembler.fmul(asmjit::x86::st0, m_RegWorkingSet.StackPosition(Reg2)); + } + else + { + m_RegWorkingSet.UnMap_FPR(Reg2, true); + m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fd, CRegInfo::FPU_Float); + + asmjit::x86::Gp TempReg = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false); + m_Assembler.MoveVariableToX86reg(TempReg, (uint8_t *)&m_Reg.m_FPR_S[Reg2], stdstr_f("_FPR_S[%d]", Reg2).c_str()); + m_Assembler.fmul(asmjit::x86::dword_ptr(TempReg)); + } + m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true); } - m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true); } void CX86RecompilerOps::COP1_S_DIV()