func: float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
  
  {
  
      flag aSign;
  
      int_fast16_t aExp;
  
      uint32_t aSig;
  
      uint32_t mask;
  
      uint32_t increment;
  
      int8 roundingMode;
  
      a = float32_squash_input_denormal(a STATUS_VAR);
  
  
  
      aSig = extractFloat32Frac( a );
  
      aExp = extractFloat32Exp( a );
  
      aSign = extractFloat32Sign( a );
  
      if ( aExp == 0xFF ) {
  
          if (aSig) {
  
              /* Input is a NaN */
  
              float16 r = commonNaNToFloat16( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
  
              if (!ieee) {
  
                  return packFloat16(aSign, 0, 0);
  
              }
  
              return r;
  
          }
  
          /* Infinity */
  
          if (!ieee) {
  
              float_raise(float_flag_invalid STATUS_VAR);
  
              return packFloat16(aSign, 0x1f, 0x3ff);
  
          }
  
          return packFloat16(aSign, 0x1f, 0);
  
      }
  
      if (aExp == 0 && aSig == 0) {
  
          return packFloat16(aSign, 0, 0);
  
      }
  
      /* Decimal point between bits 22 and 23.  */
  
      aSig |= 0x00800000;
  
      aExp -= 0x7f;
  
      if (aExp < -14) {
  
          mask = 0x00ffffff;
  
          if (aExp >= -24) {
  
              mask >>= 25 + aExp;
  
          }
  
      } else {
  
          mask = 0x00001fff;
  
      }
  
      if (aSig & mask) {
  
          float_raise( float_flag_underflow STATUS_VAR );
  
          roundingMode = STATUS(float_rounding_mode);
  
          switch (roundingMode) {
  
          case float_round_nearest_even:
  
              increment = (mask + 1) >> 1;
  
              if ((aSig & mask) == increment) {
  
                  increment = aSig & (increment << 1);
  
              }
  
              break;
  
          case float_round_up:
  
              increment = aSign ? 0 : mask;
  
              break;
  
          case float_round_down:
  
              increment = aSign ? mask : 0;
  
              break;
  
          default: /* round_to_zero */
  
              increment = 0;
  
              break;
  
          }
  
          aSig += increment;
  
          if (aSig >= 0x01000000) {
  
              aSig >>= 1;
  
              aExp++;
  
          }
  
      } else if (aExp < -14
  
            && STATUS(float_detect_tininess) == float_tininess_before_rounding) {
  
          float_raise( float_flag_underflow STATUS_VAR);
  
      }
  
  
  
      if (ieee) {
  
          if (aExp > 15) {
  
              float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
  
              return packFloat16(aSign, 0x1f, 0);
  
          }
  
      } else {
  
          if (aExp > 16) {
  
              float_raise(float_flag_invalid | float_flag_inexact STATUS_VAR);
  
              return packFloat16(aSign, 0x1f, 0x3ff);
  
          }
  
      }
  
      if (aExp < -24) {
  
          return packFloat16(aSign, 0, 0);
  
      }
  
      if (aExp < -14) {
  
          aSig >>= -14 - aExp;
  
          aExp = -14;
  
      }
  
      return packFloat16(aSign, aExp + 14, aSig >> 13);
  
  }
  