blob: 598b815cb081002ac70ca7e22cd3bda53a381e3d [file] [log] [blame]
Martin Storsjö5bddbd22019-12-07 00:06:07 +02001/*
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>
Martin Storsjöd13613a2019-12-07 23:44:02 +020013#include <float.h>
Martin Storsjö5bddbd22019-12-07 00:06:07 +020014
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)
Martin Storsjöd13613a2019-12-07 23:44:02 +0200103
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 */
Martin Storsjö6f4224d2019-12-08 00:18:16 +0200124
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))