mirror of
https://github.com/phabrics/Run-Sun3-SunOS-4.1.1.git
synced 2026-04-29 11:02:59 -04:00
825 lines
42 KiB
C
825 lines
42 KiB
C
/* 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 (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 [1,10): */
|
|
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 (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 [1,10): */
|
|
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 (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 [1,10): */
|
|
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 (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 [1,10): */
|
|
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 *));
|
|
|