common/fp/unpacked: Correct edge-cases within FPUnpack for half-precision floating point

This corrects one case where floating-point exceptions could be set when
they're not supposed to be.

This also corrects a case where values were being treated as NaNs when
they weren't supposed to be.
This commit is contained in:
Lioncash 2019-03-09 19:15:51 -05:00 committed by MerryMage
parent 32364fb62c
commit a829c93406

View file

@ -33,7 +33,9 @@ std::tuple<FPType, bool, FPUnpacked> FPUnpackBase(FPT op, FPCR fpcr, FPSR& fpsr)
if (frac_raw == 0 || fpcr.FZ16()) { if (frac_raw == 0 || fpcr.FZ16()) {
return {FPType::Zero, sign, {sign, 0, 0}}; return {FPType::Zero, sign, {sign, 0, 0}};
} }
return {FPType::Nonzero, sign, ToNormalized(sign, denormal_exponent, frac_raw)};
} }
if (frac_raw == 0 || fpcr.FZ()) { if (frac_raw == 0 || fpcr.FZ()) {
if (frac_raw != 0) { if (frac_raw != 0) {
FPProcessException(FPExc::InputDenorm, fpcr, fpsr); FPProcessException(FPExc::InputDenorm, fpcr, fpsr);
@ -46,7 +48,7 @@ std::tuple<FPType, bool, FPUnpacked> FPUnpackBase(FPT op, FPCR fpcr, FPSR& fpsr)
const bool exp_all_ones = exp_raw == Common::Ones<FPT>(FPInfo<FPT>::exponent_width); const bool exp_all_ones = exp_raw == Common::Ones<FPT>(FPInfo<FPT>::exponent_width);
const bool ahp_disabled = is_half_precision && !fpcr.AHP(); const bool ahp_disabled = is_half_precision && !fpcr.AHP();
if (exp_all_ones || ahp_disabled) { if ((exp_all_ones && !is_half_precision) || (exp_all_ones && ahp_disabled)) {
if (frac_raw == 0) { if (frac_raw == 0) {
return {FPType::Infinity, sign, ToNormalized(sign, 1000000, 1)}; return {FPType::Infinity, sign, ToNormalized(sign, 1000000, 1)};
} }