/* automatically generated by ieee754-misc-auto.sh, do not edit! */
#include <tme/common.h>
_TME_RCSID("$Id: ieee754-misc-auto.sh,v 1.6 2007/08/24 01:05:43 fredette Exp $");

#include <tme/ic/ieee754.h>
#include "softfloat-tme.h"
#include <math.h>
#ifdef HAVE_FLOAT_H
#include <float.h>
#endif
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif

/* this converts a value from IEEE 754 single precision format
   to the builtin C type that is the best match for that format: */
tme_ieee754_single_builtin_t
tme_ieee754_single_value_to_builtin(const tme_uint32_t *x_ieee754)
{
  tme_ieee754_single_builtin_t x_builtin;
  tme_uint32_t exponent;
  tme_uint32_t sign;
  tme_uint32_t chunk;
  tme_uint32_t fracor;

  /* get x's biased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU((*x_ieee754), ((tme_uint32_t) 0x7f800000));

  /* convert the fraction one 16-bit chunk at a time, and track
     a bitwise-or of all of the fraction bits: */
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754), 0x007f0000);
  fracor = chunk;
  /* if the exponent is nonzero, add the implicit integer bit: */
  if (exponent != 0) chunk |= ((0x007f0000 / _TME_FIELD_MASK_FACTOR(0x007f0000)) + 1);
  x_builtin = chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754), 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;

  /* get x's sign bit: */
  sign = ((*x_ieee754) & (((tme_uint32_t) 0x7f800000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000))));

  /* if the exponent is the biased maximum, x is either an infinity or a NaN: */
  if (exponent == (((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000)))) {

    /* if the fraction is nonzero, x is a NaN.  x must not be a NaN,
       because we were supposed to catch this earlier: */
    assert (fracor == 0);

    /* x is an infinity.  construct a builtin infinity: */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_infinity_float
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_infinity_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_infinity_long_double
#endif
      (sign);
  }

  /* if the exponent is the biased minimum and the fraction is
     all-bits-zero, x is a zero: */
  else if (exponent == 0
	   && fracor == 0) {

    /* construct a builtin zero: */
    x_builtin =
      (sign ?
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
       tme_float_negative_zero_float()
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
       tme_float_negative_zero_double()
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
       tme_float_negative_zero_long_double()
#endif
       : 0.0);
  }

  /* otherwise, x is an in-range value that needs to be converted: */
  else {

    /* scale the result by the unbiased exponent, adjusted by the
       number of fraction bits (which are currently to the left of the
       floating point in x_builtin): */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_radix2_scale_long_double
#endif
      (x_builtin, (exponent - ((((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000))) >> 1)) - 23);

    if (sign) {
      x_builtin = 0 - x_builtin;
    }
  }

  /* done: */
  return (x_builtin);
}

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 single precision format, to that
   format: */
const tme_uint32_t *
tme_ieee754_single_value_from_builtin(tme_ieee754_single_builtin_t x_builtin, tme_uint32_t *x_ieee754)
{
  tme_int32_t exponent;
  tme_uint32_t chunk;
  tme_ieee754_single_builtin_t x_builtin_buffer;
  const tme_ieee754_single_builtin_t pzero_builtin = +0.0;

  /* x must not be a NaN or an infinity: */
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#endif

  /* get the mantissa and exponent of x: */
  x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
    tme_float_radix2_mantissa_exponent_float
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
    tme_float_radix2_mantissa_exponent_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
    tme_float_radix2_mantissa_exponent_long_double
#endif
    (x_builtin, &exponent);

  /* zero the IEEE 754 version: */
  memset((char *) x_ieee754, 0, sizeof((*x_ieee754)));

  /* if x is positive or negative zero: */
  if (x_builtin == 0
      || -x_builtin == 0) {

    /* set x's sign bit if x is not positive zero: */
    memcpy((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin));
    x_builtin_buffer = x_builtin;
    if (x_builtin < 0
        || memcmp((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)) != 0) {
      (*x_ieee754) |= (((tme_uint32_t) 0x7f800000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000)));
    }

    /* return the zero: */
    return (x_ieee754);
  }

  /* set x's sign bit: */
  if (x_builtin < 0) {
    (*x_ieee754) |= (((tme_uint32_t) 0x7f800000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000)));
    x_builtin = -x_builtin;
  }

  /* bias the exponent: */
  exponent += ((((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000))) >> 1);

  /* if the biased exponent is greater than or equal to the biased
     maximum, we must represent x as an infinity: */
  if (exponent >= (tme_int32_t) (((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000)))) {

    /* we do this by just setting the biased exponent to the biased
       maximum: */
    exponent = (((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000)));
  }

  /* otherwise, x will be either a normalized number, a denormalized
     number, or possibly a zero: */
  else {

    /* if the biased exponent is less than or equal to the biased
       minimum, x will be a denormalized number (possibly so
       denormalized that it becomes a zero): */
    if (exponent <= 0) {

      /* scale x into a denormalized number: */
      assert (x_builtin >= 1);
      x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
	tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
	tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
	tme_float_radix2_scale_long_double
#endif
	(x_builtin, exponent - 1);
      assert (x_builtin < 1);
      exponent = 0;
    }

    /* convert the mantissa, one 16-bit chunk at a time: */
    /* remove any implicit integer bit: */
    if (x_builtin >= 1) {
      x_builtin -= 1;
    }
    x_builtin = x_builtin * ((0x007f0000 / _TME_FIELD_MASK_FACTOR(0x007f0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754), 0x007f0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754), 0x0000ffff, chunk);
  }

  /* set x's biased exponent: */
  TME_FIELD_MASK_DEPOSITU((*x_ieee754), ((tme_uint32_t) 0x7f800000), exponent);

  /* done: */
  return (x_ieee754);
}

/* this does a NaN check for an IEEE 754 single precision monadic function: */
int
tme_ieee754_single_check_nan_monadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, struct tme_float *dst)
{
  const tme_uint32_t *nan0;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_single_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_SINGLE);
    nan0 = &src0->tme_float_value_ieee754_single;
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_single)
      (ieee754_ctl, nan0, nan0, &dst->tme_float_value_ieee754_single);
    return (TRUE);
  }

  return (FALSE);
}

/* this does a NaN check for an IEEE 754 single precision dyadic function: */
int
tme_ieee754_single_check_nan_dyadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  const tme_uint32_t *nan0;
  const tme_uint32_t *nan1;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_single_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_SINGLE);
    nan0 = &src0->tme_float_value_ieee754_single;
  }
  nan1 = nan0;
  if (tme_ieee754_single_is_nan(src1)) {
    assert (src1->tme_float_format == TME_FLOAT_FORMAT_IEEE754_SINGLE);
    nan1 = &src1->tme_float_value_ieee754_single;
    if (nan0 == NULL) {
      nan0 = nan1;
    }
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_single)
      (ieee754_ctl, nan0, nan1, &dst->tme_float_value_ieee754_single);
    return (TRUE);
  }

  return (FALSE);
}

/* this converts a tme_uint32_t to a single: */
void
tme_ieee754_single_from_int32(tme_uint32_t src, struct tme_float *dst)
{
  _tme_ieee754_single_value_set(dst, float32, int32_to_float32(src));
}

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a single: */
void
tme_ieee754_single_from_int64(tme_uint64_t src, struct tme_float *dst)
{
  _tme_ieee754_single_value_set(dst, float32, int64_to_float32(src));
}

#endif /* defined(TME_HAVE_INT64_T) */

/* this converts an in-range IEEE 754 single precision value into its
   radix 2 mantissa and exponent.  the mantissa is either zero, or
   in the range incl 1 to 2 excl: */
void
tme_ieee754_single_radix2_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent)
{
  tme_int32_t exponent;

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_single_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if this is an infinity: */
  if (tme_ieee754_single_is_inf(src)) {

    /* return a NaN: */
    _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
    _mantissa->tme_float_value_ieee754_single = ieee754_ctl->tme_ieee754_ctl_default_nan_single;
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* extract the unbiased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU(src->tme_float_value_ieee754_single, ((tme_uint32_t) 0x7f800000));
  exponent -= ((((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000))) >> 1);

  /* the mantissa is the source with a biased zero for the exponent: */
  *_mantissa = *src;
  TME_FIELD_MASK_DEPOSITU(_mantissa->tme_float_value_ieee754_single, ((tme_uint32_t) 0x7f800000), ((((tme_uint32_t) 0x7f800000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000))) >> 1));

  /* return the exponent: */
  if (_exponent != NULL) {
    _tme_ieee754_single_value_set(_exponent, float32, int32_to_float32(exponent));
  }
}

/* this scales an IEEE 754 single precision value by adding n to its
   radix 2 exponent: */
void
tme_ieee754_single_radix2_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  tme_uint32_t src_buffer;
  tme_int8_t rounding_mode;
  tme_int32_t _n;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) == 0)
  tme_int32_t exponent;
  tme_uint32_t exponent_bit, n;
  float32 * const value = (float32 *) &dst->tme_float_value_ieee754_single;
  struct tme_float constant_buffer;
  const float32 * const constant = (float32 *) &constant_buffer.tme_float_value_ieee754_single;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_single_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
    return;
  }

  /* if the exponent is an infinity: */
  if (tme_ieee754_single_is_inf(src1)) {

    /* return a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
    dst->tme_float_value_ieee754_single = ieee754_ctl->tme_ieee754_ctl_default_nan_single;
    return;
  }

  /* if the operand is a zero or an infinity: */
  if (tme_ieee754_single_is_zero(src1)
      || tme_ieee754_single_is_inf(src1)) {

    /* return the operand unchanged: */
    *dst = *src0;
    return;
  }

  /* truncate the exponent to an integer, using the round-to-zero mode: */
  rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
  _n = float32_to_int32(*((const float32 *) tme_ieee754_single_value_get(src1, &src_buffer)));
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;

  /* if a builtin type matches the IEEE 754 single format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_single_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix2_scale_float(tme_ieee754_single_value_builtin_get(src0), _n));
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_single_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix2_scale_double(tme_ieee754_single_value_builtin_get(src0), _n));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_single_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix2_scale_long_double(tme_ieee754_single_value_builtin_get(src0), _n));
#else

  /* start this value: */
  tme_ieee754_single_value_set(dst, *tme_ieee754_single_value_get(src0, &src_buffer));

  /* start with the most significant exponent bit: */
  exponent_bit = TME_ARRAY_ELS(tme_ieee754_single_constant_2e2ex) - 1;
  exponent = (1 << exponent_bit);
  tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_2e2ex[exponent_bit]);

  /* if n is negative: */
  if (_n < 0) {

    for (n = 0 - _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float32_div(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_2e2ex[exponent_bit]);
      }
    }
  }

  /* otherwise, n is positive: */
  else {
    for (n = _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float32_mul(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_2e2ex[exponent_bit]);
      }
    }
  }
#endif
}

/* this converts an in-range IEEE 754 single precision value into its
   radix 10 mantissa and exponent.  the mantissa is either zero, or
   in the range incl 1 to 10 excl: */
void
tme_ieee754_single_radix10_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent)
{
  tme_int32_t exponent;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) == 0)
  tme_uint32_t value_ieee754_buffer;
  struct tme_float value_buffer;
  struct tme_float zero_buffer;
  struct tme_float one_buffer;
  struct tme_float constant_buffer;
  struct tme_float radix_buffer;
  float32 * const value = (float32 *) &value_buffer.tme_float_value_ieee754_single;
  const float32 * const zero = (float32 *) &zero_buffer.tme_float_value_ieee754_single;
  const float32 * const one = (float32 *) &one_buffer.tme_float_value_ieee754_single;
  const float32 * const constant = (float32 *) &constant_buffer.tme_float_value_ieee754_single;
  const float32 * const radix = (float32 *) &radix_buffer.tme_float_value_ieee754_single;
  tme_uint32_t exponent_bit;
  int negate;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_single_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if this is an infinity: */
  if (tme_ieee754_single_is_inf(src)) {

    /* return a NaN: */
    _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
    _mantissa->tme_float_value_ieee754_single = ieee754_ctl->tme_ieee754_ctl_default_nan_single;
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if a builtin type matches the IEEE 754 single format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_single_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix10_mantissa_exponent_float(tme_ieee754_single_value_builtin_get(src), &exponent));
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_single_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix10_mantissa_exponent_double(tme_ieee754_single_value_builtin_get(src), &exponent));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_single_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix10_mantissa_exponent_long_double(tme_ieee754_single_value_builtin_get(src), &exponent));
#else

  /* get this value and some constants: */
  tme_ieee754_single_value_set(&value_buffer, *tme_ieee754_single_value_get(src, &value_ieee754_buffer));
  tme_ieee754_single_value_set_constant(&zero_buffer, &tme_ieee754_single_constant_zero);
  tme_ieee754_single_value_set_constant(&one_buffer, &tme_ieee754_single_constant_one);
  tme_ieee754_single_value_set_constant(&radix_buffer, &tme_ieee754_single_constant_10e2ex[0]);

  /* take the magnitude of the value, but remember if it was negative: */
  negate = float32_lt(*value, *zero);
  if (negate) {
    *value = float32_sub(*zero, *value);
  }

  /* start with an exponent of zero: */
  exponent = 0;

  /* if the value is nonzero: */
  if (!float32_eq(*value, *zero)) {

    /* while the value is less than one: */
    exponent_bit = TME_ARRAY_ELS(tme_ieee754_single_constant_10e_minus_2ex) - 1;
    tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e_minus_2ex[exponent_bit]);
    for (; float32_lt(*value, *one); ) {

      /* if value is less than or equal to 10^-(2^exponent_bit),
         divide value by 10^-(2^exponent_bit), and subtract 2^exponent_bit
         from exponent: */
      if (float32_le(*value, *constant)
          || exponent_bit == 0) {
        *value = float32_div(*value, *constant);
        exponent -= (1 << exponent_bit);
      }

      /* otherwise, move to the next exponent bit: */
      else {
        exponent_bit--;
        tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e_minus_2ex[exponent_bit]);
      }
    }

    /* while the value is greater than 10: */
    exponent_bit = TME_ARRAY_ELS(tme_ieee754_single_constant_10e2ex) - 1;
    tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e2ex[exponent_bit]);
    for (; !(float32_le(*value, *radix)) ; ) {

      /* if value is greater than or equal to 10^(2^exponent_bit),
         divide value by 10^(2^exponent_bit), and add 2^exponent_bit
         to exponent: */
      if (!(float32_lt(*value, *constant))
          || exponent_bit == 0) {
        *value = float32_div(*value, *constant);
        exponent += (1 << exponent_bit);
      }

      /* otherwise, move to the next exponent bit: */
      else {
        exponent_bit--;
        tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e2ex[exponent_bit]);
      }
    }

    /* if the value was originally negative, negate the mantissa: */
    if (negate) {
      *value = float32_sub(*zero, *value);
    }

    /* return the mantissa: */
    _tme_ieee754_single_value_set(_mantissa, float32, *value);
  }
#endif

  /* return the exponent: */
  if (_exponent != NULL) {
    _tme_ieee754_single_value_set(_exponent, float32, int32_to_float32(exponent));
  }
}

/* this scales an IEEE 754 single precision value by adding n to its
   radix 10 exponent: */
void
tme_ieee754_single_radix10_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  tme_uint32_t src_buffer;
  tme_int8_t rounding_mode;
  tme_int32_t _n;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) == 0)
  tme_int32_t exponent;
  tme_uint32_t exponent_bit, n;
  float32 * const value = (float32 *) &dst->tme_float_value_ieee754_single;
  struct tme_float constant_buffer;
  const float32 * const constant = (float32 *) &constant_buffer.tme_float_value_ieee754_single;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_single_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
    return;
  }

  /* if the exponent is an infinity: */
  if (tme_ieee754_single_is_inf(src1)) {

    /* return a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE;
    dst->tme_float_value_ieee754_single = ieee754_ctl->tme_ieee754_ctl_default_nan_single;
    return;
  }

  /* if the operand is a zero or an infinity: */
  if (tme_ieee754_single_is_zero(src1)
      || tme_ieee754_single_is_inf(src1)) {

    /* return the operand unchanged: */
    *dst = *src0;
    return;
  }

  /* truncate the exponent to an integer, using the round-to-zero mode: */
  rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
  _n = float32_to_int32(*((const float32 *) tme_ieee754_single_value_get(src1, &src_buffer)));
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;

  /* if a builtin type matches the IEEE 754 single format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_single_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix10_scale_float(tme_ieee754_single_value_builtin_get(src0), _n));
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_single_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix10_scale_double(tme_ieee754_single_value_builtin_get(src0), _n));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_single_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix10_scale_long_double(tme_ieee754_single_value_builtin_get(src0), _n));
#else

  /* start this value: */
  tme_ieee754_single_value_set(dst, *tme_ieee754_single_value_get(src0, &src_buffer));

  /* start with the most significant exponent bit: */
  exponent_bit = TME_ARRAY_ELS(tme_ieee754_single_constant_10e2ex) - 1;
  exponent = (1 << exponent_bit);
  tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e2ex[exponent_bit]);

  /* if n is negative: */
  if (_n < 0) {

    for (n = 0 - _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float32_div(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e2ex[exponent_bit]);
      }
    }
  }

  /* otherwise, n is positive: */
  else {
    for (n = _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float32_mul(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_single_value_set_constant(&constant_buffer, &tme_ieee754_single_constant_10e2ex[exponent_bit]);
      }
    }
  }
#endif
}

/* this converts a value from IEEE 754 double precision format
   to the builtin C type that is the best match for that format: */
tme_ieee754_double_builtin_t
tme_ieee754_double_value_to_builtin(const union tme_value64 *x_ieee754)
{
  tme_ieee754_double_builtin_t x_builtin;
  tme_uint32_t exponent;
  tme_uint32_t sign;
  tme_uint32_t chunk;
  tme_uint32_t fracor;

  /* get x's biased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_value64_uint32_hi, ((tme_uint32_t) 0x7ff00000));

  /* convert the fraction one 16-bit chunk at a time, and track
     a bitwise-or of all of the fraction bits: */
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_value64_uint32_hi, 0x000f0000);
  fracor = chunk;
  /* if the exponent is nonzero, add the implicit integer bit: */
  if (exponent != 0) chunk |= ((0x000f0000 / _TME_FIELD_MASK_FACTOR(0x000f0000)) + 1);
  x_builtin = chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_value64_uint32_hi, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_value64_uint32_lo, 0xffff0000);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_value64_uint32_lo, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;

  /* get x's sign bit: */
  sign = ((*x_ieee754).tme_value64_uint32_hi & (((tme_uint32_t) 0x7ff00000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000))));

  /* if the exponent is the biased maximum, x is either an infinity or a NaN: */
  if (exponent == (((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000)))) {

    /* if the fraction is nonzero, x is a NaN.  x must not be a NaN,
       because we were supposed to catch this earlier: */
    assert (fracor == 0);

    /* x is an infinity.  construct a builtin infinity: */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_infinity_float
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_infinity_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_infinity_long_double
#endif
      (sign);
  }

  /* if the exponent is the biased minimum and the fraction is
     all-bits-zero, x is a zero: */
  else if (exponent == 0
	   && fracor == 0) {

    /* construct a builtin zero: */
    x_builtin =
      (sign ?
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
       tme_float_negative_zero_float()
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
       tme_float_negative_zero_double()
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
       tme_float_negative_zero_long_double()
#endif
       : 0.0);
  }

  /* otherwise, x is an in-range value that needs to be converted: */
  else {

    /* scale the result by the unbiased exponent, adjusted by the
       number of fraction bits (which are currently to the left of the
       floating point in x_builtin): */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_radix2_scale_long_double
#endif
      (x_builtin, (exponent - ((((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000))) >> 1)) - 52);

    if (sign) {
      x_builtin = 0 - x_builtin;
    }
  }

  /* done: */
  return (x_builtin);
}

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 double precision format, to that
   format: */
const union tme_value64 *
tme_ieee754_double_value_from_builtin(tme_ieee754_double_builtin_t x_builtin, union tme_value64 *x_ieee754)
{
  tme_int32_t exponent;
  tme_uint32_t chunk;
  tme_ieee754_double_builtin_t x_builtin_buffer;
  const tme_ieee754_double_builtin_t pzero_builtin = +0.0;

  /* x must not be a NaN or an infinity: */
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#endif

  /* get the mantissa and exponent of x: */
  x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
    tme_float_radix2_mantissa_exponent_float
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
    tme_float_radix2_mantissa_exponent_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
    tme_float_radix2_mantissa_exponent_long_double
#endif
    (x_builtin, &exponent);

  /* zero the IEEE 754 version: */
  memset((char *) x_ieee754, 0, sizeof((*x_ieee754)));

  /* if x is positive or negative zero: */
  if (x_builtin == 0
      || -x_builtin == 0) {

    /* set x's sign bit if x is not positive zero: */
    memcpy((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin));
    x_builtin_buffer = x_builtin;
    if (x_builtin < 0
        || memcmp((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)) != 0) {
      (*x_ieee754).tme_value64_uint32_hi |= (((tme_uint32_t) 0x7ff00000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000)));
    }

    /* return the zero: */
    return (x_ieee754);
  }

  /* set x's sign bit: */
  if (x_builtin < 0) {
    (*x_ieee754).tme_value64_uint32_hi |= (((tme_uint32_t) 0x7ff00000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000)));
    x_builtin = -x_builtin;
  }

  /* bias the exponent: */
  exponent += ((((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000))) >> 1);

  /* if the biased exponent is greater than or equal to the biased
     maximum, we must represent x as an infinity: */
  if (exponent >= (tme_int32_t) (((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000)))) {

    /* we do this by just setting the biased exponent to the biased
       maximum: */
    exponent = (((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000)));
  }

  /* otherwise, x will be either a normalized number, a denormalized
     number, or possibly a zero: */
  else {

    /* if the biased exponent is less than or equal to the biased
       minimum, x will be a denormalized number (possibly so
       denormalized that it becomes a zero): */
    if (exponent <= 0) {

      /* scale x into a denormalized number: */
      assert (x_builtin >= 1);
      x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
	tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
	tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
	tme_float_radix2_scale_long_double
#endif
	(x_builtin, exponent - 1);
      assert (x_builtin < 1);
      exponent = 0;
    }

    /* convert the mantissa, one 16-bit chunk at a time: */
    /* remove any implicit integer bit: */
    if (x_builtin >= 1) {
      x_builtin -= 1;
    }
    x_builtin = x_builtin * ((0x000f0000 / _TME_FIELD_MASK_FACTOR(0x000f0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_value64_uint32_hi, 0x000f0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_value64_uint32_hi, 0x0000ffff, chunk);
    x_builtin = x_builtin * ((0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_value64_uint32_lo, 0xffff0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_value64_uint32_lo, 0x0000ffff, chunk);
  }

  /* set x's biased exponent: */
  TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_value64_uint32_hi, ((tme_uint32_t) 0x7ff00000), exponent);

  /* done: */
  return (x_ieee754);
}

/* this does a NaN check for an IEEE 754 double precision monadic function: */
int
tme_ieee754_double_check_nan_monadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, struct tme_float *dst)
{
  const union tme_value64 *nan0;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_double_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_DOUBLE);
    nan0 = &src0->tme_float_value_ieee754_double;
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_double)
      (ieee754_ctl, nan0, nan0, &dst->tme_float_value_ieee754_double);
    return (TRUE);
  }

  return (FALSE);
}

/* this does a NaN check for an IEEE 754 double precision dyadic function: */
int
tme_ieee754_double_check_nan_dyadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  const union tme_value64 *nan0;
  const union tme_value64 *nan1;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_double_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_DOUBLE);
    nan0 = &src0->tme_float_value_ieee754_double;
  }
  nan1 = nan0;
  if (tme_ieee754_double_is_nan(src1)) {
    assert (src1->tme_float_format == TME_FLOAT_FORMAT_IEEE754_DOUBLE);
    nan1 = &src1->tme_float_value_ieee754_double;
    if (nan0 == NULL) {
      nan0 = nan1;
    }
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_double)
      (ieee754_ctl, nan0, nan1, &dst->tme_float_value_ieee754_double);
    return (TRUE);
  }

  return (FALSE);
}

/* this converts a tme_uint32_t to a double: */
void
tme_ieee754_double_from_int32(tme_uint32_t src, struct tme_float *dst)
{
  _tme_ieee754_double_value_set(dst, float64, int32_to_float64(src));
}

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a double: */
void
tme_ieee754_double_from_int64(tme_uint64_t src, struct tme_float *dst)
{
  _tme_ieee754_double_value_set(dst, float64, int64_to_float64(src));
}

#endif /* defined(TME_HAVE_INT64_T) */

/* this converts an in-range IEEE 754 double precision value into its
   radix 2 mantissa and exponent.  the mantissa is either zero, or
   in the range incl 1 to 2 excl: */
void
tme_ieee754_double_radix2_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent)
{
  tme_int32_t exponent;

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_double_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if this is an infinity: */
  if (tme_ieee754_double_is_inf(src)) {

    /* return a NaN: */
    _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
    _mantissa->tme_float_value_ieee754_double = ieee754_ctl->tme_ieee754_ctl_default_nan_double;
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* extract the unbiased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU(src->tme_float_value_ieee754_double.tme_value64_uint32_hi, ((tme_uint32_t) 0x7ff00000));
  exponent -= ((((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000))) >> 1);

  /* the mantissa is the source with a biased zero for the exponent: */
  *_mantissa = *src;
  TME_FIELD_MASK_DEPOSITU(_mantissa->tme_float_value_ieee754_double.tme_value64_uint32_hi, ((tme_uint32_t) 0x7ff00000), ((((tme_uint32_t) 0x7ff00000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000))) >> 1));

  /* return the exponent: */
  if (_exponent != NULL) {
    _tme_ieee754_double_value_set(_exponent, float64, int32_to_float64(exponent));
  }
}

/* this scales an IEEE 754 double precision value by adding n to its
   radix 2 exponent: */
void
tme_ieee754_double_radix2_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  union tme_value64 src_buffer;
  tme_int8_t rounding_mode;
  tme_int32_t _n;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) == 0)
  tme_int32_t exponent;
  tme_uint32_t exponent_bit, n;
  float64 * const value = (float64 *) &dst->tme_float_value_ieee754_double;
  struct tme_float constant_buffer;
  const float64 * const constant = (float64 *) &constant_buffer.tme_float_value_ieee754_double;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_double_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
    return;
  }

  /* if the exponent is an infinity: */
  if (tme_ieee754_double_is_inf(src1)) {

    /* return a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
    dst->tme_float_value_ieee754_double = ieee754_ctl->tme_ieee754_ctl_default_nan_double;
    return;
  }

  /* if the operand is a zero or an infinity: */
  if (tme_ieee754_double_is_zero(src1)
      || tme_ieee754_double_is_inf(src1)) {

    /* return the operand unchanged: */
    *dst = *src0;
    return;
  }

  /* truncate the exponent to an integer, using the round-to-zero mode: */
  rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
  _n = float64_to_int32(*((const float64 *) tme_ieee754_double_value_get(src1, &src_buffer)));
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;

  /* if a builtin type matches the IEEE 754 double format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_double_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix2_scale_float(tme_ieee754_double_value_builtin_get(src0), _n));
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_double_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix2_scale_double(tme_ieee754_double_value_builtin_get(src0), _n));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_double_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix2_scale_long_double(tme_ieee754_double_value_builtin_get(src0), _n));
#else

  /* start this value: */
  tme_ieee754_double_value_set(dst, *tme_ieee754_double_value_get(src0, &src_buffer));

  /* start with the most significant exponent bit: */
  exponent_bit = TME_ARRAY_ELS(tme_ieee754_double_constant_2e2ex) - 1;
  exponent = (1 << exponent_bit);
  tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_2e2ex[exponent_bit]);

  /* if n is negative: */
  if (_n < 0) {

    for (n = 0 - _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float64_div(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_2e2ex[exponent_bit]);
      }
    }
  }

  /* otherwise, n is positive: */
  else {
    for (n = _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float64_mul(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_2e2ex[exponent_bit]);
      }
    }
  }
#endif
}

/* this converts an in-range IEEE 754 double precision value into its
   radix 10 mantissa and exponent.  the mantissa is either zero, or
   in the range incl 1 to 10 excl: */
void
tme_ieee754_double_radix10_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent)
{
  tme_int32_t exponent;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) == 0)
  union tme_value64 value_ieee754_buffer;
  struct tme_float value_buffer;
  struct tme_float zero_buffer;
  struct tme_float one_buffer;
  struct tme_float constant_buffer;
  struct tme_float radix_buffer;
  float64 * const value = (float64 *) &value_buffer.tme_float_value_ieee754_double;
  const float64 * const zero = (float64 *) &zero_buffer.tme_float_value_ieee754_double;
  const float64 * const one = (float64 *) &one_buffer.tme_float_value_ieee754_double;
  const float64 * const constant = (float64 *) &constant_buffer.tme_float_value_ieee754_double;
  const float64 * const radix = (float64 *) &radix_buffer.tme_float_value_ieee754_double;
  tme_uint32_t exponent_bit;
  int negate;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_double_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if this is an infinity: */
  if (tme_ieee754_double_is_inf(src)) {

    /* return a NaN: */
    _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
    _mantissa->tme_float_value_ieee754_double = ieee754_ctl->tme_ieee754_ctl_default_nan_double;
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if a builtin type matches the IEEE 754 double format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_double_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix10_mantissa_exponent_float(tme_ieee754_double_value_builtin_get(src), &exponent));
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_double_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix10_mantissa_exponent_double(tme_ieee754_double_value_builtin_get(src), &exponent));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_double_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix10_mantissa_exponent_long_double(tme_ieee754_double_value_builtin_get(src), &exponent));
#else

  /* get this value and some constants: */
  tme_ieee754_double_value_set(&value_buffer, *tme_ieee754_double_value_get(src, &value_ieee754_buffer));
  tme_ieee754_double_value_set_constant(&zero_buffer, &tme_ieee754_double_constant_zero);
  tme_ieee754_double_value_set_constant(&one_buffer, &tme_ieee754_double_constant_one);
  tme_ieee754_double_value_set_constant(&radix_buffer, &tme_ieee754_double_constant_10e2ex[0]);

  /* take the magnitude of the value, but remember if it was negative: */
  negate = float64_lt(*value, *zero);
  if (negate) {
    *value = float64_sub(*zero, *value);
  }

  /* start with an exponent of zero: */
  exponent = 0;

  /* if the value is nonzero: */
  if (!float64_eq(*value, *zero)) {

    /* while the value is less than one: */
    exponent_bit = TME_ARRAY_ELS(tme_ieee754_double_constant_10e_minus_2ex) - 1;
    tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e_minus_2ex[exponent_bit]);
    for (; float64_lt(*value, *one); ) {

      /* if value is less than or equal to 10^-(2^exponent_bit),
         divide value by 10^-(2^exponent_bit), and subtract 2^exponent_bit
         from exponent: */
      if (float64_le(*value, *constant)
          || exponent_bit == 0) {
        *value = float64_div(*value, *constant);
        exponent -= (1 << exponent_bit);
      }

      /* otherwise, move to the next exponent bit: */
      else {
        exponent_bit--;
        tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e_minus_2ex[exponent_bit]);
      }
    }

    /* while the value is greater than 10: */
    exponent_bit = TME_ARRAY_ELS(tme_ieee754_double_constant_10e2ex) - 1;
    tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e2ex[exponent_bit]);
    for (; !(float64_le(*value, *radix)) ; ) {

      /* if value is greater than or equal to 10^(2^exponent_bit),
         divide value by 10^(2^exponent_bit), and add 2^exponent_bit
         to exponent: */
      if (!(float64_lt(*value, *constant))
          || exponent_bit == 0) {
        *value = float64_div(*value, *constant);
        exponent += (1 << exponent_bit);
      }

      /* otherwise, move to the next exponent bit: */
      else {
        exponent_bit--;
        tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e2ex[exponent_bit]);
      }
    }

    /* if the value was originally negative, negate the mantissa: */
    if (negate) {
      *value = float64_sub(*zero, *value);
    }

    /* return the mantissa: */
    _tme_ieee754_double_value_set(_mantissa, float64, *value);
  }
#endif

  /* return the exponent: */
  if (_exponent != NULL) {
    _tme_ieee754_double_value_set(_exponent, float64, int32_to_float64(exponent));
  }
}

/* this scales an IEEE 754 double precision value by adding n to its
   radix 10 exponent: */
void
tme_ieee754_double_radix10_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  union tme_value64 src_buffer;
  tme_int8_t rounding_mode;
  tme_int32_t _n;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) == 0)
  tme_int32_t exponent;
  tme_uint32_t exponent_bit, n;
  float64 * const value = (float64 *) &dst->tme_float_value_ieee754_double;
  struct tme_float constant_buffer;
  const float64 * const constant = (float64 *) &constant_buffer.tme_float_value_ieee754_double;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_double_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
    return;
  }

  /* if the exponent is an infinity: */
  if (tme_ieee754_double_is_inf(src1)) {

    /* return a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
    dst->tme_float_value_ieee754_double = ieee754_ctl->tme_ieee754_ctl_default_nan_double;
    return;
  }

  /* if the operand is a zero or an infinity: */
  if (tme_ieee754_double_is_zero(src1)
      || tme_ieee754_double_is_inf(src1)) {

    /* return the operand unchanged: */
    *dst = *src0;
    return;
  }

  /* truncate the exponent to an integer, using the round-to-zero mode: */
  rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
  _n = float64_to_int32(*((const float64 *) tme_ieee754_double_value_get(src1, &src_buffer)));
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;

  /* if a builtin type matches the IEEE 754 double format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_double_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix10_scale_float(tme_ieee754_double_value_builtin_get(src0), _n));
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_double_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix10_scale_double(tme_ieee754_double_value_builtin_get(src0), _n));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_double_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix10_scale_long_double(tme_ieee754_double_value_builtin_get(src0), _n));
#else

  /* start this value: */
  tme_ieee754_double_value_set(dst, *tme_ieee754_double_value_get(src0, &src_buffer));

  /* start with the most significant exponent bit: */
  exponent_bit = TME_ARRAY_ELS(tme_ieee754_double_constant_10e2ex) - 1;
  exponent = (1 << exponent_bit);
  tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e2ex[exponent_bit]);

  /* if n is negative: */
  if (_n < 0) {

    for (n = 0 - _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float64_div(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e2ex[exponent_bit]);
      }
    }
  }

  /* otherwise, n is positive: */
  else {
    for (n = _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = float64_mul(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_double_value_set_constant(&constant_buffer, &tme_ieee754_double_constant_10e2ex[exponent_bit]);
      }
    }
  }
#endif
}

/* this converts a value from IEEE 754 extended80 precision format
   to the builtin C type that is the best match for that format: */
tme_ieee754_extended80_builtin_t
tme_ieee754_extended80_value_to_builtin(const struct tme_float_ieee754_extended80 *x_ieee754)
{
  tme_ieee754_extended80_builtin_t x_builtin;
  tme_uint32_t exponent;
  tme_uint32_t sign;
  tme_uint32_t chunk;
  tme_uint32_t fracor;

  /* get x's biased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_extended80_sexp, ((tme_uint32_t) 0x7fff));

  /* convert the fraction one 16-bit chunk at a time, and track
     a bitwise-or of all of the fraction bits: */
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_hi, 0xffff0000);
  fracor = chunk;
  /* if the exponent is the biased maximum, clear the explicit integer bit: */
  if (exponent == (((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff)))) fracor &= ~_TME_FIELD_MASK_MSBIT(0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000));
  x_builtin = chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_hi, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_lo, 0xffff0000);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_lo, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;

  /* get x's sign bit: */
  sign = ((*x_ieee754).tme_float_ieee754_extended80_sexp & (((tme_uint32_t) 0x7fff) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff))));

  /* if the exponent is the biased maximum, x is either an infinity or a NaN: */
  if (exponent == (((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff)))) {

    /* if the fraction is nonzero, x is a NaN.  x must not be a NaN,
       because we were supposed to catch this earlier: */
    assert (fracor == 0);

    /* x is an infinity.  construct a builtin infinity: */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_infinity_float
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_infinity_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_infinity_long_double
#endif
      (sign);
  }

  /* if the exponent is the biased minimum and the fraction is
     all-bits-zero, x is a zero: */
  else if (exponent == 0
	   && fracor == 0) {

    /* construct a builtin zero: */
    x_builtin =
      (sign ?
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
       tme_float_negative_zero_float()
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
       tme_float_negative_zero_double()
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
       tme_float_negative_zero_long_double()
#endif
       : 0.0);
  }

  /* otherwise, x is an in-range value that needs to be converted: */
  else {

    /* scale the result by the unbiased exponent, adjusted by the
       number of fraction bits (which are currently to the left of the
       floating point in x_builtin): */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_radix2_scale_long_double
#endif
      (x_builtin, (exponent - ((((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff))) >> 1)) - 63);

    if (sign) {
      x_builtin = 0 - x_builtin;
    }
  }

  /* done: */
  return (x_builtin);
}

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 extended80 precision format, to that
   format: */
const struct tme_float_ieee754_extended80 *
tme_ieee754_extended80_value_from_builtin(tme_ieee754_extended80_builtin_t x_builtin, struct tme_float_ieee754_extended80 *x_ieee754)
{
  tme_int32_t exponent;
  tme_uint32_t chunk;
  tme_ieee754_extended80_builtin_t x_builtin_buffer;
  const tme_ieee754_extended80_builtin_t pzero_builtin = +0.0;

  /* x must not be a NaN or an infinity: */
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#endif

  /* get the mantissa and exponent of x: */
  x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
    tme_float_radix2_mantissa_exponent_float
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
    tme_float_radix2_mantissa_exponent_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
    tme_float_radix2_mantissa_exponent_long_double
#endif
    (x_builtin, &exponent);

  /* zero the IEEE 754 version: */
  memset((char *) x_ieee754, 0, sizeof((*x_ieee754)));

  /* if x is positive or negative zero: */
  if (x_builtin == 0
      || -x_builtin == 0) {

    /* set x's sign bit if x is not positive zero: */
    memcpy((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin));
    x_builtin_buffer = x_builtin;
    if (x_builtin < 0
        || memcmp((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)) != 0) {
      (*x_ieee754).tme_float_ieee754_extended80_sexp |= (((tme_uint32_t) 0x7fff) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff)));
    }

    /* return the zero: */
    return (x_ieee754);
  }

  /* set x's sign bit: */
  if (x_builtin < 0) {
    (*x_ieee754).tme_float_ieee754_extended80_sexp |= (((tme_uint32_t) 0x7fff) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff)));
    x_builtin = -x_builtin;
  }

  /* bias the exponent: */
  exponent += ((((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff))) >> 1);

  /* if the biased exponent is greater than or equal to the biased
     maximum, we must represent x as an infinity: */
  if (exponent >= (tme_int32_t) (((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff)))) {

    /* we do this by just setting the biased exponent to the biased
       maximum: */
    exponent = (((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff)));
  }

  /* otherwise, x will be either a normalized number, a denormalized
     number, or possibly a zero: */
  else {

    /* if the biased exponent is less than or equal to the biased
       minimum, x will be a denormalized number (possibly so
       denormalized that it becomes a zero): */
    if (exponent <= 0) {

      /* scale x into a denormalized number: */
      assert (x_builtin >= 1);
      x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
	tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
	tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
	tme_float_radix2_scale_long_double
#endif
	(x_builtin, exponent - 1);
      assert (x_builtin < 1);
      exponent = 0;
    }

    /* convert the mantissa, one 16-bit chunk at a time: */
    x_builtin = x_builtin * (((0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000)) + 1) / 2);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_hi, 0xffff0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_hi, 0x0000ffff, chunk);
    x_builtin = x_builtin * ((0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_lo, 0xffff0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_extended80_significand.tme_value64_uint32_lo, 0x0000ffff, chunk);
  }

  /* set x's biased exponent: */
  TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_extended80_sexp, ((tme_uint32_t) 0x7fff), exponent);

  /* done: */
  return (x_ieee754);
}

/* this does a NaN check for an IEEE 754 extended80 precision monadic function: */
int
tme_ieee754_extended80_check_nan_monadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, struct tme_float *dst)
{
  const struct tme_float_ieee754_extended80 *nan0;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_extended80_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_EXTENDED80);
    nan0 = &src0->tme_float_value_ieee754_extended80;
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_extended80)
      (ieee754_ctl, nan0, nan0, &dst->tme_float_value_ieee754_extended80);
    return (TRUE);
  }

  return (FALSE);
}

/* this does a NaN check for an IEEE 754 extended80 precision dyadic function: */
int
tme_ieee754_extended80_check_nan_dyadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  const struct tme_float_ieee754_extended80 *nan0;
  const struct tme_float_ieee754_extended80 *nan1;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_extended80_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_EXTENDED80);
    nan0 = &src0->tme_float_value_ieee754_extended80;
  }
  nan1 = nan0;
  if (tme_ieee754_extended80_is_nan(src1)) {
    assert (src1->tme_float_format == TME_FLOAT_FORMAT_IEEE754_EXTENDED80);
    nan1 = &src1->tme_float_value_ieee754_extended80;
    if (nan0 == NULL) {
      nan0 = nan1;
    }
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_extended80)
      (ieee754_ctl, nan0, nan1, &dst->tme_float_value_ieee754_extended80);
    return (TRUE);
  }

  return (FALSE);
}

/* this converts a tme_uint32_t to a extended80: */
void
tme_ieee754_extended80_from_int32(tme_uint32_t src, struct tme_float *dst)
{
  _tme_ieee754_extended80_value_set(dst, floatx80, int32_to_floatx80(src));
}

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a extended80: */
void
tme_ieee754_extended80_from_int64(tme_uint64_t src, struct tme_float *dst)
{
  _tme_ieee754_extended80_value_set(dst, floatx80, int64_to_floatx80(src));
}

#endif /* defined(TME_HAVE_INT64_T) */

/* this converts an in-range IEEE 754 extended80 precision value into its
   radix 2 mantissa and exponent.  the mantissa is either zero, or
   in the range incl 1 to 2 excl: */
void
tme_ieee754_extended80_radix2_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent)
{
  tme_int32_t exponent;

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_extended80_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if this is an infinity: */
  if (tme_ieee754_extended80_is_inf(src)) {

    /* return a NaN: */
    _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80;
    _mantissa->tme_float_value_ieee754_extended80 = ieee754_ctl->tme_ieee754_ctl_default_nan_extended80;
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* extract the unbiased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU(src->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_sexp, ((tme_uint32_t) 0x7fff));
  exponent -= ((((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff))) >> 1);

  /* the mantissa is the source with a biased zero for the exponent: */
  *_mantissa = *src;
  TME_FIELD_MASK_DEPOSITU(_mantissa->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_sexp, ((tme_uint32_t) 0x7fff), ((((tme_uint32_t) 0x7fff) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff))) >> 1));

  /* return the exponent: */
  if (_exponent != NULL) {
    _tme_ieee754_extended80_value_set(_exponent, floatx80, int32_to_floatx80(exponent));
  }
}

/* this scales an IEEE 754 extended80 precision value by adding n to its
   radix 2 exponent: */
void
tme_ieee754_extended80_radix2_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  struct tme_float_ieee754_extended80 src_buffer;
  tme_int8_t rounding_mode;
  tme_int32_t _n;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) == 0)
  tme_int32_t exponent;
  tme_uint32_t exponent_bit, n;
  floatx80 * const value = (floatx80 *) &dst->tme_float_value_ieee754_extended80;
  struct tme_float constant_buffer;
  const floatx80 * const constant = (floatx80 *) &constant_buffer.tme_float_value_ieee754_extended80;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_extended80_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
    return;
  }

  /* if the exponent is an infinity: */
  if (tme_ieee754_extended80_is_inf(src1)) {

    /* return a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80;
    dst->tme_float_value_ieee754_extended80 = ieee754_ctl->tme_ieee754_ctl_default_nan_extended80;
    return;
  }

  /* if the operand is a zero or an infinity: */
  if (tme_ieee754_extended80_is_zero(src1)
      || tme_ieee754_extended80_is_inf(src1)) {

    /* return the operand unchanged: */
    *dst = *src0;
    return;
  }

  /* truncate the exponent to an integer, using the round-to-zero mode: */
  rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
  _n = floatx80_to_int32(*((const floatx80 *) tme_ieee754_extended80_value_get(src1, &src_buffer)));
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;

  /* if a builtin type matches the IEEE 754 extended80 format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_extended80_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix2_scale_float(tme_ieee754_extended80_value_builtin_get(src0), _n));
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_extended80_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix2_scale_double(tme_ieee754_extended80_value_builtin_get(src0), _n));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_extended80_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix2_scale_long_double(tme_ieee754_extended80_value_builtin_get(src0), _n));
#else

  /* start this value: */
  tme_ieee754_extended80_value_set(dst, *tme_ieee754_extended80_value_get(src0, &src_buffer));

  /* start with the most significant exponent bit: */
  exponent_bit = TME_ARRAY_ELS(tme_ieee754_extended80_constant_2e2ex) - 1;
  exponent = (1 << exponent_bit);
  tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_2e2ex[exponent_bit]);

  /* if n is negative: */
  if (_n < 0) {

    for (n = 0 - _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = floatx80_div(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_2e2ex[exponent_bit]);
      }
    }
  }

  /* otherwise, n is positive: */
  else {
    for (n = _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = floatx80_mul(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_2e2ex[exponent_bit]);
      }
    }
  }
#endif
}

/* this converts an in-range IEEE 754 extended80 precision value into its
   radix 10 mantissa and exponent.  the mantissa is either zero, or
   in the range incl 1 to 10 excl: */
void
tme_ieee754_extended80_radix10_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent)
{
  tme_int32_t exponent;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) == 0)
  struct tme_float_ieee754_extended80 value_ieee754_buffer;
  struct tme_float value_buffer;
  struct tme_float zero_buffer;
  struct tme_float one_buffer;
  struct tme_float constant_buffer;
  struct tme_float radix_buffer;
  floatx80 * const value = (floatx80 *) &value_buffer.tme_float_value_ieee754_extended80;
  const floatx80 * const zero = (floatx80 *) &zero_buffer.tme_float_value_ieee754_extended80;
  const floatx80 * const one = (floatx80 *) &one_buffer.tme_float_value_ieee754_extended80;
  const floatx80 * const constant = (floatx80 *) &constant_buffer.tme_float_value_ieee754_extended80;
  const floatx80 * const radix = (floatx80 *) &radix_buffer.tme_float_value_ieee754_extended80;
  tme_uint32_t exponent_bit;
  int negate;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_extended80_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if this is an infinity: */
  if (tme_ieee754_extended80_is_inf(src)) {

    /* return a NaN: */
    _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80;
    _mantissa->tme_float_value_ieee754_extended80 = ieee754_ctl->tme_ieee754_ctl_default_nan_extended80;
    if (_exponent != NULL) {
      *_exponent = *_mantissa;
    }
    return;
  }

  /* if a builtin type matches the IEEE 754 extended80 format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_extended80_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix10_mantissa_exponent_float(tme_ieee754_extended80_value_builtin_get(src), &exponent));
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_extended80_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix10_mantissa_exponent_double(tme_ieee754_extended80_value_builtin_get(src), &exponent));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_extended80_value_builtin_set
    (_mantissa,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix10_mantissa_exponent_long_double(tme_ieee754_extended80_value_builtin_get(src), &exponent));
#else

  /* get this value and some constants: */
  tme_ieee754_extended80_value_set(&value_buffer, *tme_ieee754_extended80_value_get(src, &value_ieee754_buffer));
  tme_ieee754_extended80_value_set_constant(&zero_buffer, &tme_ieee754_extended80_constant_zero);
  tme_ieee754_extended80_value_set_constant(&one_buffer, &tme_ieee754_extended80_constant_one);
  tme_ieee754_extended80_value_set_constant(&radix_buffer, &tme_ieee754_extended80_constant_10e2ex[0]);

  /* take the magnitude of the value, but remember if it was negative: */
  negate = floatx80_lt(*value, *zero);
  if (negate) {
    *value = floatx80_sub(*zero, *value);
  }

  /* start with an exponent of zero: */
  exponent = 0;

  /* if the value is nonzero: */
  if (!floatx80_eq(*value, *zero)) {

    /* while the value is less than one: */
    exponent_bit = TME_ARRAY_ELS(tme_ieee754_extended80_constant_10e_minus_2ex) - 1;
    tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e_minus_2ex[exponent_bit]);
    for (; floatx80_lt(*value, *one); ) {

      /* if value is less than or equal to 10^-(2^exponent_bit),
         divide value by 10^-(2^exponent_bit), and subtract 2^exponent_bit
         from exponent: */
      if (floatx80_le(*value, *constant)
          || exponent_bit == 0) {
        *value = floatx80_div(*value, *constant);
        exponent -= (1 << exponent_bit);
      }

      /* otherwise, move to the next exponent bit: */
      else {
        exponent_bit--;
        tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e_minus_2ex[exponent_bit]);
      }
    }

    /* while the value is greater than 10: */
    exponent_bit = TME_ARRAY_ELS(tme_ieee754_extended80_constant_10e2ex) - 1;
    tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e2ex[exponent_bit]);
    for (; !(floatx80_le(*value, *radix)) ; ) {

      /* if value is greater than or equal to 10^(2^exponent_bit),
         divide value by 10^(2^exponent_bit), and add 2^exponent_bit
         to exponent: */
      if (!(floatx80_lt(*value, *constant))
          || exponent_bit == 0) {
        *value = floatx80_div(*value, *constant);
        exponent += (1 << exponent_bit);
      }

      /* otherwise, move to the next exponent bit: */
      else {
        exponent_bit--;
        tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e2ex[exponent_bit]);
      }
    }

    /* if the value was originally negative, negate the mantissa: */
    if (negate) {
      *value = floatx80_sub(*zero, *value);
    }

    /* return the mantissa: */
    _tme_ieee754_extended80_value_set(_mantissa, floatx80, *value);
  }
#endif

  /* return the exponent: */
  if (_exponent != NULL) {
    _tme_ieee754_extended80_value_set(_exponent, floatx80, int32_to_floatx80(exponent));
  }
}

/* this scales an IEEE 754 extended80 precision value by adding n to its
   radix 10 exponent: */
void
tme_ieee754_extended80_radix10_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  struct tme_float_ieee754_extended80 src_buffer;
  tme_int8_t rounding_mode;
  tme_int32_t _n;
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) == 0)
  tme_int32_t exponent;
  tme_uint32_t exponent_bit, n;
  floatx80 * const value = (floatx80 *) &dst->tme_float_value_ieee754_extended80;
  struct tme_float constant_buffer;
  const floatx80 * const constant = (floatx80 *) &constant_buffer.tme_float_value_ieee754_extended80;
#endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) == 0) */

  /* check for a NaN operand: */
  if (__tme_predict_false(tme_ieee754_extended80_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
    return;
  }

  /* if the exponent is an infinity: */
  if (tme_ieee754_extended80_is_inf(src1)) {

    /* return a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80;
    dst->tme_float_value_ieee754_extended80 = ieee754_ctl->tme_ieee754_ctl_default_nan_extended80;
    return;
  }

  /* if the operand is a zero or an infinity: */
  if (tme_ieee754_extended80_is_zero(src1)
      || tme_ieee754_extended80_is_inf(src1)) {

    /* return the operand unchanged: */
    *dst = *src0;
    return;
  }

  /* truncate the exponent to an integer, using the round-to-zero mode: */
  rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
  _n = floatx80_to_int32(*((const floatx80 *) tme_ieee754_extended80_value_get(src1, &src_buffer)));
  ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;

  /* if a builtin type matches the IEEE 754 extended80 format exactly,
     use the corresponding mantissa-exponent function: */
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_FLOAT)
  tme_ieee754_extended80_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_FLOAT,
     tme_float_radix10_scale_float(tme_ieee754_extended80_value_builtin_get(src0), _n));
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_DOUBLE)
  tme_ieee754_extended80_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_DOUBLE,
     tme_float_radix10_scale_double(tme_ieee754_extended80_value_builtin_get(src0), _n));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80 == TME_FLOAT_FORMAT_LONG_DOUBLE))
  tme_ieee754_extended80_value_builtin_set
    (dst,
     TME_FLOAT_FORMAT_LONG_DOUBLE,
     tme_float_radix10_scale_long_double(tme_ieee754_extended80_value_builtin_get(src0), _n));
#else

  /* start this value: */
  tme_ieee754_extended80_value_set(dst, *tme_ieee754_extended80_value_get(src0, &src_buffer));

  /* start with the most significant exponent bit: */
  exponent_bit = TME_ARRAY_ELS(tme_ieee754_extended80_constant_10e2ex) - 1;
  exponent = (1 << exponent_bit);
  tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e2ex[exponent_bit]);

  /* if n is negative: */
  if (_n < 0) {

    for (n = 0 - _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = floatx80_div(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e2ex[exponent_bit]);
      }
    }
  }

  /* otherwise, n is positive: */
  else {
    for (n = _n; n > 0;) {
      if (n >= exponent || exponent == 1) {
        *value = floatx80_mul(*value, *constant);
        n -= exponent;
      }
      else {
        exponent >>= 1;
        exponent_bit--;
	tme_ieee754_extended80_value_set_constant(&constant_buffer, &tme_ieee754_extended80_constant_10e2ex[exponent_bit]);
      }
    }
  }
#endif
}

/* this converts a value from IEEE 754 quad precision format
   to the builtin C type that is the best match for that format: */
tme_ieee754_quad_builtin_t
tme_ieee754_quad_value_to_builtin(const struct tme_float_ieee754_quad *x_ieee754)
{
  tme_ieee754_quad_builtin_t x_builtin;
  tme_uint32_t exponent;
  tme_uint32_t sign;
  tme_uint32_t chunk;
  tme_uint32_t fracor;

  /* get x's biased exponent: */
  exponent = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi, ((tme_uint32_t) 0x7fff0000));

  /* convert the fraction one 16-bit chunk at a time, and track
     a bitwise-or of all of the fraction bits: */
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi, 0x0000ffff);
  fracor = chunk;
  /* if the exponent is nonzero, add the implicit integer bit: */
  if (exponent != 0) chunk |= ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
  x_builtin = chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_lo, 0xffff0000);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_lo, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_hi, 0xffff0000);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_hi, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_lo, 0xffff0000);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;
  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_lo, 0x0000ffff);
  fracor |= chunk;
  x_builtin = (x_builtin * 65536) + chunk;

  /* get x's sign bit: */
  sign = ((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi & (((tme_uint32_t) 0x7fff0000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000))));

  /* if the exponent is the biased maximum, x is either an infinity or a NaN: */
  if (exponent == (((tme_uint32_t) 0x7fff0000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000)))) {

    /* if the fraction is nonzero, x is a NaN.  x must not be a NaN,
       because we were supposed to catch this earlier: */
    assert (fracor == 0);

    /* x is an infinity.  construct a builtin infinity: */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_infinity_float
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_infinity_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_infinity_long_double
#endif
      (sign);
  }

  /* if the exponent is the biased minimum and the fraction is
     all-bits-zero, x is a zero: */
  else if (exponent == 0
	   && fracor == 0) {

    /* construct a builtin zero: */
    x_builtin =
      (sign ?
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
       tme_float_negative_zero_float()
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
       tme_float_negative_zero_double()
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
       tme_float_negative_zero_long_double()
#endif
       : 0.0);
  }

  /* otherwise, x is an in-range value that needs to be converted: */
  else {

    /* scale the result by the unbiased exponent, adjusted by the
       number of fraction bits (which are currently to the left of the
       floating point in x_builtin): */
    x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
      tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
      tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
      tme_float_radix2_scale_long_double
#endif
      (x_builtin, (exponent - ((((tme_uint32_t) 0x7fff0000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000))) >> 1)) - 112);

    if (sign) {
      x_builtin = 0 - x_builtin;
    }
  }

  /* done: */
  return (x_builtin);
}

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 quad precision format, to that
   format: */
const struct tme_float_ieee754_quad *
tme_ieee754_quad_value_from_builtin(tme_ieee754_quad_builtin_t x_builtin, struct tme_float_ieee754_quad *x_ieee754)
{
  tme_int32_t exponent;
  tme_uint32_t chunk;
  tme_ieee754_quad_builtin_t x_builtin_buffer;
  const tme_ieee754_quad_builtin_t pzero_builtin = +0.0;

  /* x must not be a NaN or an infinity: */
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
  assert (!isnan(x_builtin));
  assert (!isinf(x_builtin));
#endif

  /* get the mantissa and exponent of x: */
  x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
    tme_float_radix2_mantissa_exponent_float
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
    tme_float_radix2_mantissa_exponent_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
    tme_float_radix2_mantissa_exponent_long_double
#endif
    (x_builtin, &exponent);

  /* zero the IEEE 754 version: */
  memset((char *) x_ieee754, 0, sizeof((*x_ieee754)));

  /* if x is positive or negative zero: */
  if (x_builtin == 0
      || -x_builtin == 0) {

    /* set x's sign bit if x is not positive zero: */
    memcpy((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin));
    x_builtin_buffer = x_builtin;
    if (x_builtin < 0
        || memcmp((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)) != 0) {
      (*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi |= (((tme_uint32_t) 0x7fff0000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000)));
    }

    /* return the zero: */
    return (x_ieee754);
  }

  /* set x's sign bit: */
  if (x_builtin < 0) {
    (*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi |= (((tme_uint32_t) 0x7fff0000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000)));
    x_builtin = -x_builtin;
  }

  /* bias the exponent: */
  exponent += ((((tme_uint32_t) 0x7fff0000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000))) >> 1);

  /* if the biased exponent is greater than or equal to the biased
     maximum, we must represent x as an infinity: */
  if (exponent >= (tme_int32_t) (((tme_uint32_t) 0x7fff0000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000)))) {

    /* we do this by just setting the biased exponent to the biased
       maximum: */
    exponent = (((tme_uint32_t) 0x7fff0000) / _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000)));
  }

  /* otherwise, x will be either a normalized number, a denormalized
     number, or possibly a zero: */
  else {

    /* if the biased exponent is less than or equal to the biased
       minimum, x will be a denormalized number (possibly so
       denormalized that it becomes a zero): */
    if (exponent <= 0) {

      /* scale x into a denormalized number: */
      assert (x_builtin >= 1);
      x_builtin =
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
	tme_float_radix2_scale_float
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
	tme_float_radix2_scale_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
	tme_float_radix2_scale_long_double
#endif
	(x_builtin, exponent - 1);
      assert (x_builtin < 1);
      exponent = 0;
    }

    /* convert the mantissa, one 16-bit chunk at a time: */
    /* remove any implicit integer bit: */
    if (x_builtin >= 1) {
      x_builtin -= 1;
    }
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi, 0x0000ffff, chunk);
    x_builtin = x_builtin * ((0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_lo, 0xffff0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_lo, 0x0000ffff, chunk);
    x_builtin = x_builtin * ((0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_hi, 0xffff0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_hi, 0x0000ffff, chunk);
    x_builtin = x_builtin * ((0xffff0000 / _TME_FIELD_MASK_FACTOR(0xffff0000)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_lo, 0xffff0000, chunk);
    x_builtin = x_builtin * ((0x0000ffff / _TME_FIELD_MASK_FACTOR(0x0000ffff)) + 1);
    chunk = x_builtin;
    chunk -= (chunk > x_builtin);
    x_builtin -= chunk;
    TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_lo.tme_value64_uint32_lo, 0x0000ffff, chunk);
  }

  /* set x's biased exponent: */
  TME_FIELD_MASK_DEPOSITU((*x_ieee754).tme_float_ieee754_quad_hi.tme_value64_uint32_hi, ((tme_uint32_t) 0x7fff0000), exponent);

  /* done: */
  return (x_ieee754);
}

/* this does a NaN check for an IEEE 754 quad precision monadic function: */
int
tme_ieee754_quad_check_nan_monadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, struct tme_float *dst)
{
  const struct tme_float_ieee754_quad *nan0;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_quad_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_QUAD);
    nan0 = &src0->tme_float_value_ieee754_quad;
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_quad)
      (ieee754_ctl, nan0, nan0, &dst->tme_float_value_ieee754_quad);
    return (TRUE);
  }

  return (FALSE);
}

/* this does a NaN check for an IEEE 754 quad precision dyadic function: */
int
tme_ieee754_quad_check_nan_dyadic(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst)
{
  const struct tme_float_ieee754_quad *nan0;
  const struct tme_float_ieee754_quad *nan1;

  /* check for a NaN operand: */
  nan0 = NULL;
  if (tme_ieee754_quad_is_nan(src0)) {
    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_QUAD);
    nan0 = &src0->tme_float_value_ieee754_quad;
  }
  nan1 = nan0;
  if (tme_ieee754_quad_is_nan(src1)) {
    assert (src1->tme_float_format == TME_FLOAT_FORMAT_IEEE754_QUAD);
    nan1 = &src1->tme_float_value_ieee754_quad;
    if (nan0 == NULL) {
      nan0 = nan1;
    }
  }

  /* if we have a NaN operand: */
  if (__tme_predict_false(nan0 != NULL)) {

    /* propagate a NaN: */
    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD;
    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_quad)
      (ieee754_ctl, nan0, nan1, &dst->tme_float_value_ieee754_quad);
    return (TRUE);
  }

  return (FALSE);
}

/* this converts a tme_uint32_t to a quad: */
void
tme_ieee754_quad_from_int32(tme_uint32_t src, struct tme_float *dst)
{
  _tme_ieee754_quad_value_set(dst, float128, int32_to_float128(src));
}

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a quad: */
void
tme_ieee754_quad_from_int64(tme_uint64_t src, struct tme_float *dst)
{
  _tme_ieee754_quad_value_set(dst, float128, int64_to_float128(src));
}

#endif /* defined(TME_HAVE_INT64_T) */
