Annotation of tme/ic/ieee754/ieee754-misc-auto.sh, revision 1.1.1.1

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;

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.