-template<class FP16_INT_T,
- int FP16_BIAS, int FP16_MANTISSA_BITS, int FP16_EXPONENT_BITS, int FP16_MAX_EXPONENT,
- int FP32_BIAS, int FP32_MANTISSA_BITS, int FP32_EXPONENT_BITS, int FP32_MAX_EXPONENT>
-inline float fp_upconvert(FP16_INT_T x)
-{
- int sign = x.val >> (FP16_MANTISSA_BITS + FP16_EXPONENT_BITS);
- int exponent = (x.val & ((1U << (FP16_MANTISSA_BITS + FP16_EXPONENT_BITS)) - 1)) >> FP16_MANTISSA_BITS;
- unsigned int mantissa = x.val & ((1U << FP16_MANTISSA_BITS) - 1);
-
- int sign32;
- int exponent32;
- unsigned int mantissa32;
-
- if (exponent == 0) {
- /*
- * Denormals, or zero. Zero is still zero, denormals become
- * ordinary numbers.
- */
- if (mantissa == 0) {
- sign32 = sign;
- exponent32 = 0;
- mantissa32 = 0;
- } else {
- sign32 = sign;
- exponent32 = FP32_BIAS - FP16_BIAS;
- mantissa32 = mantissa << (FP32_MANTISSA_BITS - FP16_MANTISSA_BITS + 1);
-
- /* Normalize the number. */
- while ((mantissa32 & (1U << FP32_MANTISSA_BITS)) == 0) {
- --exponent32;
- mantissa32 <<= 1;
- }
-
- /* Clear the now-implicit one-bit. */
- mantissa32 &= ~(1U << FP32_MANTISSA_BITS);
- }
- } else if (exponent == FP16_MAX_EXPONENT) {
- /*
- * Infinities or NaN (mantissa=0 => infinity, otherwise NaN).
- * We don't care much about NaNs, so let us just make sure we
- * keep the first bit (which signals signalling/non-signalling
- * in many implementations).
- */
- sign32 = sign;
- exponent32 = FP32_MAX_EXPONENT;
- mantissa32 = mantissa << (FP32_MANTISSA_BITS - FP16_MANTISSA_BITS);
- } else {
- sign32 = sign;
-
- /* Up-conversion is simple. Just re-bias the exponent... */
- exponent32 = exponent + FP32_BIAS - FP16_BIAS;
-
- /* ...and convert the mantissa. */
- mantissa32 = mantissa << (FP32_MANTISSA_BITS - FP16_MANTISSA_BITS);
- }