From 77ac4744a5d17082dca95450ac35dbf308a7b3d5 Mon Sep 17 00:00:00 2001 From: zilmar Date: Thu, 23 May 2024 11:52:58 +0930 Subject: [PATCH] Core: Make sure fpu stack is being cleared --- .../Recompiler/x86/x86RecompilerOps.cpp | 30 ++++++++++--------- .../N64System/Recompiler/x86/x86ops.cpp | 18 +++++++++++ .../N64System/Recompiler/x86/x86ops.h | 3 ++ 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 1d5986e59..b90534f07 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -302,6 +302,10 @@ void CX86RecompilerOps::PostCompileOpcode(void) if (!g_System->bFPURegCaching()) { m_RegWorkingSet.UnMap_AllFPRs(); + if (m_RegWorkingSet.StackTopPos() != 0) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } } /*if (m_CompilePC >= 0x800933B4 && m_CompilePC <= 0x80093414 && (m_PipelineStage == PIPELINE_STAGE_NORMAL || m_PipelineStage == PIPELINE_STAGE_DO_DELAY_SLOT)) { @@ -7767,7 +7771,7 @@ void CX86RecompilerOps::COP1_S_CMP() m_Assembler.fpuLoadDwordFromX86Reg(m_RegWorkingSet.StackTopPos(), FtPtr); m_Assembler.fpuLoadDwordFromX86Reg(m_RegWorkingSet.StackTopPos(), FsPtr); - m_Assembler.fucompp(); + m_Assembler.fpuCompp(m_RegWorkingSet.StackTopPos()); m_Assembler.fstsw(asmjit::x86::ax); m_Assembler.sahf(); asmjit::Label NotNanLabel = m_Assembler.newLabel(); @@ -7961,7 +7965,7 @@ void CX86RecompilerOps::COP1_D_CMP() m_Assembler.fpuLoadQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), FtPtr); m_Assembler.fpuLoadQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), FsPtr); - m_Assembler.fucompp(); + m_Assembler.fpuCompp(m_RegWorkingSet.StackTopPos()); m_Assembler.fstsw(asmjit::x86::ax); m_Assembler.sahf(); asmjit::Label NotNanLabel = m_Assembler.newLabel(); @@ -8250,15 +8254,15 @@ void CX86RecompilerOps::CompileCheckFPUInput(asmjit::x86::Gp RegPointer, FpuOpSi InvalidMinValueJump = m_Assembler.newLabel(); static uint32_t InvalidValueMax = 0x5a000000, InvalidMinValue = 0xda000000; - m_Assembler.fld(asmjit::x86::dword_ptr(RegPointer)); - m_Assembler.fld(asmjit::x86::dword_ptr((uint64_t)&InvalidValueMax)); - m_Assembler.fcompp(); + m_Assembler.fpuLoadDwordFromX86Reg(m_RegWorkingSet.StackTopPos(), RegPointer); + m_Assembler.fpuLoadDwordFromPtr(m_RegWorkingSet.StackTopPos(), (uint64_t)&InvalidValueMax); + m_Assembler.fpuCompp(m_RegWorkingSet.StackTopPos()); m_Assembler.fnstsw(asmjit::x86::ax); m_Assembler.test(asmjit::x86::ah, 0x41); m_Assembler.jnp(InvalidValueMaxJump); - m_Assembler.fld(asmjit::x86::dword_ptr(RegPointer)); - m_Assembler.fld(asmjit::x86::qword_ptr((uint64_t)&InvalidMinValue)); - m_Assembler.fcompp(); + m_Assembler.fpuLoadDwordFromX86Reg(m_RegWorkingSet.StackTopPos(), RegPointer); + m_Assembler.fpuLoadDwordFromPtr(m_RegWorkingSet.StackTopPos(), (uint64_t)&InvalidMinValue); + m_Assembler.fpuCompp(m_RegWorkingSet.StackTopPos()); m_Assembler.fnstsw(asmjit::x86::ax); m_Assembler.test(asmjit::x86::ah, 0x1); m_Assembler.je(InvalidMinValueJump); @@ -11435,8 +11439,7 @@ void CX86RecompilerOps::COP1_S_CVT(CRegBase::FPU_ROUND RoundMethod, CRegInfo::FP m_Assembler.mov(fsRegPointer, (uint64_t)&m_TempValue32); m_Assembler.fpuStoreIntegerDwordFromX86Reg(m_RegWorkingSet.StackTopPos(), fsRegPointer, false); m_Assembler.fpuLoadIntegerDwordFromX86Reg(m_RegWorkingSet.StackTopPos(), fsRegPointer); - m_Assembler.fcompp(); - m_RegWorkingSet.StackTopPos() = (m_RegWorkingSet.StackTopPos() - 2) & 7; + m_Assembler.fpuCompp(m_RegWorkingSet.StackTopPos()); m_Assembler.fstsw(asmjit::x86::ax); m_Assembler.sahf(); asmjit::Label ExactLabel = m_Assembler.newLabel(); @@ -11467,11 +11470,10 @@ void CX86RecompilerOps::COP1_S_CVT(CRegBase::FPU_ROUND RoundMethod, CRegInfo::FP else if (NewFormat == CRegInfo::FPU_Qword) { m_Assembler.mov(fsRegPointer, (uint64_t)&m_TempValue64); - m_Assembler.fld(asmjit::x86::st0); + m_Assembler.fpuLoadDwordFromStackReg(m_RegWorkingSet.StackTopPos(), asmjit::x86::st0); m_Assembler.fpuStoreIntegerQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), fsRegPointer, true); m_Assembler.fpuLoadIntegerQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), fsRegPointer); - m_Assembler.fcompp(); - m_RegWorkingSet.StackTopPos() = (m_RegWorkingSet.StackTopPos() - 2) & 7; + m_Assembler.fpuCompp(m_RegWorkingSet.StackTopPos()); m_Assembler.fstsw(asmjit::x86::ax); m_Assembler.sahf(); asmjit::Label ExactLabel = m_Assembler.newLabel(); @@ -11506,7 +11508,7 @@ void CX86RecompilerOps::COP1_S_CVT(CRegBase::FPU_ROUND RoundMethod, CRegInfo::FP else if (NewFormat == CRegInfo::FPU_Double) { m_Assembler.mov(fsRegPointer, (uint64_t)&m_TempValue64); - m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), fsRegPointer, false); + m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), fsRegPointer, true); CompileCheckFPUResult64(fsRegPointer); } else diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp index c1eaee206..dd1b94a85 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp @@ -765,6 +765,12 @@ void CX86Ops::XorVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, } } +void CX86Ops::fpuCompp(int32_t & StackPos) +{ + StackPos = (StackPos + 2) & 7; + fcompp(); +} + void CX86Ops::fpuIncStack(int32_t & StackPos) { StackPos = (StackPos + 1) & 7; @@ -792,6 +798,18 @@ void CX86Ops::fpuLoadDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & StackPos = (StackPos - 1) & 7; } +void CX86Ops::fpuLoadDwordFromStackReg(int32_t & StackPos, const asmjit::x86::St & StackReg) +{ + fld(StackReg); + StackPos = (StackPos - 1) & 7; +} + +void CX86Ops::fpuLoadDwordFromPtr(int32_t & StackPos, uint64_t Ptr) +{ + fld(asmjit::x86::dword_ptr(Ptr)); + StackPos = (StackPos - 1) & 7; +} + void CX86Ops::fpuLoadIntegerDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & x86reg) { fild(asmjit::x86::dword_ptr(x86reg)); diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86ops.h b/Source/Project64-core/N64System/Recompiler/x86/x86ops.h index 4a8e4925f..26515acd4 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86ops.h +++ b/Source/Project64-core/N64System/Recompiler/x86/x86ops.h @@ -96,9 +96,12 @@ class CX86Ops : void TestVariable(void * Variable, const char * VariableName, uint32_t Const); void XorVariableToX86reg(const asmjit::x86::Gp & Reg, void * Variable, const char * VariableName); + void fpuCompp(int32_t & StackPos); void fpuIncStack(int32_t & StackPos); void fpuLoadControl(void * Variable, const char * VariableName); void fpuLoadDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); + void fpuLoadDwordFromStackReg(int32_t & StackPos, const asmjit::x86::St & Reg); + void fpuLoadDwordFromPtr(int32_t & StackPos, uint64_t Ptr); void fpuLoadIntegerDwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadIntegerQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg); void fpuLoadQwordFromX86Reg(int32_t & StackPos, const asmjit::x86::Gp & Reg);