Skip to content

Commit

Permalink
Core: Make sure fpu stack is being cleared
Browse files Browse the repository at this point in the history
  • Loading branch information
project64 committed May 23, 2024
1 parent 0ff0d52 commit 77ac474
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 14 deletions.
30 changes: 16 additions & 14 deletions Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
{
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions Source/Project64-core/N64System/Recompiler/x86/x86ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down
3 changes: 3 additions & 0 deletions Source/Project64-core/N64System/Recompiler/x86/x86ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 77ac474

Please sign in to comment.