Core: Have fpu ops check the input of fs and ft at the same time
This commit is contained in:
parent
dc4fa211b0
commit
62bf10e505
|
@ -2321,7 +2321,7 @@ void R4300iOp::COP1_S_ADD()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput32(*(float *)m_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs32(*(float *)m_FPR_S_L[m_Opcode.fs], *(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2339,7 +2339,7 @@ void R4300iOp::COP1_S_SUB()
|
|||
{
|
||||
return;
|
||||
}
|
||||
if (CheckFPUInput32(*(float *)m_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs32(*(float *)m_FPR_S_L[m_Opcode.fs], *(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2358,7 +2358,7 @@ void R4300iOp::COP1_S_MUL()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput32(*(float *)m_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs32(*(float *)m_FPR_S_L[m_Opcode.fs], *(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2377,7 +2377,7 @@ void R4300iOp::COP1_S_DIV()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput32(*(float *)m_FPR_S_L[m_Opcode.fs]) || CheckFPUInput32(*(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs32(*(float *)m_FPR_S_L[m_Opcode.fs], *(float *)m_FPR_UW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2724,7 +2724,7 @@ void R4300iOp::COP1_D_ADD()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput64(*(double *)m_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs64(*(double *)m_FPR_D[m_Opcode.fs],*(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2743,7 +2743,7 @@ void R4300iOp::COP1_D_SUB()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput64(*(double *)m_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs64(*(double *)m_FPR_D[m_Opcode.fs],*(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2762,7 +2762,7 @@ void R4300iOp::COP1_D_MUL()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput64(*(double *)m_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs64(*(double *)m_FPR_D[m_Opcode.fs], *(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -2781,7 +2781,7 @@ void R4300iOp::COP1_D_DIV()
|
|||
return;
|
||||
}
|
||||
|
||||
if (CheckFPUInput64(*(double *)m_FPR_D[m_Opcode.fs]) || CheckFPUInput64(*(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
if (CheckFPUInputs64(*(double *)m_FPR_D[m_Opcode.fs], *(double *)m_FPR_UDW[m_Opcode.ft]))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -3371,6 +3371,60 @@ bool R4300iOp::CheckFPUInput32(const float & Value)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool R4300iOp::CheckFPUInputs32(const float & Value, const float & Value2)
|
||||
{
|
||||
bool Exception = false;
|
||||
bool isNan[2] =
|
||||
{
|
||||
((*((uint32_t *)&Value) & 0x7F800000) == 0x7F800000 && (*((uint32_t *)&Value) & 0x007FFFFF) != 0x00000000),
|
||||
((*((uint32_t *)&Value2) & 0x7F800000) == 0x7F800000 && (*((uint32_t *)&Value2) & 0x007FFFFF) != 0x00000000)
|
||||
};
|
||||
bool isQNan[2] =
|
||||
{
|
||||
((*(uint32_t *)&Value >= 0x7F800001 && *(uint32_t *)&Value < 0x7FC00000) || (*(uint32_t *)&Value >= 0xFF800001 && *(uint32_t *)&Value < 0xFFC00000)),
|
||||
((*(uint32_t *)&Value2 >= 0x7F800001 && *(uint32_t *)&Value2 < 0x7FC00000) || (*(uint32_t *)&Value2 >= 0xFF800001 && *(uint32_t *)&Value2 < 0xFFC00000))
|
||||
};
|
||||
bool isSubNormal[2] =
|
||||
{
|
||||
((*((uint32_t *)&Value) & 0x7F800000) == 0x00000000 && (*((uint32_t *)&Value) & 0x007FFFFF) != 0x00000000),
|
||||
((*((uint32_t *)&Value2) & 0x7F800000) == 0x00000000 && (*((uint32_t *)&Value2) & 0x007FFFFF) != 0x00000000)
|
||||
};
|
||||
|
||||
if (isSubNormal[0] || isSubNormal[1])
|
||||
{
|
||||
FPStatusReg & StatusReg = (FPStatusReg &)m_FPCR[31];
|
||||
StatusReg.Cause.UnimplementedOperation = 1;
|
||||
Exception = true;
|
||||
}
|
||||
else if (isNan[0] || isNan[1])
|
||||
{
|
||||
FPStatusReg & StatusReg = (FPStatusReg &)m_FPCR[31];
|
||||
if (isQNan[0] || isQNan[1])
|
||||
{
|
||||
StatusReg.Cause.UnimplementedOperation = 1;
|
||||
Exception = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusReg.Cause.InvalidOperation = 1;
|
||||
if (StatusReg.Enable.InvalidOperation)
|
||||
{
|
||||
Exception = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusReg.Flags.InvalidOperation = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Exception)
|
||||
{
|
||||
m_Reg.TriggerException(EXC_FPE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool R4300iOp::CheckFPUInput32Conv(const float & Value)
|
||||
{
|
||||
uint32_t InvalidValueMax = 0x5a000000, InvalidMinValue = 0xda000000;
|
||||
|
@ -3427,6 +3481,60 @@ bool R4300iOp::CheckFPUInput64(const double & Value)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool R4300iOp::CheckFPUInputs64(const double & Value, const double & Value2)
|
||||
{
|
||||
bool isNan[2] =
|
||||
{
|
||||
((*((uint64_t *)&Value) & 0x7FF0000000000000ULL) == 0x7FF0000000000000ULL && (*((uint64_t *)&Value) & 0x000FFFFFFFFFFFFFULL) != 0x0000000000000000ULL),
|
||||
((*((uint64_t *)&Value2) & 0x7FF0000000000000ULL) == 0x7FF0000000000000ULL && (*((uint64_t *)&Value2) & 0x000FFFFFFFFFFFFFULL) != 0x0000000000000000ULL)
|
||||
};
|
||||
bool isQNan[2] =
|
||||
{
|
||||
((*(uint64_t *)&Value >= 0x7FF0000000000001 && *(uint64_t *)&Value <= 0x7FF7FFFFFFFFFFFF) || (*(uint64_t *)&Value >= 0xFFF0000000000001 && *(uint64_t *)&Value <= 0xFFF7FFFFFFFFFFFF)),
|
||||
((*(uint64_t *)&Value2 >= 0x7FF0000000000001 && *(uint64_t *)&Value2 <= 0x7FF7FFFFFFFFFFFF) || (*(uint64_t *)&Value2 >= 0xFFF0000000000001 && *(uint64_t *)&Value2 <= 0xFFF7FFFFFFFFFFFF)),
|
||||
};
|
||||
bool isSubNormal[2] =
|
||||
{
|
||||
((*((uint64_t *)&Value) & 0x7FF0000000000000ULL) == 0x0000000000000000ULL && (*((uint64_t *)&Value) & 0x000FFFFFFFFFFFFFULL) != 0x0000000000000000ULL),
|
||||
((*((uint64_t *)&Value2) & 0x7FF0000000000000ULL) == 0x0000000000000000ULL && (*((uint64_t *)&Value2) & 0x000FFFFFFFFFFFFFULL) != 0x0000000000000000ULL)
|
||||
};
|
||||
|
||||
bool Exception = false;
|
||||
if (isSubNormal[0] || isSubNormal[1])
|
||||
{
|
||||
FPStatusReg & StatusReg = (FPStatusReg &)m_FPCR[31];
|
||||
StatusReg.Cause.UnimplementedOperation = 1;
|
||||
Exception = true;
|
||||
}
|
||||
else if (isNan[0] || isNan[1])
|
||||
{
|
||||
FPStatusReg & StatusReg = (FPStatusReg &)m_FPCR[31];
|
||||
if (isQNan[0] || isQNan[1])
|
||||
{
|
||||
StatusReg.Cause.UnimplementedOperation = 1;
|
||||
Exception = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusReg.Cause.InvalidOperation = 1;
|
||||
if (StatusReg.Enable.InvalidOperation)
|
||||
{
|
||||
Exception = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusReg.Flags.InvalidOperation = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (Exception)
|
||||
{
|
||||
m_Reg.TriggerException(EXC_FPE);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool R4300iOp::CheckFPUInput64Conv(const double & Value)
|
||||
{
|
||||
uint64_t InvalidValueMax = 0x4340000000000000, InvalidMinValue = 0xc340000000000000;
|
||||
|
|
|
@ -292,8 +292,10 @@ private:
|
|||
|
||||
bool TestCop1UsableException(void);
|
||||
bool CheckFPUInput32(const float & Value);
|
||||
bool CheckFPUInputs32(const float & Value, const float & Value2);
|
||||
bool CheckFPUInput32Conv(const float & Value);
|
||||
bool CheckFPUInput64(const double & Value);
|
||||
bool CheckFPUInputs64(const double & Value, const double & Value2);
|
||||
bool CheckFPUInput64Conv(const double & Value);
|
||||
bool CheckFPUResult32(float & Result);
|
||||
bool CheckFPUResult64(double & Result);
|
||||
|
|
|
@ -110,6 +110,9 @@ bool MIPSInterfaceHandler::Write32(uint32_t Address, uint32_t Value, uint32_t Ma
|
|||
MI_MODE_REG |= MI_MODE_RDRAM;
|
||||
}
|
||||
break;
|
||||
case 0x04300008:
|
||||
//read only
|
||||
break;
|
||||
case 0x0430000C:
|
||||
if ((MaskedValue & MI_INTR_MASK_CLR_SP) != 0)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue