Core: Split CheckFPUException into CheckFPUException and CheckFPUInvalidException
This commit is contained in:
parent
7c71ec21b5
commit
49a385e743
|
@ -3161,10 +3161,6 @@ bool R4300iOp::CheckFPUInput32Conv(const float & Value)
|
||||||
{
|
{
|
||||||
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
||||||
StatusReg.Cause.UnimplementedOperation = 1;
|
StatusReg.Cause.UnimplementedOperation = 1;
|
||||||
Exception = true;
|
|
||||||
}
|
|
||||||
if (Exception)
|
|
||||||
{
|
|
||||||
g_Reg->DoFloatingPointException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
|
g_Reg->DoFloatingPointException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
|
||||||
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||||
|
@ -3319,92 +3315,14 @@ bool R4300iOp::CheckFPUResult64(double & Result)
|
||||||
bool R4300iOp::CheckFPUException(void)
|
bool R4300iOp::CheckFPUException(void)
|
||||||
{
|
{
|
||||||
int Except = fetestexcept(FE_ALL_EXCEPT);
|
int Except = fetestexcept(FE_ALL_EXCEPT);
|
||||||
if (Except == 0)
|
if (Except == 0 || !SetFPUException())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
g_Reg->DoFloatingPointException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
|
||||||
bool Res = false;
|
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||||
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||||
if ((Except & FE_UNDERFLOW) != 0)
|
return true;
|
||||||
{
|
|
||||||
if (StatusReg.FlushSubnormals == 0 || StatusReg.Enable.Underflow || StatusReg.Enable.Inexact)
|
|
||||||
{
|
|
||||||
StatusReg.Cause.UnimplementedOperation = 1;
|
|
||||||
Res = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Res)
|
|
||||||
{
|
|
||||||
if ((Except & FE_INEXACT) != 0)
|
|
||||||
{
|
|
||||||
StatusReg.Cause.Inexact = 1;
|
|
||||||
if (StatusReg.Enable.Inexact)
|
|
||||||
{
|
|
||||||
Res = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusReg.Flags.Inexact = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((Except & FE_UNDERFLOW) != 0)
|
|
||||||
{
|
|
||||||
StatusReg.Cause.Underflow = 1;
|
|
||||||
if (StatusReg.Enable.Underflow)
|
|
||||||
{
|
|
||||||
Res = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusReg.Flags.Underflow = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((Except & FE_OVERFLOW) != 0)
|
|
||||||
{
|
|
||||||
StatusReg.Cause.Overflow = 1;
|
|
||||||
if (StatusReg.Enable.Overflow)
|
|
||||||
{
|
|
||||||
Res = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusReg.Flags.Overflow = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((Except & FE_DIVBYZERO) != 0)
|
|
||||||
{
|
|
||||||
StatusReg.Cause.DivisionByZero = 1;
|
|
||||||
if (StatusReg.Enable.DivisionByZero)
|
|
||||||
{
|
|
||||||
Res = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusReg.Flags.DivisionByZero = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((Except & FE_INVALID) != 0)
|
|
||||||
{
|
|
||||||
StatusReg.Cause.InvalidOperation = 1;
|
|
||||||
if (StatusReg.Enable.InvalidOperation)
|
|
||||||
{
|
|
||||||
Res = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StatusReg.Flags.InvalidOperation = 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 Res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool R4300iOp::CheckFPUInvalidException(void)
|
bool R4300iOp::CheckFPUInvalidException(void)
|
||||||
|
@ -3444,3 +3362,80 @@ bool R4300iOp::CheckFPUInvalidException(void)
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool R4300iOp::SetFPUException(void)
|
||||||
|
{
|
||||||
|
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
||||||
|
int Except = fetestexcept(FE_ALL_EXCEPT);
|
||||||
|
if ((Except & FE_UNDERFLOW) != 0)
|
||||||
|
{
|
||||||
|
if (StatusReg.FlushSubnormals == 0 || StatusReg.Enable.Underflow || StatusReg.Enable.Inexact)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.UnimplementedOperation = 1;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Res = false;
|
||||||
|
if ((Except & FE_INEXACT) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.Inexact = 1;
|
||||||
|
if (StatusReg.Enable.Inexact)
|
||||||
|
{
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusReg.Flags.Inexact = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Except & FE_UNDERFLOW) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.Underflow = 1;
|
||||||
|
if (StatusReg.Enable.Underflow)
|
||||||
|
{
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusReg.Flags.Underflow = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Except & FE_OVERFLOW) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.Overflow = 1;
|
||||||
|
if (StatusReg.Enable.Overflow)
|
||||||
|
{
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusReg.Flags.Overflow = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Except & FE_DIVBYZERO) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.DivisionByZero = 1;
|
||||||
|
if (StatusReg.Enable.DivisionByZero)
|
||||||
|
{
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusReg.Flags.DivisionByZero = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((Except & FE_INVALID) != 0)
|
||||||
|
{
|
||||||
|
StatusReg.Cause.InvalidOperation = 1;
|
||||||
|
if (StatusReg.Enable.InvalidOperation)
|
||||||
|
{
|
||||||
|
Res = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusReg.Flags.InvalidOperation = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Res;
|
||||||
|
}
|
||||||
|
|
|
@ -264,6 +264,7 @@ protected:
|
||||||
static bool CheckFPUResult64(double & Result);
|
static bool CheckFPUResult64(double & Result);
|
||||||
static bool CheckFPUException(void);
|
static bool CheckFPUException(void);
|
||||||
static bool CheckFPUInvalidException(void);
|
static bool CheckFPUInvalidException(void);
|
||||||
|
static bool SetFPUException(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