1 /* automatically generated by ieee754-misc-auto.sh, do not edit! */
2 #include <tme/common.h>
3 _TME_RCSID("$Id: ieee754-misc-auto.sh,v 1.6 2007/08/24 01:05:43 fredette Exp $");
4 
5 
6 /* decide which builtin C floating-point type is the best match for
7    the IEEE 754 single precision format.  if a builtin type matches
8    this format exactly, use that type, otherwise we assume that the
9    smallest builtin type that is at least 4 bytes wide is the best
10    match.  if no builtin type is at least that wide, we use long
11    double, or double if long double is not available: */
12 #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_SINGLE) != 0)
13 #define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_IEEE754_SINGLE
14 #elif (_TME_SIZEOF_FLOAT >= 4)
15 #define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_FLOAT
16 #elif (_TME_SIZEOF_DOUBLE >= 4 || !defined(_TME_HAVE_LONG_DOUBLE))
17 #define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_DOUBLE
18 #else
19 #define TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
20 #endif
21 
22 /* typedef the builtin C floating-point type that is the best match
23    for the IEEE 754 single precision format: */
24 #if (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
25 typedef float tme_ieee754_single_builtin_t;
26 #define tme_float_value_ieee754_single_builtin tme_float_value_float
27 #elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
28 typedef double tme_ieee754_single_builtin_t;
29 #define tme_float_value_ieee754_single_builtin tme_float_value_double
30 #elif (TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)
31 typedef long double tme_ieee754_single_builtin_t;
32 #define tme_float_value_ieee754_single_builtin tme_float_value_long_double
33 #endif
34 
35 /* this asserts that the float is either in IEEE 754 single
36    precision format, or in the best-match builtin type format.  it
37    evaluates to nonzero if the float is in IEEE 754 single
38    precision format: */
39 #define tme_ieee754_single_is_format(x) \
40   (tme_float_assert_formats(x, \
41                             TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
42    && tme_float_is_format(x, \
43                           TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN, \
44 		          TME_FLOAT_FORMAT_IEEE754_SINGLE))
45 
46 /* this asserts that the float is either in IEEE 754 single
47    precision format, or in the best-match builtin type format.  it
48    evaluates to nonzero if the float is in the best-match builtin
49    type format: */
50 #define tme_ieee754_single_is_format_builtin(x) \
51   (tme_float_assert_formats(x, \
52                             TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
53    && tme_float_is_format(x, \
54                           TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN, \
55 		          TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
56 
57 /* this asserts that the float is either in IEEE 754 single
58    precision format, or in the best-match builtin type format.  it
59    evaluates to nonzero if the float is a NaN: */
60 #define tme_ieee754_single_is_nan(x) \
61   (tme_float_assert_formats(x, \
62                             TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
63    && tme_float_is_nan(x, \
64                        TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
65 
66 /* this asserts that the float is either in IEEE 754 single
67    precision format, or in the best-match builtin type format.  it
68    evaluates to nonzero if the float is an infinity: */
69 #define tme_ieee754_single_is_inf(x) \
70   (tme_float_assert_formats(x, \
71                             TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
72    && tme_float_is_inf(x, \
73                        TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
74 
75 /* this asserts that the float is either in IEEE 754 single
76    precision format, or in the best-match builtin type format.  it
77    evaluates to nonzero if the float is a zero: */
78 #define tme_ieee754_single_is_zero(x) \
79   (tme_float_assert_formats(x, \
80                             TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) \
81    && tme_float_is_zero(x, \
82                         TME_FLOAT_FORMAT_IEEE754_SINGLE | TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN))
83 
84 /* tme_ieee754_single_value_get(x, buffer) returns a pointer to
85    the value of x in IEEE 754 single precision format (i.e., it
86    returns a pointer to tme_uint32_t).  if x isn't already in this
87    format, it is converted into that format in the given buffer: */
88 #define tme_ieee754_single_value_get(x, buffer) \
89   (tme_ieee754_single_is_format(x) \
90    ? &(x)->tme_float_value_ieee754_single \
91    : tme_ieee754_single_value_from_builtin((x)->tme_float_value_ieee754_single_builtin, buffer))
92 
93 /* tme_ieee754_single_value_set(x, y) sets the value of x to
94    y, in IEEE 754 single precision format (i.e., y is a tme_uint32_t).
95    (the internal function _tme_ieee754_single_value_set(x, t, y)
96    takes the type of y, which must be compatible with tme_uint32_t): */
97 #define tme_ieee754_single_value_set(x, y) \
98   do { \
99     (x)->tme_float_value_ieee754_single = (y); \
100     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
101   } while (/* CONSTCOND */ 0)
102 #define _tme_ieee754_single_value_set(x, t, y) \
103   do { \
104     *((t *) &(x)->tme_float_value_ieee754_single) = (y); \
105     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
106   } while (/* CONSTCOND */ 0)
107 
108 /* tme_ieee754_single_value_set_constant(x, y) sets the value of
109    x to the constant y (i.e., y is a const tme_uint32_t *): */
110 #define tme_ieee754_single_value_set_constant(x, y) \
111   do { \
112     (x)->tme_float_value_ieee754_single = *(y); \
113     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
114   } while (/* CONSTCOND */ 0)
115 
116 /* tme_ieee754_single_value_builtin_get(x) returns the value of
117    x as the builtin C type that is the best match for the IEEE 754
118    single precision format: */
119 #define tme_ieee754_single_value_builtin_get(x) \
120   (tme_ieee754_single_is_format_builtin(x) \
121    ? (x)->tme_float_value_ieee754_single_builtin \
122    : tme_ieee754_single_value_to_builtin(&(x)->tme_float_value_ieee754_single))
123 
124 /* tme_ieee754_single_value_builtin_set(x, format, y) sets the value of
125    x to y, whose type is a builtin C type with format format.  if the value of
126    y is a NaN or an infinity, y is stored in x in IEEE 754 single
127    precision format, otherwise y is stored in x as the builtin C type
128    that is the best match for the IEEE 754 single precision format: */
129 #define tme_ieee754_single_value_builtin_set(x, format, y) \
130   do { \
131     /* set the value: */ \
132     tme_float_value_builtin_set(x, format, y); \
133     \
134     /* if the result is a NaN: */ \
135     if (tme_float_is_nan(x, format)) { \
136       \
137       /* use the proper default IEEE 754 single precision NaN: */ \
138       (x)->tme_float_value_ieee754_single = ieee754_ctl->tme_ieee754_ctl_default_nan_single; \
139       (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
140     } \
141     \
142     /* otherwise, if the result isn't already in IEEE 754 single precision format: */ \
143     else if ((format) != TME_FLOAT_FORMAT_IEEE754_SINGLE) { \
144       \
145       /* if the result is infinite: */ \
146       if (tme_float_is_inf(x, format)) { \
147         \
148 	/* use the IEEE 754 single precision infinity: */ \
149 	(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); \
150         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE; \
151       } \
152       \
153       /* otherwise, if the result isn't already the builtin C type that \
154          is the best match for the IEEE 754 single precision format: */ \
155       else if ((format) != TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN) { \
156         \
157 	/* convert the result: */ \
158 	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
159 	  (x)->tme_float_value_ieee754_single_builtin = (x)->tme_float_value_float; \
160 	} \
161         TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
162 	  (x)->tme_float_value_ieee754_single_builtin = (x)->tme_float_value_long_double; \
163 	}) \
164 	else { \
165 	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
166 	  (x)->tme_float_value_ieee754_single_builtin = (x)->tme_float_value_double; \
167 	} \
168         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_SINGLE_BUILTIN; \
169       } \
170     } \
171   } while (/* CONSTCOND */ 0)
172 
173 /* this converts a value from IEEE 754 single precision format
174    into the builtin C type that is the best match for that format: */
175 tme_ieee754_single_builtin_t tme_ieee754_single_value_to_builtin _TME_P((const tme_uint32_t *));
176 
177 /* this converts a value from the builtin C type that is the best
178    match for the IEEE 754 single precision format, into that
179    format: */
180 const tme_uint32_t *tme_ieee754_single_value_from_builtin _TME_P((tme_ieee754_single_builtin_t, tme_uint32_t *));
181 
182 /* this does a NaN check for an IEEE 754 single precision monadic function: */
183 int tme_ieee754_single_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));
184 
185 /* this does a NaN check for an IEEE 754 single precision dyadic function: */
186 int tme_ieee754_single_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
187 
188 /* this converts a tme_uint32_t to a single: */
189 void tme_ieee754_single_from_int32 _TME_P((tme_uint32_t, struct tme_float *));
190 
191 #if defined(TME_HAVE_INT64_T)
192 
193 /* this converts a tme_uint64_t to a single: */
194 void tme_ieee754_single_from_int64 _TME_P((tme_uint64_t, struct tme_float *));
195 
196 #endif /* defined(TME_HAVE_INT64_T) */
197 
198 /* this converts an in-range IEEE 754 single precision value into its
199    radix 10 mantissa and exponent.  the mantissa is either zero, or
200    in the range [1,10): */
201 void tme_ieee754_single_radix10_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));
202 
203 /* this scales an IEEE 754 single precision value by adding n to its
204    radix 10 exponent: */
205 void tme_ieee754_single_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
206 
207 
208 /* decide which builtin C floating-point type is the best match for
209    the IEEE 754 double precision format.  if a builtin type matches
210    this format exactly, use that type, otherwise we assume that the
211    smallest builtin type that is at least 8 bytes wide is the best
212    match.  if no builtin type is at least that wide, we use long
213    double, or double if long double is not available: */
214 #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_DOUBLE) != 0)
215 #define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_IEEE754_DOUBLE
216 #elif (_TME_SIZEOF_FLOAT >= 8)
217 #define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_FLOAT
218 #elif (_TME_SIZEOF_DOUBLE >= 8 || !defined(_TME_HAVE_LONG_DOUBLE))
219 #define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_DOUBLE
220 #else
221 #define TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
222 #endif
223 
224 /* typedef the builtin C floating-point type that is the best match
225    for the IEEE 754 double precision format: */
226 #if (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
227 typedef float tme_ieee754_double_builtin_t;
228 #define tme_float_value_ieee754_double_builtin tme_float_value_float
229 #elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
230 typedef double tme_ieee754_double_builtin_t;
231 #define tme_float_value_ieee754_double_builtin tme_float_value_double
232 #elif (TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)
233 typedef long double tme_ieee754_double_builtin_t;
234 #define tme_float_value_ieee754_double_builtin tme_float_value_long_double
235 #endif
236 
237 /* this asserts that the float is either in IEEE 754 double
238    precision format, or in the best-match builtin type format.  it
239    evaluates to nonzero if the float is in IEEE 754 double
240    precision format: */
241 #define tme_ieee754_double_is_format(x) \
242   (tme_float_assert_formats(x, \
243                             TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
244    && tme_float_is_format(x, \
245                           TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN, \
246 		          TME_FLOAT_FORMAT_IEEE754_DOUBLE))
247 
248 /* this asserts that the float is either in IEEE 754 double
249    precision format, or in the best-match builtin type format.  it
250    evaluates to nonzero if the float is in the best-match builtin
251    type format: */
252 #define tme_ieee754_double_is_format_builtin(x) \
253   (tme_float_assert_formats(x, \
254                             TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
255    && tme_float_is_format(x, \
256                           TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN, \
257 		          TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
258 
259 /* this asserts that the float is either in IEEE 754 double
260    precision format, or in the best-match builtin type format.  it
261    evaluates to nonzero if the float is a NaN: */
262 #define tme_ieee754_double_is_nan(x) \
263   (tme_float_assert_formats(x, \
264                             TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
265    && tme_float_is_nan(x, \
266                        TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
267 
268 /* this asserts that the float is either in IEEE 754 double
269    precision format, or in the best-match builtin type format.  it
270    evaluates to nonzero if the float is an infinity: */
271 #define tme_ieee754_double_is_inf(x) \
272   (tme_float_assert_formats(x, \
273                             TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
274    && tme_float_is_inf(x, \
275                        TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
276 
277 /* this asserts that the float is either in IEEE 754 double
278    precision format, or in the best-match builtin type format.  it
279    evaluates to nonzero if the float is a zero: */
280 #define tme_ieee754_double_is_zero(x) \
281   (tme_float_assert_formats(x, \
282                             TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) \
283    && tme_float_is_zero(x, \
284                         TME_FLOAT_FORMAT_IEEE754_DOUBLE | TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN))
285 
286 /* tme_ieee754_double_value_get(x, buffer) returns a pointer to
287    the value of x in IEEE 754 double precision format (i.e., it
288    returns a pointer to union tme_value64).  if x isn't already in this
289    format, it is converted into that format in the given buffer: */
290 #define tme_ieee754_double_value_get(x, buffer) \
291   (tme_ieee754_double_is_format(x) \
292    ? &(x)->tme_float_value_ieee754_double \
293    : tme_ieee754_double_value_from_builtin((x)->tme_float_value_ieee754_double_builtin, buffer))
294 
295 /* tme_ieee754_double_value_set(x, y) sets the value of x to
296    y, in IEEE 754 double precision format (i.e., y is a union tme_value64).
297    (the internal function _tme_ieee754_double_value_set(x, t, y)
298    takes the type of y, which must be compatible with union tme_value64): */
299 #define tme_ieee754_double_value_set(x, y) \
300   do { \
301     (x)->tme_float_value_ieee754_double = (y); \
302     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
303   } while (/* CONSTCOND */ 0)
304 #define _tme_ieee754_double_value_set(x, t, y) \
305   do { \
306     *((t *) &(x)->tme_float_value_ieee754_double) = (y); \
307     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
308   } while (/* CONSTCOND */ 0)
309 
310 /* tme_ieee754_double_value_set_constant(x, y) sets the value of
311    x to the constant y (i.e., y is a const struct tme_ieee754_double_constant *): */
312 #define tme_ieee754_double_value_set_constant(x, y) \
313   do { \
314     (x)->tme_float_value_ieee754_double.tme_value64_uint32_hi = (y)->tme_ieee754_double_constant_hi; \
315     (x)->tme_float_value_ieee754_double.tme_value64_uint32_lo = (y)->tme_ieee754_double_constant_lo; \
316     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
317   } while (/* CONSTCOND */ 0)
318 
319 /* tme_ieee754_double_value_builtin_get(x) returns the value of
320    x as the builtin C type that is the best match for the IEEE 754
321    double precision format: */
322 #define tme_ieee754_double_value_builtin_get(x) \
323   (tme_ieee754_double_is_format_builtin(x) \
324    ? (x)->tme_float_value_ieee754_double_builtin \
325    : tme_ieee754_double_value_to_builtin(&(x)->tme_float_value_ieee754_double))
326 
327 /* tme_ieee754_double_value_builtin_set(x, format, y) sets the value of
328    x to y, whose type is a builtin C type with format format.  if the value of
329    y is a NaN or an infinity, y is stored in x in IEEE 754 double
330    precision format, otherwise y is stored in x as the builtin C type
331    that is the best match for the IEEE 754 double precision format: */
332 #define tme_ieee754_double_value_builtin_set(x, format, y) \
333   do { \
334     /* set the value: */ \
335     tme_float_value_builtin_set(x, format, y); \
336     \
337     /* if the result is a NaN: */ \
338     if (tme_float_is_nan(x, format)) { \
339       \
340       /* use the proper default IEEE 754 double precision NaN: */ \
341       (x)->tme_float_value_ieee754_double = ieee754_ctl->tme_ieee754_ctl_default_nan_double; \
342       (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
343     } \
344     \
345     /* otherwise, if the result isn't already in IEEE 754 double precision format: */ \
346     else if ((format) != TME_FLOAT_FORMAT_IEEE754_DOUBLE) { \
347       \
348       /* if the result is infinite: */ \
349       if (tme_float_is_inf(x, format)) { \
350         \
351 	/* use the IEEE 754 double precision infinity: */ \
352 	(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); \
353 	(x)->tme_float_value_ieee754_double.tme_value64_uint32_lo = 0; \
354         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE; \
355       } \
356       \
357       /* otherwise, if the result isn't already the builtin C type that \
358          is the best match for the IEEE 754 double precision format: */ \
359       else if ((format) != TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN) { \
360         \
361 	/* convert the result: */ \
362 	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
363 	  (x)->tme_float_value_ieee754_double_builtin = (x)->tme_float_value_float; \
364 	} \
365         TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
366 	  (x)->tme_float_value_ieee754_double_builtin = (x)->tme_float_value_long_double; \
367 	}) \
368 	else { \
369 	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
370 	  (x)->tme_float_value_ieee754_double_builtin = (x)->tme_float_value_double; \
371 	} \
372         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE_BUILTIN; \
373       } \
374     } \
375   } while (/* CONSTCOND */ 0)
376 
377 /* this converts a value from IEEE 754 double precision format
378    into the builtin C type that is the best match for that format: */
379 tme_ieee754_double_builtin_t tme_ieee754_double_value_to_builtin _TME_P((const union tme_value64 *));
380 
381 /* this converts a value from the builtin C type that is the best
382    match for the IEEE 754 double precision format, into that
383    format: */
384 const union tme_value64 *tme_ieee754_double_value_from_builtin _TME_P((tme_ieee754_double_builtin_t, union tme_value64 *));
385 
386 /* this does a NaN check for an IEEE 754 double precision monadic function: */
387 int tme_ieee754_double_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));
388 
389 /* this does a NaN check for an IEEE 754 double precision dyadic function: */
390 int tme_ieee754_double_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
391 
392 /* this converts a tme_uint32_t to a double: */
393 void tme_ieee754_double_from_int32 _TME_P((tme_uint32_t, struct tme_float *));
394 
395 #if defined(TME_HAVE_INT64_T)
396 
397 /* this converts a tme_uint64_t to a double: */
398 void tme_ieee754_double_from_int64 _TME_P((tme_uint64_t, struct tme_float *));
399 
400 #endif /* defined(TME_HAVE_INT64_T) */
401 
402 /* this converts an in-range IEEE 754 double precision value into its
403    radix 10 mantissa and exponent.  the mantissa is either zero, or
404    in the range [1,10): */
405 void tme_ieee754_double_radix10_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));
406 
407 /* this scales an IEEE 754 double precision value by adding n to its
408    radix 10 exponent: */
409 void tme_ieee754_double_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
410 
411 
412 /* decide which builtin C floating-point type is the best match for
413    the IEEE 754 extended80 precision format.  if a builtin type matches
414    this format exactly, use that type, otherwise we assume that the
415    smallest builtin type that is at least 12 bytes wide is the best
416    match.  if no builtin type is at least that wide, we use long
417    double, or double if long double is not available: */
418 #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_EXTENDED80) != 0)
419 #define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_IEEE754_EXTENDED80
420 #elif (_TME_SIZEOF_FLOAT >= 12)
421 #define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_FLOAT
422 #elif (_TME_SIZEOF_DOUBLE >= 12 || !defined(_TME_HAVE_LONG_DOUBLE))
423 #define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_DOUBLE
424 #else
425 #define TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
426 #endif
427 
428 /* typedef the builtin C floating-point type that is the best match
429    for the IEEE 754 extended80 precision format: */
430 #if (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
431 typedef float tme_ieee754_extended80_builtin_t;
432 #define tme_float_value_ieee754_extended80_builtin tme_float_value_float
433 #elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
434 typedef double tme_ieee754_extended80_builtin_t;
435 #define tme_float_value_ieee754_extended80_builtin tme_float_value_double
436 #elif (TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)
437 typedef long double tme_ieee754_extended80_builtin_t;
438 #define tme_float_value_ieee754_extended80_builtin tme_float_value_long_double
439 #endif
440 
441 /* this asserts that the float is either in IEEE 754 extended80
442    precision format, or in the best-match builtin type format.  it
443    evaluates to nonzero if the float is in IEEE 754 extended80
444    precision format: */
445 #define tme_ieee754_extended80_is_format(x) \
446   (tme_float_assert_formats(x, \
447                             TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
448    && tme_float_is_format(x, \
449                           TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN, \
450 		          TME_FLOAT_FORMAT_IEEE754_EXTENDED80))
451 
452 /* this asserts that the float is either in IEEE 754 extended80
453    precision format, or in the best-match builtin type format.  it
454    evaluates to nonzero if the float is in the best-match builtin
455    type format: */
456 #define tme_ieee754_extended80_is_format_builtin(x) \
457   (tme_float_assert_formats(x, \
458                             TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
459    && tme_float_is_format(x, \
460                           TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN, \
461 		          TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))
462 
463 /* this asserts that the float is either in IEEE 754 extended80
464    precision format, or in the best-match builtin type format.  it
465    evaluates to nonzero if the float is a NaN: */
466 #define tme_ieee754_extended80_is_nan(x) \
467   (tme_float_assert_formats(x, \
468                             TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
469    && tme_float_is_nan(x, \
470                        TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))
471 
472 /* this asserts that the float is either in IEEE 754 extended80
473    precision format, or in the best-match builtin type format.  it
474    evaluates to nonzero if the float is an infinity: */
475 #define tme_ieee754_extended80_is_inf(x) \
476   (tme_float_assert_formats(x, \
477                             TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
478    && tme_float_is_inf(x, \
479                        TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))
480 
481 /* this asserts that the float is either in IEEE 754 extended80
482    precision format, or in the best-match builtin type format.  it
483    evaluates to nonzero if the float is a zero: */
484 #define tme_ieee754_extended80_is_zero(x) \
485   (tme_float_assert_formats(x, \
486                             TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) \
487    && tme_float_is_zero(x, \
488                         TME_FLOAT_FORMAT_IEEE754_EXTENDED80 | TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN))
489 
490 /* tme_ieee754_extended80_value_get(x, buffer) returns a pointer to
491    the value of x in IEEE 754 extended80 precision format (i.e., it
492    returns a pointer to struct tme_float_ieee754_extended80).  if x isn't already in this
493    format, it is converted into that format in the given buffer: */
494 #define tme_ieee754_extended80_value_get(x, buffer) \
495   (tme_ieee754_extended80_is_format(x) \
496    ? &(x)->tme_float_value_ieee754_extended80 \
497    : tme_ieee754_extended80_value_from_builtin((x)->tme_float_value_ieee754_extended80_builtin, buffer))
498 
499 /* tme_ieee754_extended80_value_set(x, y) sets the value of x to
500    y, in IEEE 754 extended80 precision format (i.e., y is a struct tme_float_ieee754_extended80).
501    (the internal function _tme_ieee754_extended80_value_set(x, t, y)
502    takes the type of y, which must be compatible with struct tme_float_ieee754_extended80): */
503 #define tme_ieee754_extended80_value_set(x, y) \
504   do { \
505     (x)->tme_float_value_ieee754_extended80 = (y); \
506     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
507   } while (/* CONSTCOND */ 0)
508 #define _tme_ieee754_extended80_value_set(x, t, y) \
509   do { \
510     *((t *) &(x)->tme_float_value_ieee754_extended80) = (y); \
511     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
512   } while (/* CONSTCOND */ 0)
513 
514 /* tme_ieee754_extended80_value_set_constant(x, y) sets the value of
515    x to the constant y (i.e., y is a const struct tme_ieee754_extended80_constant *): */
516 #define tme_ieee754_extended80_value_set_constant(x, y) \
517   do { \
518     (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_sexp = (y)->tme_ieee754_extended80_constant_sexp; \
519     (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = (y)->tme_ieee754_extended80_constant_significand_hi; \
520     (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = (y)->tme_ieee754_extended80_constant_significand_lo; \
521     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
522   } while (/* CONSTCOND */ 0)
523 
524 /* tme_ieee754_extended80_value_builtin_get(x) returns the value of
525    x as the builtin C type that is the best match for the IEEE 754
526    extended80 precision format: */
527 #define tme_ieee754_extended80_value_builtin_get(x) \
528   (tme_ieee754_extended80_is_format_builtin(x) \
529    ? (x)->tme_float_value_ieee754_extended80_builtin \
530    : tme_ieee754_extended80_value_to_builtin(&(x)->tme_float_value_ieee754_extended80))
531 
532 /* tme_ieee754_extended80_value_builtin_set(x, format, y) sets the value of
533    x to y, whose type is a builtin C type with format format.  if the value of
534    y is a NaN or an infinity, y is stored in x in IEEE 754 extended80
535    precision format, otherwise y is stored in x as the builtin C type
536    that is the best match for the IEEE 754 extended80 precision format: */
537 #define tme_ieee754_extended80_value_builtin_set(x, format, y) \
538   do { \
539     /* set the value: */ \
540     tme_float_value_builtin_set(x, format, y); \
541     \
542     /* if the result is a NaN: */ \
543     if (tme_float_is_nan(x, format)) { \
544       \
545       /* use the proper default IEEE 754 extended80 precision NaN: */ \
546       (x)->tme_float_value_ieee754_extended80 = ieee754_ctl->tme_ieee754_ctl_default_nan_extended80; \
547       (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
548     } \
549     \
550     /* otherwise, if the result isn't already in IEEE 754 extended80 precision format: */ \
551     else if ((format) != TME_FLOAT_FORMAT_IEEE754_EXTENDED80) { \
552       \
553       /* if the result is infinite: */ \
554       if (tme_float_is_inf(x, format)) { \
555         \
556 	/* use the IEEE 754 extended80 precision infinity: */ \
557 	(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); \
558 	(x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = 0; \
559 	(x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = 0; \
560         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80; \
561       } \
562       \
563       /* otherwise, if the result isn't already the builtin C type that \
564          is the best match for the IEEE 754 extended80 precision format: */ \
565       else if ((format) != TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN) { \
566         \
567 	/* convert the result: */ \
568 	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
569 	  (x)->tme_float_value_ieee754_extended80_builtin = (x)->tme_float_value_float; \
570 	} \
571         TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
572 	  (x)->tme_float_value_ieee754_extended80_builtin = (x)->tme_float_value_long_double; \
573 	}) \
574 	else { \
575 	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
576 	  (x)->tme_float_value_ieee754_extended80_builtin = (x)->tme_float_value_double; \
577 	} \
578         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_EXTENDED80_BUILTIN; \
579       } \
580     } \
581   } while (/* CONSTCOND */ 0)
582 
583 /* this converts a value from IEEE 754 extended80 precision format
584    into the builtin C type that is the best match for that format: */
585 tme_ieee754_extended80_builtin_t tme_ieee754_extended80_value_to_builtin _TME_P((const struct tme_float_ieee754_extended80 *));
586 
587 /* this converts a value from the builtin C type that is the best
588    match for the IEEE 754 extended80 precision format, into that
589    format: */
590 const struct tme_float_ieee754_extended80 *tme_ieee754_extended80_value_from_builtin _TME_P((tme_ieee754_extended80_builtin_t, struct tme_float_ieee754_extended80 *));
591 
592 /* this does a NaN check for an IEEE 754 extended80 precision monadic function: */
593 int tme_ieee754_extended80_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));
594 
595 /* this does a NaN check for an IEEE 754 extended80 precision dyadic function: */
596 int tme_ieee754_extended80_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
597 
598 /* this converts a tme_uint32_t to a extended80: */
599 void tme_ieee754_extended80_from_int32 _TME_P((tme_uint32_t, struct tme_float *));
600 
601 #if defined(TME_HAVE_INT64_T)
602 
603 /* this converts a tme_uint64_t to a extended80: */
604 void tme_ieee754_extended80_from_int64 _TME_P((tme_uint64_t, struct tme_float *));
605 
606 #endif /* defined(TME_HAVE_INT64_T) */
607 
608 /* this converts an in-range IEEE 754 extended80 precision value into its
609    radix 10 mantissa and exponent.  the mantissa is either zero, or
610    in the range [1,10): */
611 void tme_ieee754_extended80_radix10_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));
612 
613 /* this scales an IEEE 754 extended80 precision value by adding n to its
614    radix 10 exponent: */
615 void tme_ieee754_extended80_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
616 
617 
618 /* decide which builtin C floating-point type is the best match for
619    the IEEE 754 quad precision format.  if a builtin type matches
620    this format exactly, use that type, otherwise we assume that the
621    smallest builtin type that is at least 16 bytes wide is the best
622    match.  if no builtin type is at least that wide, we use long
623    double, or double if long double is not available: */
624 #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_QUAD) != 0)
625 #define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_IEEE754_QUAD
626 #elif (_TME_SIZEOF_FLOAT >= 16)
627 #define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_FLOAT
628 #elif (_TME_SIZEOF_DOUBLE >= 16 || !defined(_TME_HAVE_LONG_DOUBLE))
629 #define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_DOUBLE
630 #else
631 #define TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE
632 #endif
633 
634 /* typedef the builtin C floating-point type that is the best match
635    for the IEEE 754 quad precision format: */
636 #if (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
637 typedef float tme_ieee754_quad_builtin_t;
638 #define tme_float_value_ieee754_quad_builtin tme_float_value_float
639 #elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
640 typedef double tme_ieee754_quad_builtin_t;
641 #define tme_float_value_ieee754_quad_builtin tme_float_value_double
642 #elif (TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)
643 typedef long double tme_ieee754_quad_builtin_t;
644 #define tme_float_value_ieee754_quad_builtin tme_float_value_long_double
645 #endif
646 
647 /* this asserts that the float is either in IEEE 754 quad
648    precision format, or in the best-match builtin type format.  it
649    evaluates to nonzero if the float is in IEEE 754 quad
650    precision format: */
651 #define tme_ieee754_quad_is_format(x) \
652   (tme_float_assert_formats(x, \
653                             TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
654    && tme_float_is_format(x, \
655                           TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN, \
656 		          TME_FLOAT_FORMAT_IEEE754_QUAD))
657 
658 /* this asserts that the float is either in IEEE 754 quad
659    precision format, or in the best-match builtin type format.  it
660    evaluates to nonzero if the float is in the best-match builtin
661    type format: */
662 #define tme_ieee754_quad_is_format_builtin(x) \
663   (tme_float_assert_formats(x, \
664                             TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
665    && tme_float_is_format(x, \
666                           TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN, \
667 		          TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
668 
669 /* this asserts that the float is either in IEEE 754 quad
670    precision format, or in the best-match builtin type format.  it
671    evaluates to nonzero if the float is a NaN: */
672 #define tme_ieee754_quad_is_nan(x) \
673   (tme_float_assert_formats(x, \
674                             TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
675    && tme_float_is_nan(x, \
676                        TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
677 
678 /* this asserts that the float is either in IEEE 754 quad
679    precision format, or in the best-match builtin type format.  it
680    evaluates to nonzero if the float is an infinity: */
681 #define tme_ieee754_quad_is_inf(x) \
682   (tme_float_assert_formats(x, \
683                             TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
684    && tme_float_is_inf(x, \
685                        TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
686 
687 /* this asserts that the float is either in IEEE 754 quad
688    precision format, or in the best-match builtin type format.  it
689    evaluates to nonzero if the float is a zero: */
690 #define tme_ieee754_quad_is_zero(x) \
691   (tme_float_assert_formats(x, \
692                             TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) \
693    && tme_float_is_zero(x, \
694                         TME_FLOAT_FORMAT_IEEE754_QUAD | TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN))
695 
696 /* tme_ieee754_quad_value_get(x, buffer) returns a pointer to
697    the value of x in IEEE 754 quad precision format (i.e., it
698    returns a pointer to struct tme_float_ieee754_quad).  if x isn't already in this
699    format, it is converted into that format in the given buffer: */
700 #define tme_ieee754_quad_value_get(x, buffer) \
701   (tme_ieee754_quad_is_format(x) \
702    ? &(x)->tme_float_value_ieee754_quad \
703    : tme_ieee754_quad_value_from_builtin((x)->tme_float_value_ieee754_quad_builtin, buffer))
704 
705 /* tme_ieee754_quad_value_set(x, y) sets the value of x to
706    y, in IEEE 754 quad precision format (i.e., y is a struct tme_float_ieee754_quad).
707    (the internal function _tme_ieee754_quad_value_set(x, t, y)
708    takes the type of y, which must be compatible with struct tme_float_ieee754_quad): */
709 #define tme_ieee754_quad_value_set(x, y) \
710   do { \
711     (x)->tme_float_value_ieee754_quad = (y); \
712     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
713   } while (/* CONSTCOND */ 0)
714 #define _tme_ieee754_quad_value_set(x, t, y) \
715   do { \
716     *((t *) &(x)->tme_float_value_ieee754_quad) = (y); \
717     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
718   } while (/* CONSTCOND */ 0)
719 
720 /* tme_ieee754_quad_value_set_constant(x, y) sets the value of
721    x to the constant y (i.e., y is a const struct tme_ieee754_quad_constant *): */
722 #define tme_ieee754_quad_value_set_constant(x, y) \
723   do { \
724     (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_hi = (y)->tme_ieee754_quad_constant_hi_hi; \
725     (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = (y)->tme_ieee754_quad_constant_hi_lo; \
726     (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = (y)->tme_ieee754_quad_constant_lo_hi; \
727     (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = (y)->tme_ieee754_quad_constant_lo_lo; \
728     (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
729   } while (/* CONSTCOND */ 0)
730 
731 /* tme_ieee754_quad_value_builtin_get(x) returns the value of
732    x as the builtin C type that is the best match for the IEEE 754
733    quad precision format: */
734 #define tme_ieee754_quad_value_builtin_get(x) \
735   (tme_ieee754_quad_is_format_builtin(x) \
736    ? (x)->tme_float_value_ieee754_quad_builtin \
737    : tme_ieee754_quad_value_to_builtin(&(x)->tme_float_value_ieee754_quad))
738 
739 /* tme_ieee754_quad_value_builtin_set(x, format, y) sets the value of
740    x to y, whose type is a builtin C type with format format.  if the value of
741    y is a NaN or an infinity, y is stored in x in IEEE 754 quad
742    precision format, otherwise y is stored in x as the builtin C type
743    that is the best match for the IEEE 754 quad precision format: */
744 #define tme_ieee754_quad_value_builtin_set(x, format, y) \
745   do { \
746     /* set the value: */ \
747     tme_float_value_builtin_set(x, format, y); \
748     \
749     /* if the result is a NaN: */ \
750     if (tme_float_is_nan(x, format)) { \
751       \
752       /* use the proper default IEEE 754 quad precision NaN: */ \
753       (x)->tme_float_value_ieee754_quad = ieee754_ctl->tme_ieee754_ctl_default_nan_quad; \
754       (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
755     } \
756     \
757     /* otherwise, if the result isn't already in IEEE 754 quad precision format: */ \
758     else if ((format) != TME_FLOAT_FORMAT_IEEE754_QUAD) { \
759       \
760       /* if the result is infinite: */ \
761       if (tme_float_is_inf(x, format)) { \
762         \
763 	/* use the IEEE 754 quad precision infinity: */ \
764 	(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); \
765 	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = 0; \
766 	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = 0; \
767 	(x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = 0; \
768         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD; \
769       } \
770       \
771       /* otherwise, if the result isn't already the builtin C type that \
772          is the best match for the IEEE 754 quad precision format: */ \
773       else if ((format) != TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN) { \
774         \
775 	/* convert the result: */ \
776 	if ((format) == TME_FLOAT_FORMAT_FLOAT) { \
777 	  (x)->tme_float_value_ieee754_quad_builtin = (x)->tme_float_value_float; \
778 	} \
779         TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \
780 	  (x)->tme_float_value_ieee754_quad_builtin = (x)->tme_float_value_long_double; \
781 	}) \
782 	else { \
783 	  assert((format) == TME_FLOAT_FORMAT_DOUBLE); \
784 	  (x)->tme_float_value_ieee754_quad_builtin = (x)->tme_float_value_double; \
785 	} \
786         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_QUAD_BUILTIN; \
787       } \
788     } \
789   } while (/* CONSTCOND */ 0)
790 
791 /* this converts a value from IEEE 754 quad precision format
792    into the builtin C type that is the best match for that format: */
793 tme_ieee754_quad_builtin_t tme_ieee754_quad_value_to_builtin _TME_P((const struct tme_float_ieee754_quad *));
794 
795 /* this converts a value from the builtin C type that is the best
796    match for the IEEE 754 quad precision format, into that
797    format: */
798 const struct tme_float_ieee754_quad *tme_ieee754_quad_value_from_builtin _TME_P((tme_ieee754_quad_builtin_t, struct tme_float_ieee754_quad *));
799 
800 /* this does a NaN check for an IEEE 754 quad precision monadic function: */
801 int tme_ieee754_quad_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));
802 
803 /* this does a NaN check for an IEEE 754 quad precision dyadic function: */
804 int tme_ieee754_quad_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
805 
806 /* this converts a tme_uint32_t to a quad: */
807 void tme_ieee754_quad_from_int32 _TME_P((tme_uint32_t, struct tme_float *));
808 
809 #if defined(TME_HAVE_INT64_T)
810 
811 /* this converts a tme_uint64_t to a quad: */
812 void tme_ieee754_quad_from_int64 _TME_P((tme_uint64_t, struct tme_float *));
813 
814 #endif /* defined(TME_HAVE_INT64_T) */
815 
816 /* this converts an in-range IEEE 754 quad precision value into its
817    radix 10 mantissa and exponent.  the mantissa is either zero, or
818    in the range [1,10): */
819 void tme_ieee754_quad_radix10_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));
820 
821 /* this scales an IEEE 754 quad precision value by adding n to its
822    radix 10 exponent: */
823 void tme_ieee754_quad_radix10_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
824 
825