Core: Merge CheckFPUException into CheckFPUResult32
This commit is contained in:
parent
62b29622ca
commit
6e58edb076
|
@ -2044,7 +2044,7 @@ void R4300iOp::COP1_S_ADD()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (*(float *)_FPR_S[m_Opcode.fs] + *(float *)_FPR_S[m_Opcode.ft]);
|
float Result = (*(float *)_FPR_S[m_Opcode.fs] + *(float *)_FPR_S[m_Opcode.ft]);
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2069,13 +2069,11 @@ void R4300iOp::COP1_S_SUB()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (*(float *)_FPR_S[m_Opcode.fs] - *(float *)_FPR_S[m_Opcode.ft]);
|
float Result = (*(float *)_FPR_S[m_Opcode.fs] - *(float *)_FPR_S[m_Opcode.ft]);
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
|
*(uint32_t *)_FPR_S[m_Opcode.fd] = *(uint32_t *)&Result;
|
||||||
|
|
||||||
fesetround(*_RoundingModel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void R4300iOp::COP1_S_MUL()
|
void R4300iOp::COP1_S_MUL()
|
||||||
|
@ -2096,7 +2094,7 @@ void R4300iOp::COP1_S_MUL()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (*(float *)_FPR_S[m_Opcode.fs] * *(float *)_FPR_S[m_Opcode.ft]);
|
float Result = (*(float *)_FPR_S[m_Opcode.fs] * *(float *)_FPR_S[m_Opcode.ft]);
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2121,7 +2119,7 @@ void R4300iOp::COP1_S_DIV()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (*(float *)_FPR_S[m_Opcode.fs] / *(float *)_FPR_S[m_Opcode.ft]);
|
float Result = (*(float *)_FPR_S[m_Opcode.fs] / *(float *)_FPR_S[m_Opcode.ft]);
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2146,7 +2144,7 @@ void R4300iOp::COP1_S_SQRT()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = sqrtf(*(float *)(_FPR_S[m_Opcode.fs]));
|
float Result = sqrtf(*(float *)(_FPR_S[m_Opcode.fs]));
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2171,7 +2169,7 @@ void R4300iOp::COP1_S_ABS()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (float)fabs(*(float *)_FPR_S[m_Opcode.fs]);
|
float Result = (float)fabs(*(float *)_FPR_S[m_Opcode.fs]);
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2206,7 +2204,7 @@ void R4300iOp::COP1_S_NEG()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f);
|
float Result = (*(float *)_FPR_S[m_Opcode.fs] * -1.0f);
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2864,7 +2862,7 @@ void R4300iOp::COP1_D_CVT_S()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (float)*(double *)_FPR_D[m_Opcode.fs];
|
float Result = (float)*(double *)_FPR_D[m_Opcode.fs];
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -2993,7 +2991,7 @@ void R4300iOp::COP1_W_CVT_S()
|
||||||
fesetround(*_RoundingModel);
|
fesetround(*_RoundingModel);
|
||||||
feclearexcept(FE_ALL_EXCEPT);
|
feclearexcept(FE_ALL_EXCEPT);
|
||||||
float Result = (float)*(int32_t *)_FPR_S[m_Opcode.fs];
|
float Result = (float)*(int32_t *)_FPR_S[m_Opcode.fs];
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3039,7 +3037,7 @@ void R4300iOp::COP1_L_CVT_S()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
float Result = (float)fs;
|
float Result = (float)fs;
|
||||||
if (CheckFPUException() || CheckFPUResult32(Result))
|
if (CheckFPUResult32(Result))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3278,49 +3276,77 @@ bool R4300iOp::CheckFPUInput64Conv(const double & Value)
|
||||||
|
|
||||||
bool R4300iOp::CheckFPUResult32(float & Result)
|
bool R4300iOp::CheckFPUResult32(float & Result)
|
||||||
{
|
{
|
||||||
|
int Except = fetestexcept(FE_ALL_EXCEPT);
|
||||||
|
bool DoException = false;
|
||||||
|
|
||||||
if ((*((uint32_t *)&Result) & 0x7F800000) == 0x7F800000 && (*((uint32_t *)&Result) & 0x007FFFFF) != 0x00000000) // Nan
|
if ((*((uint32_t *)&Result) & 0x7F800000) == 0x7F800000 && (*((uint32_t *)&Result) & 0x007FFFFF) != 0x00000000) // Nan
|
||||||
{
|
{
|
||||||
*((uint32_t *)&Result) = 0x7fbfffff;
|
if (Except == 0 || !SetFPUException())
|
||||||
}
|
|
||||||
else if ((*((uint32_t *)&Result) & 0x7F800000) == 0x00000000 && (*((uint32_t *)&Result) & 0x007FFFFF) != 0x00000000) // Sub Normal
|
|
||||||
{
|
|
||||||
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
|
||||||
if (!StatusReg.FlushSubnormals || StatusReg.Enable.Underflow || StatusReg.Enable.Inexact)
|
|
||||||
{
|
{
|
||||||
StatusReg.Cause.UnimplementedOperation = 1;
|
*((uint32_t *)&Result) = 0x7fbfffff;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
StatusReg.Cause.Underflow = 1;
|
DoException = true;
|
||||||
if (!StatusReg.Enable.Underflow)
|
}
|
||||||
|
}
|
||||||
|
else if ((*((uint32_t *)&Result) & 0x7F800000) == 0x00000000 && (*((uint32_t *)&Result) & 0x007FFFFF) != 0x00000000) // Sub Normal
|
||||||
|
{
|
||||||
|
if (Except == 0 || !SetFPUException())
|
||||||
|
{
|
||||||
|
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
|
||||||
|
if (!StatusReg.FlushSubnormals || StatusReg.Enable.Underflow || StatusReg.Enable.Inexact)
|
||||||
{
|
{
|
||||||
StatusReg.Flags.Underflow = 1;
|
StatusReg.Cause.UnimplementedOperation = 1;
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
StatusReg.Cause.Inexact = 1;
|
|
||||||
if (!StatusReg.Enable.Inexact)
|
|
||||||
{
|
{
|
||||||
StatusReg.Flags.Inexact = 1;
|
StatusReg.Cause.Underflow = 1;
|
||||||
}
|
if (!StatusReg.Enable.Underflow)
|
||||||
|
{
|
||||||
|
StatusReg.Flags.Underflow = 1;
|
||||||
|
}
|
||||||
|
|
||||||
switch (*_RoundingModel)
|
StatusReg.Cause.Inexact = 1;
|
||||||
{
|
if (!StatusReg.Enable.Inexact)
|
||||||
case FE_TONEAREST:
|
{
|
||||||
case FE_TOWARDZERO:
|
StatusReg.Flags.Inexact = 1;
|
||||||
Result = Result >= 0.0f ? 0.0f : -0.0f;
|
}
|
||||||
break;
|
|
||||||
case FE_UPWARD:
|
switch (*_RoundingModel)
|
||||||
Result = Result >= 0.0f ? 1.175494351e-38F : -0.0f;
|
{
|
||||||
break;
|
case FE_TONEAREST:
|
||||||
case FE_DOWNWARD:
|
case FE_TOWARDZERO:
|
||||||
Result = Result >= 0.0f ? 0.0f : -1.175494351e-38F;
|
Result = Result >= 0.0f ? 0.0f : -0.0f;
|
||||||
break;
|
break;
|
||||||
|
case FE_UPWARD:
|
||||||
|
Result = Result >= 0.0f ? 1.175494351e-38F : -0.0f;
|
||||||
|
break;
|
||||||
|
case FE_DOWNWARD:
|
||||||
|
Result = Result >= 0.0f ? 0.0f : -1.175494351e-38F;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DoException = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (Except != 0 && SetFPUException())
|
||||||
|
{
|
||||||
|
DoException = true;
|
||||||
|
}
|
||||||
|
if (DoException)
|
||||||
|
{
|
||||||
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue