|
|
1.1 ! root 1: #! /bin/sh ! 2: ! 3: # $Id: ieee754-misc-auto.sh,v 1.2 2005/05/11 00:13:33 fredette Exp $ ! 4: ! 5: # ic/ieee754/ieee754-misc-auto.sh - automatically generates C code ! 6: # for miscellaneous IEEE 754 emulation support: ! 7: ! 8: # ! 9: # Copyright (c) 2004 Matt Fredette ! 10: # All rights reserved. ! 11: # ! 12: # Redistribution and use in source and binary forms, with or without ! 13: # modification, are permitted provided that the following conditions ! 14: # are met: ! 15: # 1. Redistributions of source code must retain the above copyright ! 16: # notice, this list of conditions and the following disclaimer. ! 17: # 2. Redistributions in binary form must reproduce the above copyright ! 18: # notice, this list of conditions and the following disclaimer in the ! 19: # documentation and/or other materials provided with the distribution. ! 20: # 3. All advertising materials mentioning features or use of this software ! 21: # must display the following acknowledgement: ! 22: # This product includes software developed by Matt Fredette. ! 23: # 4. The name of the author may not be used to endorse or promote products ! 24: # derived from this software without specific prior written permission. ! 25: # ! 26: # THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR ! 27: # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED ! 28: # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ! 29: # DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ! 30: # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ! 31: # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ! 32: # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ! 34: # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ! 35: # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ! 36: # POSSIBILITY OF SUCH DAMAGE. ! 37: # ! 38: ! 39: header=false ! 40: ! 41: for option ! 42: do ! 43: case $option in ! 44: --header) header=true ;; ! 45: esac ! 46: done ! 47: ! 48: PROG=`basename $0` ! 49: cat <<EOF ! 50: /* automatically generated by $PROG, do not edit! */ ! 51: #include <tme/common.h> ! 52: _TME_RCSID("\$Id: ieee754-misc-auto.sh,v 1.2 2005/05/11 00:13:33 fredette Exp $"); ! 53: ! 54: EOF ! 55: if $header; then ! 56: : ! 57: else ! 58: cat <<EOF ! 59: #include <tme/ic/ieee754.h> ! 60: #include "softfloat-tme.h" ! 61: #include <math.h> ! 62: #ifdef HAVE_FLOAT_H ! 63: #include <float.h> ! 64: #endif ! 65: #ifdef HAVE_LIMITS_H ! 66: #include <limits.h> ! 67: #endif ! 68: EOF ! 69: fi ! 70: ! 71: # permute for the different precisions we want to support: ! 72: # ! 73: for precision in single double extended80 quad; do ! 74: ! 75: # get information about this precision: ! 76: # ! 77: _precision=`echo $0 | sed -e "s/$PROG/ieee754-precision.sh/"` ! 78: eval `sh ${_precision} ${precision}` ! 79: ! 80: # if we're generating a header: ! 81: # ! 82: if $header; then ! 83: cat <<EOF ! 84: ! 85: /* decide which builtin C floating-point type is the best match for ! 86: the IEEE 754 ${precision} precision format. if a builtin type matches ! 87: this format exactly, use that type, otherwise we assume that the ! 88: smallest builtin type that is at least ${size} bytes wide is the best ! 89: match. if no builtin type is at least that wide, we use long ! 90: double, or double if long double is not available: */ ! 91: #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) != 0) ! 92: #define TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN TME_FLOAT_FORMAT_IEEE754_${capprecision} ! 93: #elif (_TME_SIZEOF_FLOAT >= ${size}) ! 94: #define TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN TME_FLOAT_FORMAT_FLOAT ! 95: #elif (_TME_SIZEOF_DOUBLE >= ${size} || !defined(_TME_HAVE_LONG_DOUBLE)) ! 96: #define TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN TME_FLOAT_FORMAT_DOUBLE ! 97: #else ! 98: #define TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN TME_FLOAT_FORMAT_LONG_DOUBLE ! 99: #endif ! 100: ! 101: /* typedef the builtin C floating-point type that is the best match ! 102: for the IEEE 754 ${precision} precision format: */ ! 103: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 104: typedef float tme_ieee754_${precision}_builtin_t; ! 105: #define tme_float_value_ieee754_${precision}_builtin tme_float_value_float ! 106: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 107: typedef double tme_ieee754_${precision}_builtin_t; ! 108: #define tme_float_value_ieee754_${precision}_builtin tme_float_value_double ! 109: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE) ! 110: typedef long double tme_ieee754_${precision}_builtin_t; ! 111: #define tme_float_value_ieee754_${precision}_builtin tme_float_value_long_double ! 112: #endif ! 113: ! 114: /* this asserts that the float is either in IEEE 754 ${precision} ! 115: precision format, or in the best-match builtin type format. it ! 116: evaluates to nonzero if the float is in IEEE 754 ${precision} ! 117: precision format: */ ! 118: #define tme_ieee754_${precision}_is_format(x) \\ ! 119: (tme_float_assert_formats(x, \\ ! 120: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN) \\ ! 121: && tme_float_is_format(x, \\ ! 122: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN, \\ ! 123: TME_FLOAT_FORMAT_IEEE754_${capprecision})) ! 124: ! 125: /* this asserts that the float is either in IEEE 754 ${precision} ! 126: precision format, or in the best-match builtin type format. it ! 127: evaluates to nonzero if the float is in the best-match builtin ! 128: type format: */ ! 129: #define tme_ieee754_${precision}_is_format_builtin(x) \\ ! 130: (tme_float_assert_formats(x, \\ ! 131: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN) \\ ! 132: && tme_float_is_format(x, \\ ! 133: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN, \\ ! 134: TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN)) ! 135: ! 136: /* this asserts that the float is either in IEEE 754 ${precision} ! 137: precision format, or in the best-match builtin type format. it ! 138: evaluates to nonzero if the float is a NaN: */ ! 139: #define tme_ieee754_${precision}_is_nan(x) \\ ! 140: (tme_float_assert_formats(x, \\ ! 141: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN) \\ ! 142: && tme_float_is_nan(x, \\ ! 143: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN)) ! 144: ! 145: /* this asserts that the float is either in IEEE 754 ${precision} ! 146: precision format, or in the best-match builtin type format. it ! 147: evaluates to nonzero if the float is an infinity: */ ! 148: #define tme_ieee754_${precision}_is_inf(x) \\ ! 149: (tme_float_assert_formats(x, \\ ! 150: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN) \\ ! 151: && tme_float_is_inf(x, \\ ! 152: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN)) ! 153: ! 154: /* this asserts that the float is either in IEEE 754 ${precision} ! 155: precision format, or in the best-match builtin type format. it ! 156: evaluates to nonzero if the float is a zero: */ ! 157: #define tme_ieee754_${precision}_is_zero(x) \\ ! 158: (tme_float_assert_formats(x, \\ ! 159: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN) \\ ! 160: && tme_float_is_zero(x, \\ ! 161: TME_FLOAT_FORMAT_IEEE754_${capprecision} | TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN)) ! 162: ! 163: /* tme_ieee754_${precision}_value_get(x, buffer) returns a pointer to ! 164: the value of x in IEEE 754 ${precision} precision format (i.e., it ! 165: returns a pointer to ${integral}). if x isn't already in this ! 166: format, it is converted into that format in the given buffer: */ ! 167: #define tme_ieee754_${precision}_value_get(x, buffer) \\ ! 168: (tme_ieee754_${precision}_is_format(x) \\ ! 169: ? &(x)->tme_float_value_ieee754_${precision} \\ ! 170: : tme_ieee754_${precision}_value_from_builtin((x)->tme_float_value_ieee754_${precision}_builtin, buffer)) ! 171: ! 172: /* tme_ieee754_${precision}_value_set(x, y) sets the value of x to ! 173: y, in IEEE 754 ${precision} precision format (i.e., y is a ${integral}). ! 174: (the internal function _tme_ieee754_${precision}_value_set(x, t, y) ! 175: takes the type of y, which must be compatible with ${integral}): */ ! 176: #define tme_ieee754_${precision}_value_set(x, y) \\ ! 177: do { \\ ! 178: (x)->tme_float_value_ieee754_${precision} = (y); \\ ! 179: (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ ! 180: } while (/* CONSTCOND */ 0) ! 181: #define _tme_ieee754_${precision}_value_set(x, t, y) \\ ! 182: do { \\ ! 183: *((t *) &(x)->tme_float_value_ieee754_${precision}) = (y); \\ ! 184: (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ ! 185: } while (/* CONSTCOND */ 0) ! 186: ! 187: /* tme_ieee754_${precision}_value_set_constant(x, y) sets the value of ! 188: x to the constant y (i.e., y is a const ${constant} *): */ ! 189: #define tme_ieee754_${precision}_value_set_constant(x, y) \\ ! 190: do { \\ ! 191: EOF ! 192: x_value="(x)->tme_float_value_ieee754_${precision}" ! 193: case "${precision}" in ! 194: single) ! 195: echo " ${x_value} = *(y); \\" ! 196: ;; ! 197: double) ! 198: echo " ${x_value}.tme_value64_uint32_hi = (y)->tme_ieee754_double_constant_hi; \\" ! 199: echo " ${x_value}.tme_value64_uint32_lo = (y)->tme_ieee754_double_constant_lo; \\" ! 200: ;; ! 201: extended80) ! 202: echo " ${x_value}.tme_float_ieee754_extended80_sexp = (y)->tme_ieee754_extended80_constant_sexp; \\" ! 203: echo " ${x_value}.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = (y)->tme_ieee754_extended80_constant_significand_hi; \\" ! 204: echo " ${x_value}.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = (y)->tme_ieee754_extended80_constant_significand_lo; \\" ! 205: ;; ! 206: quad) ! 207: echo " ${x_value}.tme_float_ieee754_quad_hi.tme_value64_uint32_hi = (y)->tme_ieee754_quad_constant_hi_hi; \\" ! 208: echo " ${x_value}.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = (y)->tme_ieee754_quad_constant_hi_lo; \\" ! 209: echo " ${x_value}.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = (y)->tme_ieee754_quad_constant_lo_hi; \\" ! 210: echo " ${x_value}.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = (y)->tme_ieee754_quad_constant_lo_lo; \\" ! 211: ;; ! 212: esac ! 213: cat <<EOF ! 214: (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ ! 215: } while (/* CONSTCOND */ 0) ! 216: ! 217: /* tme_ieee754_${precision}_value_builtin_get(x) returns the value of ! 218: x as the builtin C type that is the best match for the IEEE 754 ! 219: ${precision} precision format: */ ! 220: #define tme_ieee754_${precision}_value_builtin_get(x) \\ ! 221: (tme_ieee754_${precision}_is_format_builtin(x) \\ ! 222: ? (x)->tme_float_value_ieee754_${precision}_builtin \\ ! 223: : tme_ieee754_${precision}_value_to_builtin(&(x)->tme_float_value_ieee754_${precision})) ! 224: ! 225: /* tme_ieee754_${precision}_value_builtin_set(x, format, y) sets the value of ! 226: x to y, whose type is a builtin C type with format format. if the value of ! 227: y is a NaN or an infinity, y is stored in x in IEEE 754 ${precision} ! 228: precision format, otherwise y is stored in x as the builtin C type ! 229: that is the best match for the IEEE 754 ${precision} precision format: */ ! 230: #define tme_ieee754_${precision}_value_builtin_set(x, format, y) \\ ! 231: do { \\ ! 232: /* set the value: */ \\ ! 233: tme_float_value_builtin_set(x, format, y); \\ ! 234: \\ ! 235: /* if the result is a NaN: */ \\ ! 236: if (tme_float_is_nan(x, format)) { \\ ! 237: \\ ! 238: /* use the proper default IEEE 754 ${precision} precision NaN: */ \\ ! 239: (x)->tme_float_value_ieee754_${precision} = ieee754_ctl->tme_ieee754_ctl_default_nan_${precision}; \\ ! 240: (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ ! 241: } \\ ! 242: \\ ! 243: /* otherwise, if the result isn't already in IEEE 754 ${precision} precision format: */ \\ ! 244: else if ((format) != TME_FLOAT_FORMAT_IEEE754_${capprecision}) { \\ ! 245: \\ ! 246: /* if the result is infinite: */ \\ ! 247: if (tme_float_is_inf(x, format)) { \\ ! 248: \\ ! 249: /* use the IEEE 754 ${precision} precision infinity: */ \\ ! 250: (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ ! 251: (x)->tme_float_value_ieee754_${precision}${sexp} = ${mask_exp} | (tme_float_is_negative(x, (format)) ? ${mask_sign} : 0); \\ ! 252: EOF ! 253: case "${precision}" in ! 254: single) ;; ! 255: double) ! 256: echo " (x)->tme_float_value_ieee754_double.tme_value64_uint32_lo = 0; \\" ! 257: ;; ! 258: extended80) ! 259: echo " (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = 0; \\" ! 260: echo " (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = 0; \\" ! 261: ;; ! 262: quad) ! 263: echo " (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = 0; \\" ! 264: echo " (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = 0; \\" ! 265: echo " (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = 0; \\" ! 266: ;; ! 267: esac ! 268: cat <<EOF ! 269: } \\ ! 270: \\ ! 271: /* otherwise, if the result isn't already the builtin C type that \\ ! 272: is the best match for the IEEE 754 ${precision} precision format: */ \\ ! 273: else if ((format) != TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN) { \\ ! 274: \\ ! 275: /* convert the result: */ \\ ! 276: if ((format) == TME_FLOAT_FORMAT_FLOAT) { \\ ! 277: (x)->tme_float_value_ieee754_${precision}_builtin = (x)->tme_float_value_float; \\ ! 278: } \\ ! 279: TME_FLOAT_IF_LONG_DOUBLE(else if ((format) == TME_FLOAT_FORMAT_LONG_DOUBLE) { \\ ! 280: (x)->tme_float_value_ieee754_${precision}_builtin = (x)->tme_float_value_long_double; \\ ! 281: }) \\ ! 282: else { \\ ! 283: assert((format) == TME_FLOAT_FORMAT_DOUBLE); \\ ! 284: (x)->tme_float_value_ieee754_${precision}_builtin = (x)->tme_float_value_double; \\ ! 285: } \\ ! 286: } \\ ! 287: } \\ ! 288: } while (/* CONSTCOND */ 0) ! 289: ! 290: /* this converts a value from IEEE 754 ${precision} precision format ! 291: into the builtin C type that is the best match for that format: */ ! 292: tme_ieee754_${precision}_builtin_t tme_ieee754_${precision}_value_to_builtin _TME_P((const ${integral} *)); ! 293: ! 294: /* this converts a value from the builtin C type that is the best ! 295: match for the IEEE 754 ${precision} precision format, into that ! 296: format: */ ! 297: const ${integral} *tme_ieee754_${precision}_value_from_builtin _TME_P((tme_ieee754_${precision}_builtin_t, ${integral} *)); ! 298: ! 299: /* this does a NaN check for an IEEE 754 ${precision} precision monadic function: */ ! 300: int tme_ieee754_${precision}_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *)); ! 301: ! 302: /* this does a NaN check for an IEEE 754 ${precision} precision dyadic function: */ ! 303: int tme_ieee754_${precision}_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *)); ! 304: EOF ! 305: ! 306: # emit the prototypes for the from-integer conversion ! 307: # functions: ! 308: # ! 309: for convert in int32 int64; do ! 310: ! 311: cond=1 ! 312: case ${convert} in ! 313: int32) convert_builtin="tme_uint32_t" ;; ! 314: int64) convert_builtin="tme_uint64_t" ; cond="defined(TME_HAVE_INT64_T)" ;; ! 315: esac ! 316: ! 317: if test "${cond}" != 1; then ! 318: echo "" ! 319: echo "#if ${cond}" ! 320: fi ! 321: ! 322: echo "" ! 323: echo "/* this converts a ${convert_builtin} to a ${precision}: */" ! 324: echo "void tme_ieee754_${precision}_from_${convert} _TME_P((${convert_builtin}, struct tme_float *));" ! 325: ! 326: if test "${cond}" != 1; then ! 327: echo "" ! 328: echo "#endif /* ${cond} */" ! 329: fi ! 330: done ! 331: ! 332: # permute over the radices: ! 333: # ! 334: for radix in 10; do ! 335: ! 336: cat <<EOF ! 337: ! 338: /* this converts an in-range IEEE 754 ${precision} precision value into its ! 339: radix ${radix} mantissa and exponent. the mantissa is either zero, or ! 340: in the range [1,${radix}): */ ! 341: void tme_ieee754_${precision}_radix${radix}_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *)); ! 342: ! 343: /* this scales an IEEE 754 ${precision} precision value by adding n to its ! 344: radix ${radix} exponent: */ ! 345: void tme_ieee754_${precision}_radix${radix}_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *)); ! 346: ! 347: EOF ! 348: done ! 349: ! 350: # otherwise, we're not generating a header: ! 351: # ! 352: else ! 353: ! 354: cat <<EOF ! 355: ! 356: /* this converts a value from IEEE 754 ${precision} precision format ! 357: to the builtin C type that is the best match for that format: */ ! 358: tme_ieee754_${precision}_builtin_t ! 359: tme_ieee754_${precision}_value_to_builtin(const ${integral} *x_ieee754) ! 360: { ! 361: tme_ieee754_${precision}_builtin_t x_builtin; ! 362: tme_uint32_t exponent; ! 363: tme_uint32_t sign; ! 364: tme_uint32_t chunk; ! 365: tme_uint32_t fracor; ! 366: ! 367: /* get x's biased exponent: */ ! 368: exponent = TME_FIELD_MASK_EXTRACTU((*x_ieee754)${sexp}, ${mask_exp}); ! 369: ! 370: /* convert the fraction one 16-bit chunk at a time, and track ! 371: a bitwise-or of all of the fraction bits: */ ! 372: EOF ! 373: chunk_i=0 ! 374: while true; do ! 375: eval "chunk_member=\$chunk_member_${chunk_i} ; chunk_mask=\$chunk_mask_${chunk_i}" ! 376: if test "x${chunk_member}" = xx; then ! 377: break ! 378: fi ! 379: echo " chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754)${chunk_member}, ${chunk_mask});" ! 380: if test ${chunk_i} = 0; then ! 381: echo " fracor = chunk;" ! 382: if ${implicit}; then ! 383: echo " /* if the exponent is nonzero, add the implicit integer bit: */" ! 384: echo " if (exponent != 0) chunk |= ((${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask})) + 1);" ! 385: fi ! 386: echo " x_builtin = chunk;" ! 387: else ! 388: echo " fracor |= chunk;" ! 389: echo " x_builtin = (x_builtin * 65536) + chunk;" ! 390: fi ! 391: chunk_i=`expr ${chunk_i} + 1` ! 392: done ! 393: cat <<EOF ! 394: ! 395: /* get x's sign bit: */ ! 396: sign = ((*x_ieee754)${sexp} & ${mask_sign}); ! 397: ! 398: /* if the exponent is the biased maximum, x is either an infinity or a NaN: */ ! 399: if (exponent == ${exp_biased_max}) { ! 400: ! 401: /* if the fraction is nonzero, x is a NaN. x must not be a NaN, ! 402: because we were supposed to catch this earlier: */ ! 403: assert (fracor == 0); ! 404: ! 405: /* x is an infinity. construct a builtin infinity: */ ! 406: /* XXX FIXME - we assume that multiplying the maximum builtin ! 407: value by +10 or -10 will not yield a value whose magnitude is ! 408: less than the maximum builtin value: */ ! 409: x_builtin = ! 410: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 411: FLOAT_MAX_FLOAT ! 412: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 413: FLOAT_MAX_DOUBLE ! 414: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 415: FLOAT_MAX_LONG_DOUBLE ! 416: #endif ! 417: * (sign ? -10 : 10); ! 418: } ! 419: ! 420: /* if the exponent is the biased minimum and the fraction is ! 421: all-bits-zero, x is a zero: */ ! 422: else if (exponent == 0 ! 423: && fracor == 0) { ! 424: ! 425: /* construct a builtin zero: */ ! 426: /* XXX FIXME - we assume that dividing the minimum builtin value ! 427: by +10 or -10 (in case the builtin type is radix 10) will yield ! 428: a value whose magnitude is not greater than the minimum builtin ! 429: value: */ ! 430: x_builtin = ! 431: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 432: FLOAT_MIN_FLOAT ! 433: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 434: FLOAT_MIN_DOUBLE ! 435: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 436: FLOAT_MIN_LONG_DOUBLE ! 437: #endif ! 438: / (sign ? -10 : 10); ! 439: } ! 440: ! 441: /* otherwise, x is an in-range value that needs to be converted: */ ! 442: else { ! 443: ! 444: /* scale the result by the unbiased exponent, adjusted by the ! 445: number of fraction bits (which are currently to the left of the ! 446: floating point in x_builtin): */ ! 447: x_builtin = ! 448: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 449: tme_float_radix2_scale_float ! 450: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 451: tme_float_radix2_scale_double ! 452: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 453: tme_float_radix2_scale_long_double ! 454: #endif ! 455: (x_builtin, (exponent - ${exp_bias}) - ${fracbits}); ! 456: ! 457: if (sign) { ! 458: x_builtin = 0 - x_builtin; ! 459: } ! 460: } ! 461: ! 462: /* done: */ ! 463: return (x_builtin); ! 464: } ! 465: ! 466: /* this converts a value from the builtin C type that is the best ! 467: match for the IEEE 754 ${precision} precision format, to that ! 468: format: */ ! 469: const ${integral} * ! 470: tme_ieee754_${precision}_value_from_builtin(tme_ieee754_${precision}_builtin_t x_builtin, ${integral} *x_ieee754) ! 471: { ! 472: tme_int32_t exponent; ! 473: tme_uint32_t chunk; ! 474: ! 475: /* x must not be a NaN or an infinity: */ ! 476: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 477: assert (!isnanf(x_builtin)); ! 478: assert (!isinff(x_builtin)); ! 479: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 480: assert (!isnan(x_builtin)); ! 481: assert (!isinf(x_builtin)); ! 482: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 483: assert (!isnan(x_builtin)); ! 484: assert (!isinf(x_builtin)); ! 485: #endif ! 486: ! 487: /* get the mantissa and exponent of x: */ ! 488: x_builtin = ! 489: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 490: tme_float_radix2_mantissa_exponent_float ! 491: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 492: tme_float_radix2_mantissa_exponent_double ! 493: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 494: tme_float_radix2_mantissa_exponent_long_double ! 495: #endif ! 496: (x_builtin, &exponent); ! 497: ! 498: /* zero the IEEE 754 version: */ ! 499: memset((char *) x_ieee754, 0, sizeof((*x_ieee754))); ! 500: ! 501: /* set x's sign bit: */ ! 502: if (x_builtin < 0) { ! 503: (*x_ieee754)${sexp} |= ${mask_sign}; ! 504: x_builtin = -x_builtin; ! 505: } ! 506: ! 507: /* if x is zero, return now: */ ! 508: if (x_builtin == 0) { ! 509: return (x_ieee754); ! 510: } ! 511: ! 512: /* bias the exponent: */ ! 513: exponent += ${exp_bias}; ! 514: ! 515: /* if the biased exponent is greater than or equal to the biased ! 516: maximum, we must represent x as an infinity: */ ! 517: if (exponent >= (tme_int32_t) ${exp_biased_max}) { ! 518: ! 519: /* we do this by just setting the biased exponent to the biased ! 520: maximum: */ ! 521: exponent = ${exp_biased_max}; ! 522: } ! 523: ! 524: /* otherwise, x will be either a normalized number, a denormalized ! 525: number, or possibly a zero: */ ! 526: else { ! 527: ! 528: /* if the biased exponent is less than or equal to the biased ! 529: minimum, x will be a denormalized number (possibly so ! 530: denormalized that it becomes a zero): */ ! 531: if (exponent <= 0) { ! 532: ! 533: /* scale x into a denormalized number: */ ! 534: assert (x_builtin >= 1); ! 535: x_builtin = ! 536: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) ! 537: tme_float_radix2_scale_float ! 538: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) ! 539: tme_float_radix2_scale_double ! 540: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 541: tme_float_radix2_scale_long_double ! 542: #endif ! 543: (x_builtin, exponent - 1); ! 544: assert (x_builtin < 1); ! 545: exponent = 0; ! 546: } ! 547: ! 548: /* convert the mantissa, one 16-bit chunk at a time: */ ! 549: EOF ! 550: chunk_i=0 ! 551: while true; do ! 552: eval "chunk_member=\$chunk_member_${chunk_i} ; chunk_mask=\$chunk_mask_${chunk_i}" ! 553: if test "x${chunk_member}" = xx; then ! 554: break ! 555: fi ! 556: factor="((${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask})) + 1)" ! 557: if test ${chunk_i} = 0; then ! 558: if ${implicit}; then ! 559: echo " /* remove any implicit integer bit: */" ! 560: echo " if (x_builtin >= 1) {" ! 561: echo " x_builtin -= 1;" ! 562: echo " }" ! 563: else ! 564: factor="(${factor} / 2)" ! 565: fi ! 566: fi ! 567: echo " x_builtin = x_builtin * ${factor};" ! 568: echo " chunk = x_builtin;" ! 569: echo " x_builtin -= chunk;" ! 570: echo " TME_FIELD_MASK_DEPOSITU((*x_ieee754)${chunk_member}, ${chunk_mask}, chunk);" ! 571: chunk_i=`expr ${chunk_i} + 1` ! 572: factor=65536 ! 573: done ! 574: cat <<EOF ! 575: } ! 576: ! 577: /* set x's biased exponent: */ ! 578: TME_FIELD_MASK_DEPOSITU((*x_ieee754)${sexp}, ${mask_exp}, exponent); ! 579: ! 580: /* done: */ ! 581: return (x_ieee754); ! 582: } ! 583: EOF ! 584: ! 585: # emit the NaN check functions: ! 586: # ! 587: for monadic in true false; do ! 588: if ${monadic}; then type=monadic; else type=dyadic; fi ! 589: ! 590: echo "" ! 591: echo "/* this does a NaN check for an IEEE 754 ${precision} precision ${type} function: */" ! 592: echo "int" ! 593: echo -n "tme_ieee754_${precision}_check_nan_${type}(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0" ! 594: if ${monadic}; then :; else ! 595: echo -n ", const struct tme_float *src1" ! 596: fi ! 597: echo ", struct tme_float *dst)" ! 598: echo "{" ! 599: echo " const ${integral} *nan0;" ! 600: if $monadic; then :; else ! 601: echo " const ${integral} *nan1;" ! 602: fi ! 603: echo "" ! 604: echo " /* check for a NaN operand: */" ! 605: echo " nan0 = NULL;" ! 606: echo " if (tme_ieee754_${precision}_is_nan(src0)) {" ! 607: echo " assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_${capprecision});" ! 608: echo " nan0 = &src0->tme_float_value_ieee754_${precision};" ! 609: echo " }" ! 610: if $monadic; then nan1=nan0; else ! 611: nan1=nan1 ! 612: echo " nan1 = nan0;" ! 613: echo " if (tme_ieee754_${precision}_is_nan(src1)) {" ! 614: echo " assert (src1->tme_float_format == TME_FLOAT_FORMAT_IEEE754_${capprecision});" ! 615: echo " nan1 = &src1->tme_float_value_ieee754_${precision};" ! 616: echo " if (nan0 == NULL) {" ! 617: echo " nan0 = nan1;" ! 618: echo " }" ! 619: echo " }" ! 620: fi ! 621: echo "" ! 622: echo " /* if we have a NaN operand: */" ! 623: echo " if (__tme_predict_false(nan0 != NULL)) {" ! 624: echo "" ! 625: echo " /* propagate a NaN: */" ! 626: echo " dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision};" ! 627: echo " (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_${precision})" ! 628: echo " (ieee754_ctl, nan0, ${nan1}, &dst->tme_float_value_ieee754_${precision});" ! 629: echo " return (TRUE);" ! 630: echo " }" ! 631: echo "" ! 632: echo " return (FALSE);" ! 633: echo "}" ! 634: done ! 635: ! 636: # emit the from-integer conversion functions: ! 637: # ! 638: for convert in int32 int64; do ! 639: ! 640: cond=1 ! 641: case ${convert} in ! 642: int32) convert_builtin="tme_uint32_t" ;; ! 643: int64) convert_builtin="tme_uint64_t" ; cond="defined(TME_HAVE_INT64_T)" ;; ! 644: esac ! 645: ! 646: if test "${cond}" != 1; then ! 647: echo "" ! 648: echo "#if ${cond}" ! 649: fi ! 650: ! 651: echo "" ! 652: echo "/* this converts a ${convert_builtin} to a ${precision}: */" ! 653: echo "void" ! 654: echo "tme_ieee754_${precision}_from_${convert}(${convert_builtin} src, struct tme_float *dst)" ! 655: echo "{" ! 656: echo " _tme_ieee754_${precision}_value_set(dst, ${precision_sf}, ${convert}_to_${precision_sf}(src));" ! 657: echo "}" ! 658: ! 659: if test "${cond}" != 1; then ! 660: echo "" ! 661: echo "#endif /* ${cond} */" ! 662: fi ! 663: done ! 664: ! 665: echo "" ! 666: echo "/* this converts a ${precision} to an int32: */" ! 667: echo "tme_int32_t" ! 668: echo "tme_ieee754_${precision}_to_int32(const struct tme_float *src)" ! 669: echo "{" ! 670: echo " ${integral} src_buffer;" ! 671: echo " return (${precision_sf}_to_int32(*((const ${precision_sf} *) tme_ieee754_${precision}_value_get(src, &src_buffer))));" ! 672: echo "}" ! 673: ! 674: # permute over the radices: ! 675: # ! 676: for radix in 2 10; do ! 677: ! 678: # XXX FIXME - for now, skip quad precisions. this is just ! 679: # laziness over generating the constants: ! 680: # ! 681: if test "${precision}" = quad; then continue; fi ! 682: ! 683: cat <<EOF ! 684: ! 685: /* this converts an in-range IEEE 754 ${precision} precision value into its ! 686: radix ${radix} mantissa and exponent. the mantissa is either zero, or ! 687: in the range [1,${radix}): */ ! 688: void ! 689: tme_ieee754_${precision}_radix${radix}_mantissa_exponent(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src, struct tme_float *_mantissa, struct tme_float *_exponent) ! 690: { ! 691: tme_int32_t exponent; ! 692: EOF ! 693: if test ${radix} != 2; then ! 694: cat <<EOF ! 695: #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0) ! 696: ${integral} value_ieee754_buffer; ! 697: struct tme_float value_buffer; ! 698: struct tme_float zero_buffer; ! 699: struct tme_float one_buffer; ! 700: struct tme_float constant_buffer; ! 701: struct tme_float radix_buffer; ! 702: ${precision_sf} * const value = (${precision_sf} *) &value_buffer.tme_float_value_ieee754_${precision}; ! 703: const ${precision_sf} * const zero = (${precision_sf} *) &zero_buffer.tme_float_value_ieee754_${precision}; ! 704: const ${precision_sf} * const one = (${precision_sf} *) &one_buffer.tme_float_value_ieee754_${precision}; ! 705: const ${precision_sf} * const constant = (${precision_sf} *) &constant_buffer.tme_float_value_ieee754_${precision}; ! 706: const ${precision_sf} * const radix = (${precision_sf} *) &radix_buffer.tme_float_value_ieee754_${precision}; ! 707: tme_uint32_t exponent_bit; ! 708: int negate; ! 709: #endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0) */ ! 710: EOF ! 711: fi ! 712: cat <<EOF ! 713: ! 714: /* check for a NaN operand: */ ! 715: if (__tme_predict_false(tme_ieee754_${precision}_check_nan_monadic(ieee754_ctl, src, _mantissa))) { ! 716: if (_exponent != NULL) { ! 717: *_exponent = *_mantissa; ! 718: } ! 719: return; ! 720: } ! 721: ! 722: /* if this is an infinity: */ ! 723: if (tme_ieee754_${precision}_is_inf(src)) { ! 724: ! 725: /* return a NaN: */ ! 726: _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; ! 727: _mantissa->tme_float_value_ieee754_${precision} = ieee754_ctl->tme_ieee754_ctl_default_nan_${precision}; ! 728: if (_exponent != NULL) { ! 729: *_exponent = *_mantissa; ! 730: } ! 731: return; ! 732: } ! 733: EOF ! 734: if test ${radix} = 2; then ! 735: echo "" ! 736: echo " /* extract the unbiased exponent: */" ! 737: echo " exponent = TME_FIELD_MASK_EXTRACTU(src->tme_float_value_ieee754_${precision}${sexp}, ${mask_exp});" ! 738: echo " exponent -= ${exp_bias};" ! 739: echo "" ! 740: echo " /* the mantissa is the source with a biased zero for the exponent: */" ! 741: echo " *_mantissa = *src;" ! 742: echo " TME_FIELD_MASK_DEPOSITU(_mantissa->tme_float_value_ieee754_${precision}${sexp}, ${mask_exp}, ${exp_bias});" ! 743: else ! 744: cat <<EOF ! 745: ! 746: /* if a builtin type matches the IEEE 754 ${precision} format exactly, ! 747: use the corresponding mantissa-exponent function: */ ! 748: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_FLOAT) ! 749: tme_ieee754_${precision}_value_builtin_set ! 750: (_mantissa, ! 751: TME_FLOAT_FORMAT_FLOAT, ! 752: tme_float_radix${radix}_mantissa_exponent_float(tme_ieee754_${precision}_value_builtin_get(src), &exponent)); ! 753: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_DOUBLE) ! 754: tme_ieee754_${precision}_value_builtin_set ! 755: (_mantissa, ! 756: TME_FLOAT_FORMAT_DOUBLE, ! 757: tme_float_radix${radix}_mantissa_exponent_double(tme_ieee754_${precision}_value_builtin_get(src), &exponent)); ! 758: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 759: tme_ieee754_${precision}_value_builtin_set ! 760: (_mantissa, ! 761: TME_FLOAT_FORMAT_LONG_DOUBLE, ! 762: tme_float_radix${radix}_mantissa_exponent_long_double(tme_ieee754_${precision}_value_builtin_get(src), &exponent)); ! 763: #else ! 764: ! 765: /* get this value and some constants: */ ! 766: tme_ieee754_${precision}_value_set(&value_buffer, *tme_ieee754_${precision}_value_get(src, &value_ieee754_buffer)); ! 767: tme_ieee754_${precision}_value_set_constant(&zero_buffer, &tme_ieee754_${precision}_constant_zero); ! 768: tme_ieee754_${precision}_value_set_constant(&one_buffer, &tme_ieee754_${precision}_constant_one); ! 769: tme_ieee754_${precision}_value_set_constant(&radix_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[0]); ! 770: ! 771: /* take the magnitude of the value, but remember if it was negative: */ ! 772: negate = ${precision_sf}_lt(*value, *zero); ! 773: if (negate) { ! 774: *value = ${precision_sf}_sub(*zero, *value); ! 775: } ! 776: ! 777: /* start with an exponent of zero: */ ! 778: exponent = 0; ! 779: ! 780: /* if the value is nonzero: */ ! 781: if (!${precision_sf}_eq(*value, *zero)) { ! 782: ! 783: /* while the value is less than one: */ ! 784: exponent_bit = TME_ARRAY_ELS(tme_ieee754_${precision}_constant_${radix}e_minus_2ex) - 1; ! 785: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e_minus_2ex[exponent_bit]); ! 786: for (; ${precision_sf}_lt(*value, *one); ) { ! 787: ! 788: /* if value is less than or equal to ${radix}^-(2^exponent_bit), ! 789: divide value by ${radix}^-(2^exponent_bit), and subtract 2^exponent_bit ! 790: from exponent: */ ! 791: if (${precision_sf}_le(*value, *constant) ! 792: || exponent_bit == 0) { ! 793: *value = ${precision_sf}_div(*value, *constant); ! 794: exponent -= (1 << exponent_bit); ! 795: } ! 796: ! 797: /* otherwise, move to the next exponent bit: */ ! 798: else { ! 799: exponent_bit--; ! 800: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e_minus_2ex[exponent_bit]); ! 801: } ! 802: } ! 803: ! 804: /* while the value is greater than ${radix}: */ ! 805: exponent_bit = TME_ARRAY_ELS(tme_ieee754_${precision}_constant_${radix}e2ex) - 1; ! 806: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]); ! 807: for (; !(${precision_sf}_le(*value, *radix)) ; ) { ! 808: ! 809: /* if value is greater than or equal to ${radix}^(2^exponent_bit), ! 810: divide value by ${radix}^(2^exponent_bit), and add 2^exponent_bit ! 811: to exponent: */ ! 812: if (!(${precision_sf}_lt(*value, *constant)) ! 813: || exponent_bit == 0) { ! 814: *value = ${precision_sf}_div(*value, *constant); ! 815: exponent += (1 << exponent_bit); ! 816: } ! 817: ! 818: /* otherwise, move to the next exponent bit: */ ! 819: else { ! 820: exponent_bit--; ! 821: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]); ! 822: } ! 823: } ! 824: ! 825: /* if the value was originally negative, negate the mantissa: */ ! 826: if (negate) { ! 827: *value = ${precision_sf}_sub(*zero, *value); ! 828: } ! 829: ! 830: /* return the mantissa: */ ! 831: _tme_ieee754_${precision}_value_set(_mantissa, ${precision_sf}, *value); ! 832: } ! 833: #endif ! 834: EOF ! 835: fi ! 836: cat <<EOF ! 837: ! 838: /* return the exponent: */ ! 839: if (_exponent != NULL) { ! 840: _tme_ieee754_${precision}_value_set(_exponent, ${precision_sf}, int32_to_${precision_sf}(exponent)); ! 841: } ! 842: } ! 843: ! 844: /* this scales an IEEE 754 ${precision} precision value by adding n to its ! 845: radix ${radix} exponent: */ ! 846: void ! 847: tme_ieee754_${precision}_radix${radix}_scale(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0, const struct tme_float *src1, struct tme_float *dst) ! 848: { ! 849: ${integral} src_buffer; ! 850: tme_int8_t rounding_mode; ! 851: tme_int32_t _n; ! 852: #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0) ! 853: tme_int32_t exponent; ! 854: tme_uint32_t exponent_bit, n; ! 855: ${precision_sf} * const value = (${precision_sf} *) &dst->tme_float_value_ieee754_${precision}; ! 856: struct tme_float constant_buffer; ! 857: const ${precision_sf} * const constant = (${precision_sf} *) &constant_buffer.tme_float_value_ieee754_${precision}; ! 858: #endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0) */ ! 859: ! 860: /* check for a NaN operand: */ ! 861: if (__tme_predict_false(tme_ieee754_${precision}_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) { ! 862: return; ! 863: } ! 864: ! 865: /* if the exponent is an infinity: */ ! 866: if (tme_ieee754_${precision}_is_inf(src1)) { ! 867: ! 868: /* return a NaN: */ ! 869: dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; ! 870: dst->tme_float_value_ieee754_${precision} = ieee754_ctl->tme_ieee754_ctl_default_nan_${precision}; ! 871: return; ! 872: } ! 873: ! 874: /* if the operand is a zero or an infinity: */ ! 875: if (tme_ieee754_${precision}_is_zero(src1) ! 876: || tme_ieee754_${precision}_is_inf(src1)) { ! 877: ! 878: /* return the operand unchanged: */ ! 879: *dst = *src0; ! 880: return; ! 881: } ! 882: ! 883: /* truncate the exponent to an integer, using the round-to-zero mode: */ ! 884: rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode; ! 885: ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO; ! 886: _n = ${precision_sf}_to_int32(*((const ${precision_sf} *) tme_ieee754_${precision}_value_get(src1, &src_buffer))); ! 887: ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode; ! 888: ! 889: /* if a builtin type matches the IEEE 754 ${precision} format exactly, ! 890: use the corresponding mantissa-exponent function: */ ! 891: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_FLOAT) ! 892: tme_ieee754_${precision}_value_builtin_set ! 893: (dst, ! 894: TME_FLOAT_FORMAT_FLOAT, ! 895: tme_float_radix${radix}_scale_float(tme_ieee754_${precision}_value_builtin_get(src0), _n)); ! 896: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_DOUBLE) ! 897: tme_ieee754_${precision}_value_builtin_set ! 898: (dst, ! 899: TME_FLOAT_FORMAT_DOUBLE, ! 900: tme_float_radix${radix}_scale_double(tme_ieee754_${precision}_value_builtin_get(src0), _n)); ! 901: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_LONG_DOUBLE)) ! 902: tme_ieee754_${precision}_value_builtin_set ! 903: (dst, ! 904: TME_FLOAT_FORMAT_LONG_DOUBLE, ! 905: tme_float_radix${radix}_scale_long_double(tme_ieee754_${precision}_value_builtin_get(src0), _n)); ! 906: #else ! 907: ! 908: /* start this value: */ ! 909: tme_ieee754_${precision}_value_set(dst, *tme_ieee754_${precision}_value_get(src0, &src_buffer)); ! 910: ! 911: /* start with the most significant exponent bit: */ ! 912: exponent_bit = TME_ARRAY_ELS(tme_ieee754_${precision}_constant_${radix}e2ex) - 1; ! 913: exponent = (1 << exponent_bit); ! 914: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]); ! 915: ! 916: /* if n is negative: */ ! 917: if (_n < 0) { ! 918: ! 919: for (n = 0 - _n; n > 0;) { ! 920: if (n >= exponent || exponent == 1) { ! 921: *value = ${precision_sf}_div(*value, *constant); ! 922: n -= exponent; ! 923: } ! 924: else { ! 925: exponent >>= 1; ! 926: exponent_bit--; ! 927: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]); ! 928: } ! 929: } ! 930: } ! 931: ! 932: /* otherwise, n is positive: */ ! 933: else { ! 934: for (n = _n; n > 0;) { ! 935: if (n >= exponent || exponent == 1) { ! 936: *value = ${precision_sf}_mul(*value, *constant); ! 937: n -= exponent; ! 938: } ! 939: else { ! 940: exponent >>= 1; ! 941: exponent_bit--; ! 942: tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]); ! 943: } ! 944: } ! 945: } ! 946: #endif ! 947: } ! 948: EOF ! 949: done ! 950: ! 951: fi ! 952: done ! 953: ! 954: # done: ! 955: # ! 956: exit 0;
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.