master
  1/*
  2* ====================================================
  3* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  4*
  5* Developed at SunPro, a Sun Microsystems, Inc. business.
  6* Permission to use, copy, modify, and distribute this
  7* software is freely granted, provided that this notice
  8* is preserved.
  9* ====================================================
 10*/
 11
 12#include <inttypes.h>
 13#include <float.h>
 14
 15typedef unsigned int u_int32_t;
 16
 17typedef union
 18{
 19    double value;
 20    struct
 21    {
 22        u_int32_t lsw;
 23        u_int32_t msw;
 24    } parts;
 25} ieee_double_shape_type;
 26
 27typedef union {
 28    float value;
 29    u_int32_t word;
 30} ieee_float_shape_type;
 31
 32/* Get two 32 bit ints from a double.  */
 33
 34#define EXTRACT_WORDS(ix0,ix1,d)    \
 35do {                                \
 36    ieee_double_shape_type ew_u;    \
 37    ew_u.value = (d);               \
 38    (ix0) = ew_u.parts.msw;         \
 39    (ix1) = ew_u.parts.lsw;         \
 40} while (0)
 41
 42/* Get the most significant 32 bit int from a double.  */
 43
 44#define GET_HIGH_WORD(i,d)          \
 45do {                                \
 46    ieee_double_shape_type gh_u;    \
 47    gh_u.value = (d);               \
 48    (i) = gh_u.parts.msw;           \
 49} while (0)
 50
 51/* Get the less significant 32 bit int from a double.  */
 52
 53#define GET_LOW_WORD(i,d)           \
 54do {                                \
 55    ieee_double_shape_type gl_u;    \
 56    gl_u.value = (d);               \
 57    (i) = gl_u.parts.lsw;           \
 58} while (0)
 59
 60/* Set a double from two 32 bit ints.  */
 61
 62#define INSERT_WORDS(d,ix0,ix1)     \
 63do {                                \
 64    ieee_double_shape_type iw_u;    \
 65    iw_u.parts.msw = (ix0);         \
 66    iw_u.parts.lsw = (ix1);         \
 67    (d) = iw_u.value;               \
 68} while (0)
 69
 70/* Set the more significant 32 bits of a double from an int.  */
 71
 72#define SET_HIGH_WORD(d,v)          \
 73do {                                \
 74    ieee_double_shape_type sh_u;    \
 75    sh_u.value = (d);               \
 76    sh_u.parts.msw = (v);           \
 77    (d) = sh_u.value;               \
 78} while (0)
 79
 80/* Set the less significant 32 bits of a double from an int.  */
 81
 82#define SET_LOW_WORD(d,v)           \
 83do {                                \
 84    ieee_double_shape_type sl_u;    \
 85    sl_u.value = (d);               \
 86    sl_u.parts.lsw = (v);           \
 87    (d) = sl_u.value;               \
 88} while (0)
 89
 90#define GET_FLOAT_WORD(i,d) do \
 91{ \
 92    ieee_float_shape_type gf_u; \
 93    gf_u.value = (d); \
 94    (i) = gf_u.word; \
 95} while(0)
 96
 97#define SET_FLOAT_WORD(d,i) do \
 98{ \
 99    ieee_float_shape_type gf_u; \
100    gf_u.word = (i); \
101    (d) = gf_u.value; \
102} while(0)
103
104
105#ifdef FLT_EVAL_METHOD
106/*
107 * Attempt to get strict C99 semantics for assignment with non-C99 compilers.
108 */
109#if FLT_EVAL_METHOD == 0 || __GNUC__ == 0
110#define	STRICT_ASSIGN(type, lval, rval)	((lval) = (rval))
111#else
112#define	STRICT_ASSIGN(type, lval, rval) do {	\
113	volatile type __lval;			\
114						\
115	if (sizeof(type) >= sizeof(long double))	\
116		(lval) = (rval);		\
117	else {					\
118		__lval = (rval);		\
119		(lval) = __lval;		\
120	}					\
121} while (0)
122#endif
123#endif /* FLT_EVAL_METHOD */
124
125/*
126 * Mix 0, 1 or 2 NaNs.  First add 0 to each arg.  This normally just turns
127 * signaling NaNs into quiet NaNs by setting a quiet bit.  We do this
128 * because we want to never return a signaling NaN, and also because we
129 * don't want the quiet bit to affect the result.  Then mix the converted
130 * args using the specified operation.
131 *
132 * When one arg is NaN, the result is typically that arg quieted.  When both
133 * args are NaNs, the result is typically the quietening of the arg whose
134 * mantissa is largest after quietening.  When neither arg is NaN, the
135 * result may be NaN because it is indeterminate, or finite for subsequent
136 * construction of a NaN as the indeterminate 0.0L/0.0L.
137 *
138 * Technical complications: the result in bits after rounding to the final
139 * precision might depend on the runtime precision and/or on compiler
140 * optimizations, especially when different register sets are used for
141 * different precisions.  Try to make the result not depend on at least the
142 * runtime precision by always doing the main mixing step in long double
143 * precision.  Try to reduce dependencies on optimizations by adding the
144 * the 0's in different precisions (unless everything is in long double
145 * precision).
146 */
147#define nan_mix(x, y)		(nan_mix_op((x), (y), +))
148#define nan_mix_op(x, y, op)	(((x) + 0.0L) op ((y) + 0))