Core: Improve R4300iOp::COP1_S_CVT_W
This commit is contained in:
parent
71ef28fd55
commit
5cfb80fcfc
|
@ -2377,7 +2377,19 @@ void R4300iOp::COP1_S_CVT_W()
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Float_RoundToInteger32(&*(int32_t *)_FPR_S[m_Opcode.fd], &*(float *)_FPR_S[m_Opcode.fs], *_RoundingModel);
|
_FPCR[31] &= ~0x0003F000;
|
||||||
|
fesetround(*_RoundingModel);
|
||||||
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
|
if (!CheckFPUInput32Conv(*(float *)_FPR_S[m_Opcode.fs]))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int32_t Result = (int32_t)rint(*(float *)_FPR_S[m_Opcode.fs]);
|
||||||
|
if (CheckFPUInvalidException())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void R4300iOp::COP1_S_CVT_L()
|
void R4300iOp::COP1_S_CVT_L()
|
||||||
|
@ -3141,6 +3153,26 @@ bool R4300iOp::CheckFPUInput32(const float & Value)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool R4300iOp::CheckFPUInput32Conv(const float & Value)
|
||||||
|
{
|
||||||
|
int Type = fpclassify(Value);
|
||||||
|
bool Exception = false;
|
||||||
|
if (Type == FP_SUBNORMAL || Type == FP_INFINITE || Type == FP_NAN)
|
||||||
|
{
|
||||||
|
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
||||||
|
StatusReg.Cause.UnimplementedOperation = 1;
|
||||||
|
Exception = true;
|
||||||
|
}
|
||||||
|
if (Exception)
|
||||||
|
{
|
||||||
|
g_Reg->DoFloatingPointException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
|
||||||
|
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||||
|
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool R4300iOp::CheckFPUInput64(const double & Value)
|
bool R4300iOp::CheckFPUInput64(const double & Value)
|
||||||
{
|
{
|
||||||
int Type = fpclassify(Value);
|
int Type = fpclassify(Value);
|
||||||
|
@ -3374,3 +3406,41 @@ bool R4300iOp::CheckFPUException(void)
|
||||||
}
|
}
|
||||||
return Res;
|
return Res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool R4300iOp::CheckFPUInvalidException(void)
|
||||||
|
{
|
||||||
|
int Except = fetestexcept(FE_ALL_EXCEPT);
|
||||||
|
if (Except == 0)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
||||||
|
bool Res = false;
|
||||||
|
if ((Except & FE_INVALID) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.UnimplementedOperation = 1;
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else if ((Except & FE_INEXACT) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.Inexact = 1;
|
||||||
|
if (StatusReg.Enable.Inexact)
|
||||||
|
{
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusReg.Flags.Inexact = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Res)
|
||||||
|
{
|
||||||
|
g_Reg->DoFloatingPointException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
|
||||||
|
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||||
|
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
|
@ -258,10 +258,12 @@ protected:
|
||||||
static void GenerateTLBWriteException(uint64_t VAddr, const char * function);
|
static void GenerateTLBWriteException(uint64_t VAddr, const char * function);
|
||||||
static bool TestCop1UsableException(void);
|
static bool TestCop1UsableException(void);
|
||||||
static bool CheckFPUInput32(const float & Value);
|
static bool CheckFPUInput32(const float & Value);
|
||||||
|
static bool CheckFPUInput32Conv(const float & Value);
|
||||||
static bool CheckFPUInput64(const double & Value);
|
static bool CheckFPUInput64(const double & Value);
|
||||||
static bool CheckFPUResult32(float & Result);
|
static bool CheckFPUResult32(float & Result);
|
||||||
static bool CheckFPUResult64(double & Result);
|
static bool CheckFPUResult64(double & Result);
|
||||||
static bool CheckFPUException(void);
|
static bool CheckFPUException(void);
|
||||||
|
static bool CheckFPUInvalidException(void);
|
||||||
|
|
||||||
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
|
static const uint32_t SWL_MASK[4], SWR_MASK[4], LWL_MASK[4], LWR_MASK[4];
|
||||||
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
|
static const int32_t SWL_SHIFT[4], SWR_SHIFT[4], LWL_SHIFT[4], LWR_SHIFT[4];
|
||||||
|
|
Loading…
Reference in New Issue