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() void CX86RecompilerOps::COP1_S_TRUNC_L()
{ {
CompileCop1Test(); if (FpuExceptionInRecompiler())
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); 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() void CX86RecompilerOps::COP1_S_CEIL_L()
{ {
CompileCop1Test(); if (FpuExceptionInRecompiler())
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); 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() void CX86RecompilerOps::COP1_S_FLOOR_L()
{ {
CompileCop1Test(); if (FpuExceptionInRecompiler())
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); 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() void CX86RecompilerOps::COP1_S_ROUND_W()
@ -8812,53 +8833,69 @@ void CX86RecompilerOps::COP1_W_CVT_S()
{ {
if (FpuExceptionInRecompiler()) if (FpuExceptionInRecompiler())
{ {
CompileInitFpuOperation(CRegBase::RoundUnknown); COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Dword, CRegInfo::FPU_Float);
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;
}
} }
else else
{ {
CompileCop1Test(); 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() void CX86RecompilerOps::COP1_W_CVT_D()
{ {
CompileCop1Test(); if (FpuExceptionInRecompiler())
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); 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 // COP1: L functions
void CX86RecompilerOps::COP1_L_CVT_S() void CX86RecompilerOps::COP1_L_CVT_S()
{ {
CompileCop1Test(); if (FpuExceptionInRecompiler())
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); 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() void CX86RecompilerOps::COP1_L_CVT_D()
{ {
CompileCop1Test(); if (FpuExceptionInRecompiler())
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); 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 // Other functions

View File

@ -286,6 +286,12 @@ void CX86Ops::JbLabel(const char * LabelName, asmjit::Label & JumpLabel)
jb(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) void CX86Ops::JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel)
{ {
AddSymbol(stdstr_f("L%d", JumpLabel.id()).c_str(), LabelName); 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 JaeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JaLabel(const char * LabelName, asmjit::Label & JumpLabel); void JaLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JbLabel(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 JecxzLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JeLabel(const char * LabelName, asmjit::Label & JumpLabel); void JeLabel(const char * LabelName, asmjit::Label & JumpLabel);
void JgeLabel(const char * LabelName, asmjit::Label & JumpLabel); void JgeLabel(const char * LabelName, asmjit::Label & JumpLabel);