/* 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 $");


/* decide which builtin C floating-point type is the best match for
   the IEEE 754 single precision format.  if a builtin type matches
   this format exactly, use that type, otherwise we assume that the
   smallest builtin type that is at least 4 bytes wide is the best
   match.  if no builtin type is at least that wide, we use long
   double, or double if long double is not available: */
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) != 0)
#define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_IEEE754_SINGLE
#elif (_TME_SIZEOF_FLOAT >= 4)
#define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_FLOAT
#elif (_TME_SIZEOF_DOUBLE >= 4 || !defined(_TME_HAVE_LONG_DOUBLE))
#define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_DOUBLE
#else
#define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
#endif

/* typedef the builtin C floating-point type that is the best match
   for the IEEE 754 single precision format: */
#if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
typedef float tme_ieee754_single_builtin_t;
#define tme_float_value_ieee754_single_builtin tme_float_value_float
#elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
typedef double tme_ieee754_single_builtin_t;
#define tme_float_value_ieee754_single_builtin tme_float_value_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
typedef long double tme_ieee754_single_builtin_t;
#define tme_float_value_ieee754_single_builtin tme_float_value_long_double
#endif

/* this asserts that the float is either in IEEE 754 single
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in IEEE 754 single
   precision format: */
#define tme_ieee754_single_is_format(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_SINGLE))

/* this asserts that the float is either in IEEE 754 single
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in the best-match builtin
   type format: */
#define tme_ieee754_single_is_format_builtin(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))

/* this asserts that the float is either in IEEE 754 single
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a NaN: */
#define tme_ieee754_single_is_nan(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
   && tme_float_is_nan(x, \
                       TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))

/* this asserts that the float is either in IEEE 754 single
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is an infinity: */
#define tme_ieee754_single_is_inf(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
   && tme_float_is_inf(x, \
                       TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))

/* this asserts that the float is either in IEEE 754 single
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a zero: */
#define tme_ieee754_single_is_zero(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
   && tme_float_is_zero(x, \
                        TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))

/* tme_ieee754_single_value_get(x, buffer) returns a pointer to
   the value of x in IEEE 754 single precision format (i.e., it
   returns a pointer to tme_uint32_t).  if x isn't already in this
   format, it is converted into that format in the given buffer: */
#define tme_ieee754_single_value_get(x, buffer) \
  (tme_ieee754_single_is_format(x) \
   ? &(x)->tme_float_value_ieee754_single \
   : tme_ieee754_single_value_from_builtin((x)->tme_float_value_ieee754_single_builtin, buffer))

/* tme_ieee754_single_value_set(x, y) sets the value of x to
   y, in IEEE 754 single precision format (i.e., y is a tme_uint32_t).
   (the internal function _tme_ieee754_single_value_set(x, t, y)
   takes the type of y, which must be compatible with tme_uint32_t): */
#define tme_ieee754_single_value_set(x, y) \
  do { \
    (x)->tme_float_value_ieee754_single = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
  } while (/* CONSTCOND */ 0)
#define _tme_ieee754_single_value_set(x, t, y) \
  do { \
    *((t *) &(x)->tme_float_value_ieee754_single) = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_single_value_set_constant(x, y) sets the value of
   x to the constant y (i.e., y is a const tme_uint32_t *): */
#define tme_ieee754_single_value_set_constant(x, y) \
  do { \
    (x)->tme_float_value_ieee754_single = *(y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_single_value_builtin_get(x) returns the value of
   x as the builtin C type that is the best match for the IEEE 754
   single precision format: */
#define tme_ieee754_single_value_builtin_get(x) \
  (tme_ieee754_single_is_format_builtin(x) \
   ? (x)->tme_float_value_ieee754_single_builtin \
   : tme_ieee754_single_value_to_builtin(&(x)->tme_float_value_ieee754_single))

/* tme_ieee754_single_value_builtin_set(x, format, y) sets the value of
   x to y, whose type is a builtin C type with format format.  if the value of
   y is a NaN or an infinity, y is stored in x in IEEE 754 single
   precision format, otherwise y is stored in x as the builtin C type
   that is the best match for the IEEE 754 single precision format: */
#define tme_ieee754_single_value_builtin_set(x, format, y) \
  do { \
    /* set the value: */ \
    tme_float_value_builtin_set(x, format, y); \
    \
    /* if the result is a NaN: */ \
    if (tme_float_is_nan(x, format)) { \
      \
      /* use the proper default IEEE 754 single precision NaN: */ \
      (x)->tme_float_value_ieee754_single = ieee754_ctl->tme_ieee754_ctl_default_nan_single; \
      (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
    } \
    \
    /* otherwise, if the result isn't already in IEEE 754 single precision format: */ \
    else if ((format) != TME_FLOAT_FORMAT_IEEE754_SINGLE) { \
      \
      /* if the result is infinite: */ \
      if (tme_float_is_inf(x, format)) { \
        \
	/* use the IEEE 754 single precision infinity: */ \
	(x)->tme_float_value_ieee754_single = ((tme_uint32_t) 0x7f800000) | (tme_float_is_negative(x, (format)) ? (((tme_uint32_t) 0x7f800000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7f800000))) : 0); \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
      } \
      \
      /* otherwise, if the result isn't already the builtin C type that \
         is the best match for the IEEE 754 single precision format: */ \
      else if ((format) != TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) { \
        \
	/* convert the result: */ \
	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
	  (x)->tme_float_value_ieee754_single_builtin = (x)->tme_float_value_float; \
	} \
        TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
	  (x)->tme_float_value_ieee754_single_builtin = (x)->tme_float_value_long_double; \
	}) \
	else { \
	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
	  (x)->tme_float_value_ieee754_single_builtin = (x)->tme_float_value_double; \
	} \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN; \
      } \
    } \
  } while (/* CONSTCOND */ 0)

/* this converts a value from IEEE 754 single precision format
   into the builtin C type that is the best match for that format: */
tme_ieee754_single_builtin_t tme_ieee754_single_value_to_builtin _TME_P((const tme_uint32_t *));

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 single precision format, into that
   format: */
const tme_uint32_t *tme_ieee754_single_value_from_builtin _TME_P((tme_ieee754_single_builtin_t, tme_uint32_t *));

/* this does a NaN check for an IEEE 754 single precision monadic function: */
int tme_ieee754_single_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));

/* this does a NaN check for an IEEE 754 single precision dyadic function: */
int tme_ieee754_single_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));

/* this converts a tme_uint32_t to a single: */
void tme_ieee754_single_from_int32 _TME_P((tme_uint32_t, struct tme_float *));

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a single: */
void tme_ieee754_single_from_int64 _TME_P((tme_uint64_t, struct tme_float *));

#endif /* defined(TME_HAVE_INT64_T) */

/* 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 _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));

/* this scales an IEEE 754 single precision value by adding n to its
   radix 10 exponent: */
void tme_ieee754_single_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));


/* decide which builtin C floating-point type is the best match for
   the IEEE 754 double precision format.  if a builtin type matches
   this format exactly, use that type, otherwise we assume that the
   smallest builtin type that is at least 8 bytes wide is the best
   match.  if no builtin type is at least that wide, we use long
   double, or double if long double is not available: */
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) != 0)
#define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_IEEE754_DOUBLE
#elif (_TME_SIZEOF_FLOAT >= 8)
#define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_FLOAT
#elif (_TME_SIZEOF_DOUBLE >= 8 || !defined(_TME_HAVE_LONG_DOUBLE))
#define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_DOUBLE
#else
#define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
#endif

/* typedef the builtin C floating-point type that is the best match
   for the IEEE 754 double precision format: */
#if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
typedef float tme_ieee754_double_builtin_t;
#define tme_float_value_ieee754_double_builtin tme_float_value_float
#elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
typedef double tme_ieee754_double_builtin_t;
#define tme_float_value_ieee754_double_builtin tme_float_value_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
typedef long double tme_ieee754_double_builtin_t;
#define tme_float_value_ieee754_double_builtin tme_float_value_long_double
#endif

/* this asserts that the float is either in IEEE 754 double
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in IEEE 754 double
   precision format: */
#define tme_ieee754_double_is_format(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_DOUBLE))

/* this asserts that the float is either in IEEE 754 double
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in the best-match builtin
   type format: */
#define tme_ieee754_double_is_format_builtin(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))

/* this asserts that the float is either in IEEE 754 double
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a NaN: */
#define tme_ieee754_double_is_nan(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
   && tme_float_is_nan(x, \
                       TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))

/* this asserts that the float is either in IEEE 754 double
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is an infinity: */
#define tme_ieee754_double_is_inf(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
   && tme_float_is_inf(x, \
                       TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))

/* this asserts that the float is either in IEEE 754 double
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a zero: */
#define tme_ieee754_double_is_zero(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
   && tme_float_is_zero(x, \
                        TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))

/* tme_ieee754_double_value_get(x, buffer) returns a pointer to
   the value of x in IEEE 754 double precision format (i.e., it
   returns a pointer to union tme_value64).  if x isn't already in this
   format, it is converted into that format in the given buffer: */
#define tme_ieee754_double_value_get(x, buffer) \
  (tme_ieee754_double_is_format(x) \
   ? &(x)->tme_float_value_ieee754_double \
   : tme_ieee754_double_value_from_builtin((x)->tme_float_value_ieee754_double_builtin, buffer))

/* tme_ieee754_double_value_set(x, y) sets the value of x to
   y, in IEEE 754 double precision format (i.e., y is a union tme_value64).
   (the internal function _tme_ieee754_double_value_set(x, t, y)
   takes the type of y, which must be compatible with union tme_value64): */
#define tme_ieee754_double_value_set(x, y) \
  do { \
    (x)->tme_float_value_ieee754_double = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
  } while (/* CONSTCOND */ 0)
#define _tme_ieee754_double_value_set(x, t, y) \
  do { \
    *((t *) &(x)->tme_float_value_ieee754_double) = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_double_value_set_constant(x, y) sets the value of
   x to the constant y (i.e., y is a const struct tme_ieee754_double_constant *): */
#define tme_ieee754_double_value_set_constant(x, y) \
  do { \
    (x)->tme_float_value_ieee754_double.tme_value64_uint32_hi = (y)->tme_ieee754_double_constant_hi; \
    (x)->tme_float_value_ieee754_double.tme_value64_uint32_lo = (y)->tme_ieee754_double_constant_lo; \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_double_value_builtin_get(x) returns the value of
   x as the builtin C type that is the best match for the IEEE 754
   double precision format: */
#define tme_ieee754_double_value_builtin_get(x) \
  (tme_ieee754_double_is_format_builtin(x) \
   ? (x)->tme_float_value_ieee754_double_builtin \
   : tme_ieee754_double_value_to_builtin(&(x)->tme_float_value_ieee754_double))

/* tme_ieee754_double_value_builtin_set(x, format, y) sets the value of
   x to y, whose type is a builtin C type with format format.  if the value of
   y is a NaN or an infinity, y is stored in x in IEEE 754 double
   precision format, otherwise y is stored in x as the builtin C type
   that is the best match for the IEEE 754 double precision format: */
#define tme_ieee754_double_value_builtin_set(x, format, y) \
  do { \
    /* set the value: */ \
    tme_float_value_builtin_set(x, format, y); \
    \
    /* if the result is a NaN: */ \
    if (tme_float_is_nan(x, format)) { \
      \
      /* use the proper default IEEE 754 double precision NaN: */ \
      (x)->tme_float_value_ieee754_double = ieee754_ctl->tme_ieee754_ctl_default_nan_double; \
      (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
    } \
    \
    /* otherwise, if the result isn't already in IEEE 754 double precision format: */ \
    else if ((format) != TME_FLOAT_FORMAT_IEEE754_DOUBLE) { \
      \
      /* if the result is infinite: */ \
      if (tme_float_is_inf(x, format)) { \
        \
	/* use the IEEE 754 double precision infinity: */ \
	(x)->tme_float_value_ieee754_double.tme_value64_uint32_hi = ((tme_uint32_t) 0x7ff00000) | (tme_float_is_negative(x, (format)) ? (((tme_uint32_t) 0x7ff00000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7ff00000))) : 0); \
	(x)->tme_float_value_ieee754_double.tme_value64_uint32_lo = 0; \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
      } \
      \
      /* otherwise, if the result isn't already the builtin C type that \
         is the best match for the IEEE 754 double precision format: */ \
      else if ((format) != TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) { \
        \
	/* convert the result: */ \
	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
	  (x)->tme_float_value_ieee754_double_builtin = (x)->tme_float_value_float; \
	} \
        TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
	  (x)->tme_float_value_ieee754_double_builtin = (x)->tme_float_value_long_double; \
	}) \
	else { \
	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
	  (x)->tme_float_value_ieee754_double_builtin = (x)->tme_float_value_double; \
	} \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN; \
      } \
    } \
  } while (/* CONSTCOND */ 0)

/* this converts a value from IEEE 754 double precision format
   into the builtin C type that is the best match for that format: */
tme_ieee754_double_builtin_t tme_ieee754_double_value_to_builtin _TME_P((const union tme_value64 *));

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 double precision format, into that
   format: */
const union tme_value64 *tme_ieee754_double_value_from_builtin _TME_P((tme_ieee754_double_builtin_t, union tme_value64 *));

/* this does a NaN check for an IEEE 754 double precision monadic function: */
int tme_ieee754_double_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));

/* this does a NaN check for an IEEE 754 double precision dyadic function: */
int tme_ieee754_double_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));

/* this converts a tme_uint32_t to a double: */
void tme_ieee754_double_from_int32 _TME_P((tme_uint32_t, struct tme_float *));

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a double: */
void tme_ieee754_double_from_int64 _TME_P((tme_uint64_t, struct tme_float *));

#endif /* defined(TME_HAVE_INT64_T) */

/* 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 _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));

/* this scales an IEEE 754 double precision value by adding n to its
   radix 10 exponent: */
void tme_ieee754_double_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));


/* decide which builtin C floating-point type is the best match for
   the IEEE 754 extended80 precision format.  if a builtin type matches
   this format exactly, use that type, otherwise we assume that the
   smallest builtin type that is at least 12 bytes wide is the best
   match.  if no builtin type is at least that wide, we use long
   double, or double if long double is not available: */
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) != 0)
#define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_IEEE754_EXTENDED80
#elif (_TME_SIZEOF_FLOAT >= 12)
#define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_FLOAT
#elif (_TME_SIZEOF_DOUBLE >= 12 || !defined(_TME_HAVE_LONG_DOUBLE))
#define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_DOUBLE
#else
#define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
#endif

/* typedef the builtin C floating-point type that is the best match
   for the IEEE 754 extended80 precision format: */
#if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
typedef float tme_ieee754_extended80_builtin_t;
#define tme_float_value_ieee754_extended80_builtin tme_float_value_float
#elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
typedef double tme_ieee754_extended80_builtin_t;
#define tme_float_value_ieee754_extended80_builtin tme_float_value_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
typedef long double tme_ieee754_extended80_builtin_t;
#define tme_float_value_ieee754_extended80_builtin tme_float_value_long_double
#endif

/* this asserts that the float is either in IEEE 754 extended80
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in IEEE 754 extended80
   precision format: */
#define tme_ieee754_extended80_is_format(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_EXTENDED80))

/* this asserts that the float is either in IEEE 754 extended80
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in the best-match builtin
   type format: */
#define tme_ieee754_extended80_is_format_builtin(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))

/* this asserts that the float is either in IEEE 754 extended80
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a NaN: */
#define tme_ieee754_extended80_is_nan(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
   && tme_float_is_nan(x, \
                       TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))

/* this asserts that the float is either in IEEE 754 extended80
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is an infinity: */
#define tme_ieee754_extended80_is_inf(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
   && tme_float_is_inf(x, \
                       TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))

/* this asserts that the float is either in IEEE 754 extended80
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a zero: */
#define tme_ieee754_extended80_is_zero(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
   && tme_float_is_zero(x, \
                        TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))

/* tme_ieee754_extended80_value_get(x, buffer) returns a pointer to
   the value of x in IEEE 754 extended80 precision format (i.e., it
   returns a pointer to struct tme_float_ieee754_extended80).  if x isn't already in this
   format, it is converted into that format in the given buffer: */
#define tme_ieee754_extended80_value_get(x, buffer) \
  (tme_ieee754_extended80_is_format(x) \
   ? &(x)->tme_float_value_ieee754_extended80 \
   : tme_ieee754_extended80_value_from_builtin((x)->tme_float_value_ieee754_extended80_builtin, buffer))

/* tme_ieee754_extended80_value_set(x, y) sets the value of x to
   y, in IEEE 754 extended80 precision format (i.e., y is a struct tme_float_ieee754_extended80).
   (the internal function _tme_ieee754_extended80_value_set(x, t, y)
   takes the type of y, which must be compatible with struct tme_float_ieee754_extended80): */
#define tme_ieee754_extended80_value_set(x, y) \
  do { \
    (x)->tme_float_value_ieee754_extended80 = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
  } while (/* CONSTCOND */ 0)
#define _tme_ieee754_extended80_value_set(x, t, y) \
  do { \
    *((t *) &(x)->tme_float_value_ieee754_extended80) = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_extended80_value_set_constant(x, y) sets the value of
   x to the constant y (i.e., y is a const struct tme_ieee754_extended80_constant *): */
#define tme_ieee754_extended80_value_set_constant(x, y) \
  do { \
    (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_sexp = (y)->tme_ieee754_extended80_constant_sexp; \
    (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = (y)->tme_ieee754_extended80_constant_significand_hi; \
    (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = (y)->tme_ieee754_extended80_constant_significand_lo; \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_extended80_value_builtin_get(x) returns the value of
   x as the builtin C type that is the best match for the IEEE 754
   extended80 precision format: */
#define tme_ieee754_extended80_value_builtin_get(x) \
  (tme_ieee754_extended80_is_format_builtin(x) \
   ? (x)->tme_float_value_ieee754_extended80_builtin \
   : tme_ieee754_extended80_value_to_builtin(&(x)->tme_float_value_ieee754_extended80))

/* tme_ieee754_extended80_value_builtin_set(x, format, y) sets the value of
   x to y, whose type is a builtin C type with format format.  if the value of
   y is a NaN or an infinity, y is stored in x in IEEE 754 extended80
   precision format, otherwise y is stored in x as the builtin C type
   that is the best match for the IEEE 754 extended80 precision format: */
#define tme_ieee754_extended80_value_builtin_set(x, format, y) \
  do { \
    /* set the value: */ \
    tme_float_value_builtin_set(x, format, y); \
    \
    /* if the result is a NaN: */ \
    if (tme_float_is_nan(x, format)) { \
      \
      /* use the proper default IEEE 754 extended80 precision NaN: */ \
      (x)->tme_float_value_ieee754_extended80 = ieee754_ctl->tme_ieee754_ctl_default_nan_extended80; \
      (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
    } \
    \
    /* otherwise, if the result isn't already in IEEE 754 extended80 precision format: */ \
    else if ((format) != TME_FLOAT_FORMAT_IEEE754_EXTENDED80) { \
      \
      /* if the result is infinite: */ \
      if (tme_float_is_inf(x, format)) { \
        \
	/* use the IEEE 754 extended80 precision infinity: */ \
	(x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_sexp = ((tme_uint32_t) 0x7fff) | (tme_float_is_negative(x, (format)) ? (((tme_uint32_t) 0x7fff) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff))) : 0); \
	(x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = 0; \
	(x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = 0; \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
      } \
      \
      /* otherwise, if the result isn't already the builtin C type that \
         is the best match for the IEEE 754 extended80 precision format: */ \
      else if ((format) != TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) { \
        \
	/* convert the result: */ \
	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
	  (x)->tme_float_value_ieee754_extended80_builtin = (x)->tme_float_value_float; \
	} \
        TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
	  (x)->tme_float_value_ieee754_extended80_builtin = (x)->tme_float_value_long_double; \
	}) \
	else { \
	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
	  (x)->tme_float_value_ieee754_extended80_builtin = (x)->tme_float_value_double; \
	} \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN; \
      } \
    } \
  } while (/* CONSTCOND */ 0)

/* this converts a value from IEEE 754 extended80 precision format
   into the builtin C type that is the best match for that format: */
tme_ieee754_extended80_builtin_t tme_ieee754_extended80_value_to_builtin _TME_P((const struct tme_float_ieee754_extended80 *));

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 extended80 precision format, into that
   format: */
const struct tme_float_ieee754_extended80 *tme_ieee754_extended80_value_from_builtin _TME_P((tme_ieee754_extended80_builtin_t, struct tme_float_ieee754_extended80 *));

/* this does a NaN check for an IEEE 754 extended80 precision monadic function: */
int tme_ieee754_extended80_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));

/* this does a NaN check for an IEEE 754 extended80 precision dyadic function: */
int tme_ieee754_extended80_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));

/* this converts a tme_uint32_t to a extended80: */
void tme_ieee754_extended80_from_int32 _TME_P((tme_uint32_t, struct tme_float *));

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a extended80: */
void tme_ieee754_extended80_from_int64 _TME_P((tme_uint64_t, struct tme_float *));

#endif /* defined(TME_HAVE_INT64_T) */

/* 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 _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));

/* this scales an IEEE 754 extended80 precision value by adding n to its
   radix 10 exponent: */
void tme_ieee754_extended80_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));


/* decide which builtin C floating-point type is the best match for
   the IEEE 754 quad precision format.  if a builtin type matches
   this format exactly, use that type, otherwise we assume that the
   smallest builtin type that is at least 16 bytes wide is the best
   match.  if no builtin type is at least that wide, we use long
   double, or double if long double is not available: */
#if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_QUAD) != 0)
#define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_IEEE754_QUAD
#elif (_TME_SIZEOF_FLOAT >= 16)
#define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_FLOAT
#elif (_TME_SIZEOF_DOUBLE >= 16 || !defined(_TME_HAVE_LONG_DOUBLE))
#define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_DOUBLE
#else
#define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
#endif

/* typedef the builtin C floating-point type that is the best match
   for the IEEE 754 quad precision format: */
#if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
typedef float tme_ieee754_quad_builtin_t;
#define tme_float_value_ieee754_quad_builtin tme_float_value_float
#elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
typedef double tme_ieee754_quad_builtin_t;
#define tme_float_value_ieee754_quad_builtin tme_float_value_double
#elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
typedef long double tme_ieee754_quad_builtin_t;
#define tme_float_value_ieee754_quad_builtin tme_float_value_long_double
#endif

/* this asserts that the float is either in IEEE 754 quad
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in IEEE 754 quad
   precision format: */
#define tme_ieee754_quad_is_format(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_QUAD))

/* this asserts that the float is either in IEEE 754 quad
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is in the best-match builtin
   type format: */
#define tme_ieee754_quad_is_format_builtin(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
   && tme_float_is_format(x, \
                          TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN, \
		          TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))

/* this asserts that the float is either in IEEE 754 quad
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a NaN: */
#define tme_ieee754_quad_is_nan(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
   && tme_float_is_nan(x, \
                       TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))

/* this asserts that the float is either in IEEE 754 quad
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is an infinity: */
#define tme_ieee754_quad_is_inf(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
   && tme_float_is_inf(x, \
                       TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))

/* this asserts that the float is either in IEEE 754 quad
   precision format, or in the best-match builtin type format.  it
   evaluates to nonzero if the float is a zero: */
#define tme_ieee754_quad_is_zero(x) \
  (tme_float_assert_formats(x, \
                            TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
   && tme_float_is_zero(x, \
                        TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))

/* tme_ieee754_quad_value_get(x, buffer) returns a pointer to
   the value of x in IEEE 754 quad precision format (i.e., it
   returns a pointer to struct tme_float_ieee754_quad).  if x isn't already in this
   format, it is converted into that format in the given buffer: */
#define tme_ieee754_quad_value_get(x, buffer) \
  (tme_ieee754_quad_is_format(x) \
   ? &(x)->tme_float_value_ieee754_quad \
   : tme_ieee754_quad_value_from_builtin((x)->tme_float_value_ieee754_quad_builtin, buffer))

/* tme_ieee754_quad_value_set(x, y) sets the value of x to
   y, in IEEE 754 quad precision format (i.e., y is a struct tme_float_ieee754_quad).
   (the internal function _tme_ieee754_quad_value_set(x, t, y)
   takes the type of y, which must be compatible with struct tme_float_ieee754_quad): */
#define tme_ieee754_quad_value_set(x, y) \
  do { \
    (x)->tme_float_value_ieee754_quad = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
  } while (/* CONSTCOND */ 0)
#define _tme_ieee754_quad_value_set(x, t, y) \
  do { \
    *((t *) &(x)->tme_float_value_ieee754_quad) = (y); \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_quad_value_set_constant(x, y) sets the value of
   x to the constant y (i.e., y is a const struct tme_ieee754_quad_constant *): */
#define tme_ieee754_quad_value_set_constant(x, y) \
  do { \
    (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_hi = (y)->tme_ieee754_quad_constant_hi_hi; \
    (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = (y)->tme_ieee754_quad_constant_hi_lo; \
    (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = (y)->tme_ieee754_quad_constant_lo_hi; \
    (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = (y)->tme_ieee754_quad_constant_lo_lo; \
    (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
  } while (/* CONSTCOND */ 0)

/* tme_ieee754_quad_value_builtin_get(x) returns the value of
   x as the builtin C type that is the best match for the IEEE 754
   quad precision format: */
#define tme_ieee754_quad_value_builtin_get(x) \
  (tme_ieee754_quad_is_format_builtin(x) \
   ? (x)->tme_float_value_ieee754_quad_builtin \
   : tme_ieee754_quad_value_to_builtin(&(x)->tme_float_value_ieee754_quad))

/* tme_ieee754_quad_value_builtin_set(x, format, y) sets the value of
   x to y, whose type is a builtin C type with format format.  if the value of
   y is a NaN or an infinity, y is stored in x in IEEE 754 quad
   precision format, otherwise y is stored in x as the builtin C type
   that is the best match for the IEEE 754 quad precision format: */
#define tme_ieee754_quad_value_builtin_set(x, format, y) \
  do { \
    /* set the value: */ \
    tme_float_value_builtin_set(x, format, y); \
    \
    /* if the result is a NaN: */ \
    if (tme_float_is_nan(x, format)) { \
      \
      /* use the proper default IEEE 754 quad precision NaN: */ \
      (x)->tme_float_value_ieee754_quad = ieee754_ctl->tme_ieee754_ctl_default_nan_quad; \
      (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
    } \
    \
    /* otherwise, if the result isn't already in IEEE 754 quad precision format: */ \
    else if ((format) != TME_FLOAT_FORMAT_IEEE754_QUAD) { \
      \
      /* if the result is infinite: */ \
      if (tme_float_is_inf(x, format)) { \
        \
	/* use the IEEE 754 quad precision infinity: */ \
	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_hi = ((tme_uint32_t) 0x7fff0000) | (tme_float_is_negative(x, (format)) ? (((tme_uint32_t) 0x7fff0000) + _TME_FIELD_MASK_FACTOR(((tme_uint32_t) 0x7fff0000))) : 0); \
	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = 0; \
	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = 0; \
	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = 0; \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
      } \
      \
      /* otherwise, if the result isn't already the builtin C type that \
         is the best match for the IEEE 754 quad precision format: */ \
      else if ((format) != TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) { \
        \
	/* convert the result: */ \
	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
	  (x)->tme_float_value_ieee754_quad_builtin = (x)->tme_float_value_float; \
	} \
        TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
	  (x)->tme_float_value_ieee754_quad_builtin = (x)->tme_float_value_long_double; \
	}) \
	else { \
	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
	  (x)->tme_float_value_ieee754_quad_builtin = (x)->tme_float_value_double; \
	} \
        (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN; \
      } \
    } \
  } while (/* CONSTCOND */ 0)

/* this converts a value from IEEE 754 quad precision format
   into the builtin C type that is the best match for that format: */
tme_ieee754_quad_builtin_t tme_ieee754_quad_value_to_builtin _TME_P((const struct tme_float_ieee754_quad *));

/* this converts a value from the builtin C type that is the best
   match for the IEEE 754 quad precision format, into that
   format: */
const struct tme_float_ieee754_quad *tme_ieee754_quad_value_from_builtin _TME_P((tme_ieee754_quad_builtin_t, struct tme_float_ieee754_quad *));

/* this does a NaN check for an IEEE 754 quad precision monadic function: */
int tme_ieee754_quad_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));

/* this does a NaN check for an IEEE 754 quad precision dyadic function: */
int tme_ieee754_quad_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));

/* this converts a tme_uint32_t to a quad: */
void tme_ieee754_quad_from_int32 _TME_P((tme_uint32_t, struct tme_float *));

#if defined(TME_HAVE_INT64_T)

/* this converts a tme_uint64_t to a quad: */
void tme_ieee754_quad_from_int64 _TME_P((tme_uint64_t, struct tme_float *));

#endif /* defined(TME_HAVE_INT64_T) */

/* this converts an in-range IEEE 754 quad 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_quad_radix10_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));

/* this scales an IEEE 754 quad precision value by adding n to its
   radix 10 exponent: */
void tme_ieee754_quad_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));

