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;
}
@ -3212,17 +3212,14 @@ 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)
{
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;
@ -3244,7 +3241,6 @@ bool R4300iOp::CheckFPUResult32(float & Result)
break;
}
}
}
else
{
DoException = true;
@ -3264,21 +3260,29 @@ 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)
{
if (Except == 0 || !SetFPUException())
{
*((uint64_t *)&Result) = 0x7FF7FFFFFFFFFFFF;
}
else
{
DoException = true;
}
}
else if (fptype == FP_SUBNORMAL)
{
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;
DoException = true;
}
else
else if (Except == 0 || !SetFPUException())
{
StatusReg.Cause.Underflow = 1;
StatusReg.Flags.Underflow = 1;
@ -3300,19 +3304,21 @@ bool R4300iOp::CheckFPUResult64(double & Result)
break;
}
}
}
return false;
}
bool R4300iOp::CheckFPUException(void)
{
int Except = fetestexcept(FE_ALL_EXCEPT);
if (Except == 0 || !SetFPUException())
else
{
return false;
DoException = true;
}
}
else if (Except != 0 && SetFPUException())
{
DoException = true;
}
if (DoException)
{
g_Reg->TriggerException(EXC_FPE);
return true;
}
return false;
}
bool R4300iOp::CheckFPUInvalidException(void)

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);