Core: Merge CheckFPUException into CheckFPUResult64

This commit is contained in:
zilmar 2023-08-31 18:52:34 +09:30
parent 91d1c6e237
commit 7199096748
2 changed files with 58 additions and 53 deletions

View File

@ -2327,7 +2327,7 @@ void R4300iOp::COP1_S_CVT_D()
return;
}
double Result = (double)(*(float *)_FPR_S[m_Opcode.fs]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2445,7 +2445,7 @@ void R4300iOp::COP1_D_ADD()
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] + *(double *)_FPR_D[m_Opcode.ft]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2464,7 +2464,7 @@ void R4300iOp::COP1_D_SUB()
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] - *(double *)_FPR_D[m_Opcode.ft]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2483,7 +2483,7 @@ void R4300iOp::COP1_D_MUL()
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] * *(double *)_FPR_D[m_Opcode.ft]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2502,7 +2502,7 @@ void R4300iOp::COP1_D_DIV()
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] / *(double *)_FPR_D[m_Opcode.ft]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2521,7 +2521,7 @@ void R4300iOp::COP1_D_SQRT()
return;
}
double Result = (double)sqrt(*(double *)_FPR_D[m_Opcode.fs]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2540,7 +2540,7 @@ void R4300iOp::COP1_D_ABS()
return;
}
double Result = fabs(*(double *)_FPR_D[m_Opcode.fs]);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2575,7 +2575,7 @@ void R4300iOp::COP1_D_NEG()
return;
}
double Result = (*(double *)_FPR_D[m_Opcode.fs] * -1.0);
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2872,7 +2872,7 @@ void R4300iOp::COP1_W_CVT_D()
return;
}
double Result = (double)*(int32_t *)_FPR_S[m_Opcode.fs];
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -2918,7 +2918,7 @@ void R4300iOp::COP1_L_CVT_D()
return;
}
double Result = (double)fs;
if (CheckFPUException() || CheckFPUResult64(Result))
if (CheckFPUResult64(Result))
{
return;
}
@ -3213,36 +3213,32 @@ bool R4300iOp::CheckFPUResult32(float & Result)
}
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)
{
FPStatusReg & StatusReg = (FPStatusReg &)_FPCR[31];
if (!StatusReg.FlushSubnormals || StatusReg.Enable.Underflow || StatusReg.Enable.Inexact)
{
StatusReg.Cause.UnimplementedOperation = 1;
g_Reg->TriggerException(EXC_FPE);
return true;
}
else
{
StatusReg.Cause.Underflow = 1;
StatusReg.Flags.Underflow = 1;
StatusReg.Cause.UnimplementedOperation = 1;
DoException = true;
}
else if (Except == 0 || !SetFPUException())
{
StatusReg.Cause.Underflow = 1;
StatusReg.Flags.Underflow = 1;
StatusReg.Cause.Inexact = 1;
StatusReg.Flags.Inexact = 1;
StatusReg.Cause.Inexact = 1;
StatusReg.Flags.Inexact = 1;
switch (StatusReg.RoundingMode)
{
case FPRoundingMode_RoundToNearest:
case FPRoundingMode_RoundTowardZero:
Result = Result >= 0.0f ? 0.0f : -0.0f;
break;
case FPRoundingMode_RoundTowardPlusInfinity:
Result = Result >= 0.0f ? 1.175494351e-38F : -0.0f;
break;
case FPRoundingMode_RoundTowardMinusInfinity:
Result = Result >= 0.0f ? 0.0f : -1.175494351e-38F;
break;
}
switch (StatusReg.RoundingMode)
{
case FPRoundingMode_RoundToNearest:
case FPRoundingMode_RoundTowardZero:
Result = Result >= 0.0f ? 0.0f : -0.0f;
break;
case FPRoundingMode_RoundTowardPlusInfinity:
Result = Result >= 0.0f ? 1.175494351e-38F : -0.0f;
break;
case FPRoundingMode_RoundTowardMinusInfinity:
Result = Result >= 0.0f ? 0.0f : -1.175494351e-38F;
break;
}
}
else
@ -3264,10 +3260,19 @@ bool R4300iOp::CheckFPUResult32(float & Result)
bool R4300iOp::CheckFPUResult64(double & Result)
{
int Except = fetestexcept(FE_ALL_EXCEPT);
bool DoException = false;
int fptype = fpclassify(Result);
if (fptype == FP_NAN)
{
*((uint64_t *)&Result) = 0x7FF7FFFFFFFFFFFF;
if (Except == 0 || !SetFPUException())
{
*((uint64_t *)&Result) = 0x7FF7FFFFFFFFFFFF;
}
else
{
DoException = true;
}
}
else if (fptype == FP_SUBNORMAL)
{
@ -3275,10 +3280,9 @@ bool R4300iOp::CheckFPUResult64(double & Result)
if (!StatusReg.FlushSubnormals || StatusReg.Enable.Underflow || StatusReg.Enable.Inexact)
{
StatusReg.Cause.UnimplementedOperation = 1;
g_Reg->TriggerException(EXC_FPE);
return true;
DoException = true;
}
else
else if (Except == 0 || !SetFPUException())
{
StatusReg.Cause.Underflow = 1;
StatusReg.Flags.Underflow = 1;
@ -3300,21 +3304,23 @@ bool R4300iOp::CheckFPUResult64(double & Result)
break;
}
}
else
{
DoException = true;
}
}
else if (Except != 0 && SetFPUException())
{
DoException = true;
}
if (DoException)
{
g_Reg->TriggerException(EXC_FPE);
return true;
}
return false;
}
bool R4300iOp::CheckFPUException(void)
{
int Except = fetestexcept(FE_ALL_EXCEPT);
if (Except == 0 || !SetFPUException())
{
return false;
}
g_Reg->TriggerException(EXC_FPE);
return true;
}
bool R4300iOp::CheckFPUInvalidException(void)
{
int Except = fetestexcept(FE_ALL_EXCEPT);

View File

@ -270,7 +270,6 @@ protected:
static bool CheckFPUInput64Conv(const double & Value);
static bool CheckFPUResult32(float & Result);
static bool CheckFPUResult64(double & Result);
static bool CheckFPUException(void);
static bool CheckFPUInvalidException(void);
static bool InitFpuOperation(FPRoundingMode RoundingModel);
static bool SetFPUException(void);