common/fp/unpacked: Handle half-precision unpacking in FPUnpackBase
This commit is contained in:
parent
8f9fe8690a
commit
7e814de445
1 changed files with 10 additions and 1 deletions
|
@ -23,11 +23,17 @@ std::tuple<FPType, bool, FPUnpacked> FPUnpackBase(FPT op, FPCR fpcr, FPSR& fpsr)
|
||||||
constexpr size_t mantissa_low_bit = 0;
|
constexpr size_t mantissa_low_bit = 0;
|
||||||
constexpr int denormal_exponent = FPInfo<FPT>::exponent_min - int(FPInfo<FPT>::explicit_mantissa_width);
|
constexpr int denormal_exponent = FPInfo<FPT>::exponent_min - int(FPInfo<FPT>::explicit_mantissa_width);
|
||||||
|
|
||||||
|
constexpr bool is_half_precision = std::is_same_v<FPT, u16>;
|
||||||
const bool sign = Common::Bit<sign_bit>(op);
|
const bool sign = Common::Bit<sign_bit>(op);
|
||||||
const FPT exp_raw = Common::Bits<exponent_low_bit, exponent_high_bit>(op);
|
const FPT exp_raw = Common::Bits<exponent_low_bit, exponent_high_bit>(op);
|
||||||
const FPT frac_raw = Common::Bits<mantissa_low_bit, mantissa_high_bit>(op);
|
const FPT frac_raw = Common::Bits<mantissa_low_bit, mantissa_high_bit>(op);
|
||||||
|
|
||||||
if (exp_raw == 0) {
|
if (exp_raw == 0) {
|
||||||
|
if constexpr (is_half_precision) {
|
||||||
|
if (frac_raw == 0 || fpcr.FZ16()) {
|
||||||
|
return {FPType::Zero, sign, {sign, 0, 0}};
|
||||||
|
}
|
||||||
|
}
|
||||||
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);
|
||||||
|
@ -38,7 +44,9 @@ std::tuple<FPType, bool, FPUnpacked> FPUnpackBase(FPT op, FPCR fpcr, FPSR& fpsr)
|
||||||
return {FPType::Nonzero, sign, ToNormalized(sign, denormal_exponent, frac_raw)};
|
return {FPType::Nonzero, sign, ToNormalized(sign, denormal_exponent, frac_raw)};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (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();
|
||||||
|
if (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)};
|
||||||
}
|
}
|
||||||
|
@ -52,6 +60,7 @@ std::tuple<FPType, bool, FPUnpacked> FPUnpackBase(FPT op, FPCR fpcr, FPSR& fpsr)
|
||||||
return {FPType::Nonzero, sign, {sign, exp, frac}};
|
return {FPType::Nonzero, sign, {sign, exp, frac}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template std::tuple<FPType, bool, FPUnpacked> FPUnpackBase<u16>(u16 op, FPCR fpcr, FPSR& fpsr);
|
||||||
template std::tuple<FPType, bool, FPUnpacked> FPUnpackBase<u32>(u32 op, FPCR fpcr, FPSR& fpsr);
|
template std::tuple<FPType, bool, FPUnpacked> FPUnpackBase<u32>(u32 op, FPCR fpcr, FPSR& fpsr);
|
||||||
template std::tuple<FPType, bool, FPUnpacked> FPUnpackBase<u64>(u64 op, FPCR fpcr, FPSR& fpsr);
|
template std::tuple<FPType, bool, FPUnpacked> FPUnpackBase<u64>(u64 op, FPCR fpcr, FPSR& fpsr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue