Core: get COP1_S_TRUNC_L, COP1_S_CEIL_L, COP1_S_FLOOR_L, COP1_W_CVT_S, COP1_W_CVT_D, COP1_L_CVT_S, COP1_L_CVT_D to use COP1_S_CVT function

This commit is contained in:
zilmar 2024-05-02 15:48:43 +09:30
parent dd0f7ad776
commit b3e8b760e6
3 changed files with 79 additions and 35 deletions

View File

@ -7876,32 +7876,53 @@ void CX86RecompilerOps::COP1_S_ROUND_L()
void CX86RecompilerOps::COP1_S_TRUNC_L()
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
if (FpuExceptionInRecompiler())
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
COP1_S_CVT(CRegInfo::RoundTruncate, CRegInfo::FPU_FloatLow, CRegInfo::FPU_Qword);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundTruncate);
}
void CX86RecompilerOps::COP1_S_CEIL_L()
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
if (FpuExceptionInRecompiler())
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
COP1_S_CVT(CRegInfo::RoundUp, CRegInfo::FPU_FloatLow, CRegInfo::FPU_Qword);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundUp);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundUp);
}
void CX86RecompilerOps::COP1_S_FLOOR_L()
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
if (FpuExceptionInRecompiler())
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
COP1_S_CVT(CRegInfo::RoundDown, CRegInfo::FPU_FloatLow, CRegInfo::FPU_Qword);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Float))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Float);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundDown);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Float, CRegInfo::FPU_Qword, CRegInfo::RoundDown);
}
void CX86RecompilerOps::COP1_S_ROUND_W()
@ -8812,53 +8833,69 @@ void CX86RecompilerOps::COP1_W_CVT_S()
{
if (FpuExceptionInRecompiler())
{
CompileInitFpuOperation(CRegBase::RoundUnknown);
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Any) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Any))
{
g_Notify->BreakPoint(__FILE__, __LINE__);
return;
}
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Dword, CRegInfo::FPU_Float);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
}
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
}
void CX86RecompilerOps::COP1_W_CVT_D()
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword))
if (FpuExceptionInRecompiler())
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword);
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Dword, CRegInfo::FPU_Double);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Dword))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Dword);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Double, CRegInfo::RoundDefault);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Dword, CRegInfo::FPU_Double, CRegInfo::RoundDefault);
}
// COP1: L functions
void CX86RecompilerOps::COP1_L_CVT_S()
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
if (FpuExceptionInRecompiler())
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword);
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Qword, CRegInfo::FPU_Float);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
}
void CX86RecompilerOps::COP1_L_CVT_D()
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
if (FpuExceptionInRecompiler())
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword);
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Qword, CRegInfo::FPU_Double);
}
else
{
CompileCop1Test();
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
{
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Qword);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Double, CRegInfo::RoundDefault);
}
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Qword, CRegInfo::FPU_Double, CRegInfo::RoundDefault);
}
// Other functions

View File

@ -286,6 +286,12 @@ void CX86Ops::JbLabel(const char * LabelName, asmjit::Label & JumpLabel)
jb(JumpLabel);
}
void CX86Ops::JbeLabel(const char * LabelName, asmjit::Label & JumpLabel)
{
AddSymbol(stdstr_f("L%d", JumpLabel.id()).c_str(), LabelName);
jbe(JumpLabel);
}
void CX86Ops::JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel)
{
AddSymbol(stdstr_f("L%d", JumpLabel.id()).c_str(), LabelName);

View File

@ -54,6 +54,7 @@ public:
void JaeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JbLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JbeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JgeLabel(const char * LabelName, asmjit::Label & JumpLabel);