|
|
|
@ -8294,9 +8294,6 @@ void CX86RecompilerOps::COP1_S_CMP()
|
|
|
|
|
// COP1: D functions
|
|
|
|
|
void CX86RecompilerOps::COP1_D_ADD()
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fadd);
|
|
|
|
@ -8305,6 +8302,9 @@ void CX86RecompilerOps::COP1_D_ADD()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, Reg1, CRegInfo::FPU_Double);
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(Reg2, CRegInfo::FPU_Double))
|
|
|
|
|
{
|
|
|
|
@ -8323,9 +8323,6 @@ void CX86RecompilerOps::COP1_D_ADD()
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_SUB()
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fsub);
|
|
|
|
@ -8334,6 +8331,9 @@ void CX86RecompilerOps::COP1_D_SUB()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (m_Opcode.fd == m_Opcode.ft)
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
|
|
|
|
@ -8364,15 +8364,15 @@ void CX86RecompilerOps::COP1_D_SUB()
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_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;
|
|
|
|
|
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fmul);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
@ -8394,15 +8394,15 @@ void CX86RecompilerOps::COP1_D_MUL()
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_DIV()
|
|
|
|
|
{
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fdiv);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
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();
|
|
|
|
|
|
|
|
|
|
if (m_Opcode.fd == m_Opcode.ft)
|
|
|
|
@ -8436,21 +8436,7 @@ void CX86RecompilerOps::COP1_D_ABS()
|
|
|
|
|
{
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
CompileInitFpuOperation(CRegInfo::RoundDefault);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
asmjit::x86::Gp TempReg = m_RegWorkingSet.FPRValuePointer(m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCheckFPUInput(TempReg, FpuOpSize_64bit);
|
|
|
|
|
m_RegWorkingSet.PrepareFPTopToBe(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
m_Assembler.fabs();
|
|
|
|
|
m_Assembler.mov(TempReg, (uint64_t)&m_TempValue64);
|
|
|
|
|
m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), TempReg, false);
|
|
|
|
|
CompileCheckFPUResult64(TempReg);
|
|
|
|
|
m_RegWorkingSet.SetFPTopAs(m_Opcode.fd);
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fabs);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -8462,30 +8448,23 @@ void CX86RecompilerOps::COP1_D_ABS()
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_NEG()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
m_Assembler.fchs();
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fchs);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
m_Assembler.fchs();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_SQRT()
|
|
|
|
|
{
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
CompileInitFpuOperation(CRegInfo::RoundDefault);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
asmjit::x86::Gp TempReg = m_RegWorkingSet.FPRValuePointer(m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCheckFPUInput(TempReg, FpuOpSize_64bit);
|
|
|
|
|
m_RegWorkingSet.PrepareFPTopToBe(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
m_Assembler.fsqrt();
|
|
|
|
|
m_Assembler.mov(TempReg, (uint64_t)&m_TempValue64);
|
|
|
|
|
m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), TempReg, false);
|
|
|
|
|
CompileCheckFPUResult64(TempReg);
|
|
|
|
|
m_RegWorkingSet.SetFPTopAs(m_Opcode.fd);
|
|
|
|
|
COP1_D_Opcode(&CX86Ops::Fsqrt);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
@ -8499,6 +8478,7 @@ void CX86RecompilerOps::COP1_D_MOV()
|
|
|
|
|
{
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Any) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Any))
|
|
|
|
|
{
|
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
@ -8578,16 +8558,23 @@ void CX86RecompilerOps::COP1_D_FLOOR_L()
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_ROUND_W()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
COP1_S_CVT(CRegInfo::RoundNearest, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundNearest);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundNearest);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_TRUNC_W()
|
|
|
|
@ -8613,58 +8600,86 @@ void CX86RecompilerOps::COP1_D_TRUNC_W()
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_CEIL_W()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
COP1_S_CVT(CRegInfo::RoundUp, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundUp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_FLOOR_W()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
COP1_S_CVT(CRegInfo::RoundDown, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDown);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDown);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_CVT_S()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
|
|
|
|
|
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Double, CRegInfo::FPU_FloatLow);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Qword))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fd, true);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Float, CRegInfo::RoundDefault);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_CVT_W()
|
|
|
|
|
{
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
if (FpuExceptionInRecompiler())
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
COP1_S_CVT(CRegInfo::RoundDefault, CRegInfo::FPU_Double, CRegInfo::FPU_Dword);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCop1Test();
|
|
|
|
|
if (m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Double) || m_RegWorkingSet.RegInStack(m_Opcode.fs, CRegInfo::FPU_Qword))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.UnMap_FPR(m_Opcode.fs, true);
|
|
|
|
|
}
|
|
|
|
|
if (m_Opcode.fd != m_Opcode.fs || !m_RegWorkingSet.RegInStack(m_Opcode.fd, CRegInfo::FPU_Double))
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.Load_FPR_ToTop(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDefault);
|
|
|
|
|
}
|
|
|
|
|
m_RegWorkingSet.ChangeFPURegFormat(m_Opcode.fd, CRegInfo::FPU_Double, CRegInfo::FPU_Dword, CRegInfo::RoundDefault);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_CVT_L()
|
|
|
|
@ -9138,6 +9153,12 @@ void CX86RecompilerOps::CompileCheckFPUResult64(asmjit::x86::Gp RegPointer)
|
|
|
|
|
m_Assembler.mov(RegPointerValue, RegPointer);
|
|
|
|
|
RegPointer = RegPointerValue;
|
|
|
|
|
}
|
|
|
|
|
bool RegPointerProtect = m_RegWorkingSet.GetX86Protected(GetIndexFromX86Reg(RegPointer));
|
|
|
|
|
if (!RegPointerProtect)
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(RegPointer), true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
asmjit::x86::Gp TempReg2 = m_RegWorkingSet.Map_TempReg(x86Reg_Unknown, -1, false, false);
|
|
|
|
|
m_Assembler.fnstsw(asmjit::x86::ax);
|
|
|
|
|
m_Assembler.and_(asmjit::x86::ax, 0x3D);
|
|
|
|
@ -9192,6 +9213,11 @@ void CX86RecompilerOps::CompileCheckFPUResult64(asmjit::x86::Gp RegPointer)
|
|
|
|
|
CompileExit(m_CompilePC + 4, m_CompilePC + 4, ExitRegSet, ExitReason_Normal, false, &CX86Ops::JmpLabel);
|
|
|
|
|
m_Assembler.bind(ValueSame);
|
|
|
|
|
m_Assembler.bind(DoNoModify);
|
|
|
|
|
|
|
|
|
|
if (!RegPointerProtect)
|
|
|
|
|
{
|
|
|
|
|
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(RegPointer), false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::CompileCop1Test()
|
|
|
|
@ -10872,6 +10898,26 @@ void CX86RecompilerOps::CompileStoreMemoryValue(asmjit::x86::Gp AddressReg, asmj
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_Opcode(void (CX86Ops::*Instruction)(void))
|
|
|
|
|
{
|
|
|
|
|
CompileInitFpuOperation(CRegInfo::RoundDefault);
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
asmjit::x86::Gp TempReg = m_RegWorkingSet.FPRValuePointer(m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
CompileCheckFPUInput(TempReg, FpuOpSize_64bit);
|
|
|
|
|
m_RegWorkingSet.SetX86Protected(GetIndexFromX86Reg(TempReg), false);
|
|
|
|
|
m_RegWorkingSet.PrepareFPTopToBe(m_Opcode.fd, m_Opcode.fs, CRegInfo::FPU_Double);
|
|
|
|
|
(m_Assembler.*Instruction)();
|
|
|
|
|
m_Assembler.mov(TempReg, (uint64_t)&m_TempValue64);
|
|
|
|
|
m_Assembler.fpuStoreQwordFromX86Reg(m_RegWorkingSet.StackTopPos(), TempReg, false);
|
|
|
|
|
CompileCheckFPUResult64(TempReg);
|
|
|
|
|
m_RegWorkingSet.SetFPTopAs(m_Opcode.fd);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CX86RecompilerOps::COP1_D_Opcode(void (CX86Ops::*Instruction)(const asmjit::x86::Mem &))
|
|
|
|
|
{
|
|
|
|
|
CompileInitFpuOperation(CRegInfo::RoundDefault);
|
|
|
|
|