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