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

1.1       root        1: #! /bin/sh
                      2: 
1.1.1.2 ! root        3: # $Id: ieee754-misc-auto.sh,v 1.6 2007/08/24 01:05:43 fredette Exp $
1.1       root        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>
1.1.1.2 ! root       52: _TME_RCSID("\$Id: ieee754-misc-auto.sh,v 1.6 2007/08/24 01:05:43 fredette Exp $");
1.1       root       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_value_ieee754_${precision}${sexp} = ${mask_exp} | (tme_float_is_negative(x, (format)) ? ${mask_sign} : 0); \\
                    251: EOF
                    252:        case "${precision}" in
                    253:        single) ;;
                    254:        double)
                    255:            echo "      (x)->tme_float_value_ieee754_double.tme_value64_uint32_lo = 0; \\"
                    256:            ;;
                    257:        extended80)
                    258:            echo "      (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_hi = 0; \\"
                    259:            echo "      (x)->tme_float_value_ieee754_extended80.tme_float_ieee754_extended80_significand.tme_value64_uint32_lo = 0; \\"
                    260:            ;;
                    261:        quad)
                    262:            echo "      (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_hi.tme_value64_uint32_lo = 0; \\"
                    263:            echo "      (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_hi = 0; \\"
                    264:            echo "      (x)->tme_float_value_ieee754_quad.tme_float_ieee754_quad_lo.tme_value64_uint32_lo = 0; \\"
                    265:            ;;
                    266:        esac
                    267:        cat <<EOF
1.1.1.2 ! root      268:         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\
1.1       root      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:        } \\
1.1.1.2 ! root      286:         (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN; \\
1.1       root      287:       } \\
                    288:     } \\
                    289:   } while (/* CONSTCOND */ 0)
                    290: 
                    291: /* this converts a value from IEEE 754 ${precision} precision format
                    292:    into the builtin C type that is the best match for that format: */
                    293: tme_ieee754_${precision}_builtin_t tme_ieee754_${precision}_value_to_builtin _TME_P((const ${integral} *));
                    294: 
                    295: /* this converts a value from the builtin C type that is the best
                    296:    match for the IEEE 754 ${precision} precision format, into that
                    297:    format: */
                    298: const ${integral} *tme_ieee754_${precision}_value_from_builtin _TME_P((tme_ieee754_${precision}_builtin_t, ${integral} *));
                    299: 
                    300: /* this does a NaN check for an IEEE 754 ${precision} precision monadic function: */
                    301: int tme_ieee754_${precision}_check_nan_monadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *));
                    302: 
                    303: /* this does a NaN check for an IEEE 754 ${precision} precision dyadic function: */
                    304: int tme_ieee754_${precision}_check_nan_dyadic _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
                    305: EOF
                    306: 
                    307:        # emit the prototypes for the from-integer conversion
                    308:        # functions:
                    309:        #
                    310:        for convert in int32 int64; do
                    311: 
                    312:            cond=1
                    313:            case ${convert} in
                    314:            int32) convert_builtin="tme_uint32_t" ;;
                    315:            int64) convert_builtin="tme_uint64_t" ; cond="defined(TME_HAVE_INT64_T)" ;;
                    316:            esac
                    317: 
                    318:            if test "${cond}" != 1; then
                    319:                echo ""
                    320:                echo "#if ${cond}"
                    321:            fi
                    322: 
                    323:            echo ""
                    324:            echo "/* this converts a ${convert_builtin} to a ${precision}: */"
                    325:            echo "void tme_ieee754_${precision}_from_${convert} _TME_P((${convert_builtin}, struct tme_float *));"
                    326: 
                    327:            if test "${cond}" != 1; then
                    328:                echo ""
                    329:                echo "#endif /* ${cond} */"
                    330:            fi
                    331:        done
                    332: 
                    333:        # permute over the radices:
                    334:        #
                    335:        for radix in 10; do
                    336: 
                    337:            cat <<EOF
                    338: 
                    339: /* this converts an in-range IEEE 754 ${precision} precision value into its
                    340:    radix ${radix} mantissa and exponent.  the mantissa is either zero, or 
                    341:    in the range [1,${radix}): */
                    342: void tme_ieee754_${precision}_radix${radix}_mantissa_exponent _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, struct tme_float *, struct tme_float *));
                    343: 
                    344: /* this scales an IEEE 754 ${precision} precision value by adding n to its 
                    345:    radix ${radix} exponent: */
                    346: void tme_ieee754_${precision}_radix${radix}_scale _TME_P((struct tme_ieee754_ctl *, const struct tme_float *, const struct tme_float *, struct tme_float *));
                    347: 
                    348: EOF
                    349:        done
                    350: 
                    351:     # otherwise, we're not generating a header:
                    352:     #
                    353:     else
                    354: 
                    355:        cat <<EOF
                    356: 
                    357: /* this converts a value from IEEE 754 ${precision} precision format
                    358:    to the builtin C type that is the best match for that format: */
                    359: tme_ieee754_${precision}_builtin_t
                    360: tme_ieee754_${precision}_value_to_builtin(const ${integral} *x_ieee754)
                    361: {
                    362:   tme_ieee754_${precision}_builtin_t x_builtin;
                    363:   tme_uint32_t exponent;
                    364:   tme_uint32_t sign;
                    365:   tme_uint32_t chunk;
                    366:   tme_uint32_t fracor;
                    367:   
                    368:   /* get x's biased exponent: */
                    369:   exponent = TME_FIELD_MASK_EXTRACTU((*x_ieee754)${sexp}, ${mask_exp});
                    370: 
                    371:   /* convert the fraction one 16-bit chunk at a time, and track
                    372:      a bitwise-or of all of the fraction bits: */
                    373: EOF
                    374:        chunk_i=0
                    375:        while true; do
                    376:            eval "chunk_member=\$chunk_member_${chunk_i} ; chunk_mask=\$chunk_mask_${chunk_i}"
                    377:            if test "x${chunk_member}" = xx; then
                    378:                break
                    379:            fi
                    380:            echo "  chunk = TME_FIELD_MASK_EXTRACTU((*x_ieee754)${chunk_member}, ${chunk_mask});"
                    381:            if test ${chunk_i} = 0; then
                    382:                echo "  fracor = chunk;"
                    383:                if ${implicit}; then
                    384:                    echo "  /* if the exponent is nonzero, add the implicit integer bit: */"
                    385:                    echo "  if (exponent != 0) chunk |= ((${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask})) + 1);"
1.1.1.2 ! root      386:                else
        !           387:                    echo "  /* if the exponent is the biased maximum, clear the explicit integer bit: */"
        !           388:                    echo "  if (exponent == ${exp_biased_max}) fracor &= ~_TME_FIELD_MASK_MSBIT(${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask}));"
1.1       root      389:                fi
                    390:                echo "  x_builtin = chunk;"
                    391:            else
                    392:                echo "  fracor |= chunk;"
                    393:                echo "  x_builtin = (x_builtin * 65536) + chunk;"
                    394:            fi
                    395:            chunk_i=`expr ${chunk_i} + 1`
                    396:        done
                    397:        cat <<EOF
                    398: 
                    399:   /* get x's sign bit: */
                    400:   sign = ((*x_ieee754)${sexp} & ${mask_sign});
                    401: 
                    402:   /* if the exponent is the biased maximum, x is either an infinity or a NaN: */
                    403:   if (exponent == ${exp_biased_max}) {
                    404: 
                    405:     /* if the fraction is nonzero, x is a NaN.  x must not be a NaN,
                    406:        because we were supposed to catch this earlier: */
                    407:     assert (fracor == 0);
                    408: 
                    409:     /* x is an infinity.  construct a builtin infinity: */
                    410:     x_builtin = 
                    411: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
1.1.1.2 ! root      412:       tme_float_infinity_float
1.1       root      413: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
1.1.1.2 ! root      414:       tme_float_infinity_double
1.1       root      415: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
1.1.1.2 ! root      416:       tme_float_infinity_long_double
1.1       root      417: #endif
1.1.1.2 ! root      418:       (sign);
1.1       root      419:   }
                    420: 
                    421:   /* if the exponent is the biased minimum and the fraction is
                    422:      all-bits-zero, x is a zero: */
                    423:   else if (exponent == 0
                    424:           && fracor == 0) {
                    425: 
                    426:     /* construct a builtin zero: */
                    427:     x_builtin = 
1.1.1.2 ! root      428:       (sign ?
1.1       root      429: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
1.1.1.2 ! root      430:        tme_float_negative_zero_float()
1.1       root      431: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
1.1.1.2 ! root      432:        tme_float_negative_zero_double()
1.1       root      433: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
1.1.1.2 ! root      434:        tme_float_negative_zero_long_double()
1.1       root      435: #endif
1.1.1.2 ! root      436:        : 0.0);
1.1       root      437:   }
                    438: 
                    439:   /* otherwise, x is an in-range value that needs to be converted: */
                    440:   else {
                    441: 
                    442:     /* scale the result by the unbiased exponent, adjusted by the
                    443:        number of fraction bits (which are currently to the left of the
                    444:        floating point in x_builtin): */
                    445:     x_builtin = 
                    446: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
                    447:       tme_float_radix2_scale_float
                    448: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
                    449:       tme_float_radix2_scale_double
                    450: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
                    451:       tme_float_radix2_scale_long_double
                    452: #endif
                    453:       (x_builtin, (exponent - ${exp_bias}) - ${fracbits});
                    454: 
                    455:     if (sign) {
                    456:       x_builtin = 0 - x_builtin;
                    457:     }
                    458:   }
                    459: 
                    460:   /* done: */
                    461:   return (x_builtin);
                    462: }
                    463: 
                    464: /* this converts a value from the builtin C type that is the best
                    465:    match for the IEEE 754 ${precision} precision format, to that
                    466:    format: */
                    467: const ${integral} *
                    468: tme_ieee754_${precision}_value_from_builtin(tme_ieee754_${precision}_builtin_t x_builtin, ${integral} *x_ieee754)
                    469: {
                    470:   tme_int32_t exponent;
                    471:   tme_uint32_t chunk;
1.1.1.2 ! root      472:   tme_ieee754_${precision}_builtin_t x_builtin_buffer;
        !           473:   const tme_ieee754_${precision}_builtin_t pzero_builtin = +0.0;
1.1       root      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: 
1.1.1.2 ! root      501:   /* if x is positive or negative zero: */
        !           502:   if (x_builtin == 0
        !           503:       || -x_builtin == 0) {
        !           504: 
        !           505:     /* set x's sign bit if x is not positive zero: */
        !           506:     memcpy((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin));
        !           507:     x_builtin_buffer = x_builtin;
        !           508:     if (x_builtin < 0
        !           509:         || memcmp((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)) != 0) {
        !           510:       (*x_ieee754)${sexp} |= ${mask_sign};
        !           511:     }
        !           512: 
        !           513:     /* return the zero: */
        !           514:     return (x_ieee754);
        !           515:   }
        !           516: 
1.1       root      517:   /* set x's sign bit: */
                    518:   if (x_builtin < 0) {
                    519:     (*x_ieee754)${sexp} |= ${mask_sign};
                    520:     x_builtin = -x_builtin;
                    521:   }
                    522: 
                    523:   /* bias the exponent: */
                    524:   exponent += ${exp_bias};
                    525: 
                    526:   /* if the biased exponent is greater than or equal to the biased
                    527:      maximum, we must represent x as an infinity: */
                    528:   if (exponent >= (tme_int32_t) ${exp_biased_max}) {
                    529: 
                    530:     /* we do this by just setting the biased exponent to the biased
                    531:        maximum: */
                    532:     exponent = ${exp_biased_max};
                    533:   }
                    534: 
                    535:   /* otherwise, x will be either a normalized number, a denormalized
                    536:      number, or possibly a zero: */
                    537:   else {
                    538: 
                    539:     /* if the biased exponent is less than or equal to the biased
                    540:        minimum, x will be a denormalized number (possibly so
                    541:        denormalized that it becomes a zero): */
                    542:     if (exponent <= 0) {
                    543: 
                    544:       /* scale x into a denormalized number: */
                    545:       assert (x_builtin >= 1);
                    546:       x_builtin = 
                    547: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT)
                    548:        tme_float_radix2_scale_float
                    549: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE)
                    550:        tme_float_radix2_scale_double
                    551: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE))
                    552:        tme_float_radix2_scale_long_double
                    553: #endif
                    554:        (x_builtin, exponent - 1);
                    555:       assert (x_builtin < 1);
                    556:       exponent = 0;
                    557:     }
                    558: 
                    559:     /* convert the mantissa, one 16-bit chunk at a time: */
                    560: EOF
                    561:        chunk_i=0
                    562:        while true; do
                    563:            eval "chunk_member=\$chunk_member_${chunk_i} ; chunk_mask=\$chunk_mask_${chunk_i}"
                    564:            if test "x${chunk_member}" = xx; then
                    565:                break
                    566:            fi
                    567:            factor="((${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask})) + 1)"
                    568:            if test ${chunk_i} = 0; then
                    569:                if ${implicit}; then
                    570:                    echo "    /* remove any implicit integer bit: */"
                    571:                    echo "    if (x_builtin >= 1) {"
                    572:                    echo "      x_builtin -= 1;"
                    573:                    echo "    }"
                    574:                else
                    575:                    factor="(${factor} / 2)"
                    576:                fi
                    577:            fi
                    578:            echo "    x_builtin = x_builtin * ${factor};"
                    579:            echo "    chunk = x_builtin;"
1.1.1.2 ! root      580:            echo "    chunk -= (chunk > x_builtin);"
1.1       root      581:            echo "    x_builtin -= chunk;"
                    582:            echo "    TME_FIELD_MASK_DEPOSITU((*x_ieee754)${chunk_member}, ${chunk_mask}, chunk);"
                    583:            chunk_i=`expr ${chunk_i} + 1`
                    584:        done
                    585:        cat <<EOF
                    586:   }
                    587: 
                    588:   /* set x's biased exponent: */
                    589:   TME_FIELD_MASK_DEPOSITU((*x_ieee754)${sexp}, ${mask_exp}, exponent);
                    590: 
                    591:   /* done: */
                    592:   return (x_ieee754);
                    593: }
                    594: EOF
                    595: 
                    596:        # emit the NaN check functions:
                    597:        #
                    598:        for monadic in true false; do
                    599:            if ${monadic}; then type=monadic; else type=dyadic; fi
                    600: 
                    601:            echo ""
                    602:            echo "/* this does a NaN check for an IEEE 754 ${precision} precision ${type} function: */"
                    603:            echo "int"
                    604:            echo -n "tme_ieee754_${precision}_check_nan_${type}(struct tme_ieee754_ctl *ieee754_ctl, const struct tme_float *src0"
                    605:            if ${monadic}; then :; else
                    606:                echo -n ", const struct tme_float *src1"
                    607:            fi
                    608:            echo ", struct tme_float *dst)"
                    609:            echo "{"
                    610:            echo "  const ${integral} *nan0;"
                    611:            if $monadic; then :; else
                    612:                echo "  const ${integral} *nan1;"
                    613:            fi
                    614:            echo ""
                    615:            echo "  /* check for a NaN operand: */"
                    616:            echo "  nan0 = NULL;"
                    617:            echo "  if (tme_ieee754_${precision}_is_nan(src0)) {"
                    618:            echo "    assert (src0->tme_float_format == TME_FLOAT_FORMAT_IEEE754_${capprecision});"
                    619:            echo "    nan0 = &src0->tme_float_value_ieee754_${precision};"
                    620:            echo "  }"
                    621:            if $monadic; then nan1=nan0; else
                    622:                nan1=nan1
                    623:                echo "  nan1 = nan0;"
                    624:                echo "  if (tme_ieee754_${precision}_is_nan(src1)) {"
                    625:                echo "    assert (src1->tme_float_format == TME_FLOAT_FORMAT_IEEE754_${capprecision});"
                    626:                echo "    nan1 = &src1->tme_float_value_ieee754_${precision};"
                    627:                echo "    if (nan0 == NULL) {"
                    628:                echo "      nan0 = nan1;"
                    629:                echo "    }"
                    630:                echo "  }"
                    631:            fi
                    632:            echo ""
                    633:            echo "  /* if we have a NaN operand: */"
                    634:            echo "  if (__tme_predict_false(nan0 != NULL)) {"
                    635:            echo ""
                    636:            echo "    /* propagate a NaN: */"
                    637:            echo "    dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision};"
                    638:            echo "    (*ieee754_ctl->tme_ieee754_ctl_nan_from_nans_${precision})"
                    639:            echo "      (ieee754_ctl, nan0, ${nan1}, &dst->tme_float_value_ieee754_${precision});"
                    640:            echo "    return (TRUE);"
                    641:            echo "  }"
                    642:            echo ""
                    643:            echo "  return (FALSE);"
                    644:            echo "}"
                    645:        done
                    646: 
                    647:        # emit the from-integer conversion functions:
                    648:        #
                    649:        for convert in int32 int64; do
                    650: 
                    651:            cond=1
                    652:            case ${convert} in
                    653:            int32) convert_builtin="tme_uint32_t" ;;
                    654:            int64) convert_builtin="tme_uint64_t" ; cond="defined(TME_HAVE_INT64_T)" ;;
                    655:            esac
                    656: 
                    657:            if test "${cond}" != 1; then
                    658:                echo ""
                    659:                echo "#if ${cond}"
                    660:            fi
                    661: 
                    662:            echo ""
                    663:            echo "/* this converts a ${convert_builtin} to a ${precision}: */"
                    664:            echo "void"
                    665:            echo "tme_ieee754_${precision}_from_${convert}(${convert_builtin} src, struct tme_float *dst)"
                    666:            echo "{"
                    667:            echo "  _tme_ieee754_${precision}_value_set(dst, ${precision_sf}, ${convert}_to_${precision_sf}(src));"
                    668:            echo "}"
                    669: 
                    670:            if test "${cond}" != 1; then
                    671:                echo ""
                    672:                echo "#endif /* ${cond} */"
                    673:            fi
                    674:        done
                    675: 
                    676:        # permute over the radices:
                    677:        #
                    678:        for radix in 2 10; do
                    679: 
                    680:            # XXX FIXME - for now, skip quad precisions.  this is just
                    681:            # laziness over generating the constants:
                    682:            #
                    683:            if test "${precision}" = quad; then continue; fi
                    684: 
                    685:            cat <<EOF
                    686: 
                    687: /* this converts an in-range IEEE 754 ${precision} precision value into its
                    688:    radix ${radix} mantissa and exponent.  the mantissa is either zero, or 
                    689:    in the range [1,${radix}): */
                    690: void
                    691: 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)
                    692: {
                    693:   tme_int32_t exponent;
                    694: EOF
                    695:            if test ${radix} != 2; then
                    696:                cat <<EOF
                    697: #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0)
                    698:   ${integral} value_ieee754_buffer;
                    699:   struct tme_float value_buffer;
                    700:   struct tme_float zero_buffer;
                    701:   struct tme_float one_buffer;
                    702:   struct tme_float constant_buffer;
                    703:   struct tme_float radix_buffer;
                    704:   ${precision_sf} * const value = (${precision_sf} *) &value_buffer.tme_float_value_ieee754_${precision};
                    705:   const ${precision_sf} * const zero = (${precision_sf} *) &zero_buffer.tme_float_value_ieee754_${precision};
                    706:   const ${precision_sf} * const one = (${precision_sf} *) &one_buffer.tme_float_value_ieee754_${precision};
                    707:   const ${precision_sf} * const constant = (${precision_sf} *) &constant_buffer.tme_float_value_ieee754_${precision};
                    708:   const ${precision_sf} * const radix = (${precision_sf} *) &radix_buffer.tme_float_value_ieee754_${precision};
                    709:   tme_uint32_t exponent_bit;
                    710:   int negate;
                    711: #endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0) */
                    712: EOF
                    713:            fi
                    714:            cat <<EOF
                    715: 
                    716:   /* check for a NaN operand: */
                    717:   if (__tme_predict_false(tme_ieee754_${precision}_check_nan_monadic(ieee754_ctl, src, _mantissa))) {
                    718:     if (_exponent != NULL) {
                    719:       *_exponent = *_mantissa;
                    720:     }
                    721:     return;
                    722:   }
                    723: 
                    724:   /* if this is an infinity: */
                    725:   if (tme_ieee754_${precision}_is_inf(src)) {
                    726: 
                    727:     /* return a NaN: */
                    728:     _mantissa->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision};
                    729:     _mantissa->tme_float_value_ieee754_${precision} = ieee754_ctl->tme_ieee754_ctl_default_nan_${precision};
                    730:     if (_exponent != NULL) {
                    731:       *_exponent = *_mantissa;
                    732:     }
                    733:     return;
                    734:   }
                    735: EOF
                    736:            if test ${radix} = 2; then
                    737:                echo ""
                    738:                echo "  /* extract the unbiased exponent: */"
                    739:                echo "  exponent = TME_FIELD_MASK_EXTRACTU(src->tme_float_value_ieee754_${precision}${sexp}, ${mask_exp});"
                    740:                echo "  exponent -= ${exp_bias};"
                    741:                echo ""
                    742:                echo "  /* the mantissa is the source with a biased zero for the exponent: */"
                    743:                echo "  *_mantissa = *src;"
                    744:                echo "  TME_FIELD_MASK_DEPOSITU(_mantissa->tme_float_value_ieee754_${precision}${sexp}, ${mask_exp}, ${exp_bias});"
                    745:            else
                    746:                cat <<EOF
                    747: 
                    748:   /* if a builtin type matches the IEEE 754 ${precision} format exactly, 
                    749:      use the corresponding mantissa-exponent function: */
                    750: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_FLOAT)
                    751:   tme_ieee754_${precision}_value_builtin_set
                    752:     (_mantissa,
                    753:      TME_FLOAT_FORMAT_FLOAT,
                    754:      tme_float_radix${radix}_mantissa_exponent_float(tme_ieee754_${precision}_value_builtin_get(src), &exponent));
                    755: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_DOUBLE)
                    756:   tme_ieee754_${precision}_value_builtin_set
                    757:     (_mantissa,
                    758:      TME_FLOAT_FORMAT_DOUBLE,
                    759:      tme_float_radix${radix}_mantissa_exponent_double(tme_ieee754_${precision}_value_builtin_get(src), &exponent));
                    760: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_LONG_DOUBLE))
                    761:   tme_ieee754_${precision}_value_builtin_set
                    762:     (_mantissa,
                    763:      TME_FLOAT_FORMAT_LONG_DOUBLE,
                    764:      tme_float_radix${radix}_mantissa_exponent_long_double(tme_ieee754_${precision}_value_builtin_get(src), &exponent));
                    765: #else
                    766: 
                    767:   /* get this value and some constants: */
                    768:   tme_ieee754_${precision}_value_set(&value_buffer, *tme_ieee754_${precision}_value_get(src, &value_ieee754_buffer));
                    769:   tme_ieee754_${precision}_value_set_constant(&zero_buffer, &tme_ieee754_${precision}_constant_zero);
                    770:   tme_ieee754_${precision}_value_set_constant(&one_buffer, &tme_ieee754_${precision}_constant_one);
                    771:   tme_ieee754_${precision}_value_set_constant(&radix_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[0]);
                    772: 
                    773:   /* take the magnitude of the value, but remember if it was negative: */
                    774:   negate = ${precision_sf}_lt(*value, *zero);
                    775:   if (negate) {
                    776:     *value = ${precision_sf}_sub(*zero, *value);
                    777:   }
                    778: 
                    779:   /* start with an exponent of zero: */
                    780:   exponent = 0;
                    781: 
                    782:   /* if the value is nonzero: */
                    783:   if (!${precision_sf}_eq(*value, *zero)) {
                    784: 
                    785:     /* while the value is less than one: */
                    786:     exponent_bit = TME_ARRAY_ELS(tme_ieee754_${precision}_constant_${radix}e_minus_2ex) - 1;
                    787:     tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e_minus_2ex[exponent_bit]);
                    788:     for (; ${precision_sf}_lt(*value, *one); ) {
                    789: 
                    790:       /* if value is less than or equal to ${radix}^-(2^exponent_bit),
                    791:          divide value by ${radix}^-(2^exponent_bit), and subtract 2^exponent_bit
                    792:          from exponent: */
                    793:       if (${precision_sf}_le(*value, *constant)
                    794:           || exponent_bit == 0) {
                    795:         *value = ${precision_sf}_div(*value, *constant);
                    796:         exponent -= (1 << exponent_bit);
                    797:       }
                    798: 
                    799:       /* otherwise, move to the next exponent bit: */
                    800:       else {
                    801:         exponent_bit--;
                    802:         tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e_minus_2ex[exponent_bit]);
                    803:       }
                    804:     }
                    805: 
                    806:     /* while the value is greater than ${radix}: */
                    807:     exponent_bit = TME_ARRAY_ELS(tme_ieee754_${precision}_constant_${radix}e2ex) - 1;
                    808:     tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]);
                    809:     for (; !(${precision_sf}_le(*value, *radix)) ; ) {
                    810: 
                    811:       /* if value is greater than or equal to ${radix}^(2^exponent_bit),
                    812:          divide value by ${radix}^(2^exponent_bit), and add 2^exponent_bit
                    813:          to exponent: */
                    814:       if (!(${precision_sf}_lt(*value, *constant))
                    815:           || exponent_bit == 0) {
                    816:         *value = ${precision_sf}_div(*value, *constant);
                    817:         exponent += (1 << exponent_bit);
                    818:       }
                    819: 
                    820:       /* otherwise, move to the next exponent bit: */
                    821:       else {
                    822:         exponent_bit--;
                    823:         tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]);
                    824:       }
                    825:     }
                    826: 
                    827:     /* if the value was originally negative, negate the mantissa: */
                    828:     if (negate) {
                    829:       *value = ${precision_sf}_sub(*zero, *value);
                    830:     }
                    831: 
                    832:     /* return the mantissa: */
                    833:     _tme_ieee754_${precision}_value_set(_mantissa, ${precision_sf}, *value);
                    834:   }
                    835: #endif
                    836: EOF
                    837:            fi
                    838:            cat <<EOF
                    839: 
                    840:   /* return the exponent: */
                    841:   if (_exponent != NULL) {
                    842:     _tme_ieee754_${precision}_value_set(_exponent, ${precision_sf}, int32_to_${precision_sf}(exponent));
                    843:   }
                    844: }
                    845: 
                    846: /* this scales an IEEE 754 ${precision} precision value by adding n to its 
                    847:    radix ${radix} exponent: */
                    848: void
                    849: 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)
                    850: {
                    851:   ${integral} src_buffer;
                    852:   tme_int8_t rounding_mode;
                    853:   tme_int32_t _n;
                    854: #if ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0)
                    855:   tme_int32_t exponent;
                    856:   tme_uint32_t exponent_bit, n;
                    857:   ${precision_sf} * const value = (${precision_sf} *) &dst->tme_float_value_ieee754_${precision};
                    858:   struct tme_float constant_buffer;
                    859:   const ${precision_sf} * const constant = (${precision_sf} *) &constant_buffer.tme_float_value_ieee754_${precision};
                    860: #endif /* ((TME_FLOAT_FORMATS_BUILTIN & TME_FLOAT_FORMAT_IEEE754_${capprecision}) == 0) */
                    861:     
                    862:   /* check for a NaN operand: */
                    863:   if (__tme_predict_false(tme_ieee754_${precision}_check_nan_dyadic(ieee754_ctl, src0, src1, dst))) {
                    864:     return;
                    865:   }
                    866: 
                    867:   /* if the exponent is an infinity: */
                    868:   if (tme_ieee754_${precision}_is_inf(src1)) {
                    869: 
                    870:     /* return a NaN: */
                    871:     dst->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision};
                    872:     dst->tme_float_value_ieee754_${precision} = ieee754_ctl->tme_ieee754_ctl_default_nan_${precision};
                    873:     return;
                    874:   }
                    875: 
                    876:   /* if the operand is a zero or an infinity: */
                    877:   if (tme_ieee754_${precision}_is_zero(src1)
                    878:       || tme_ieee754_${precision}_is_inf(src1)) {
                    879: 
                    880:     /* return the operand unchanged: */
                    881:     *dst = *src0;
                    882:     return;
                    883:   }
                    884: 
                    885:   /* truncate the exponent to an integer, using the round-to-zero mode: */
                    886:   rounding_mode = ieee754_ctl->tme_ieee754_ctl_rounding_mode;
                    887:   ieee754_ctl->tme_ieee754_ctl_rounding_mode = TME_FLOAT_ROUND_TO_ZERO;
                    888:   _n = ${precision_sf}_to_int32(*((const ${precision_sf} *) tme_ieee754_${precision}_value_get(src1, &src_buffer)));
                    889:   ieee754_ctl->tme_ieee754_ctl_rounding_mode = rounding_mode;
                    890: 
                    891:   /* if a builtin type matches the IEEE 754 ${precision} format exactly, 
                    892:      use the corresponding mantissa-exponent function: */
                    893: #if (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_FLOAT)
                    894:   tme_ieee754_${precision}_value_builtin_set
                    895:     (dst,
                    896:      TME_FLOAT_FORMAT_FLOAT,
                    897:      tme_float_radix${radix}_scale_float(tme_ieee754_${precision}_value_builtin_get(src0), _n));
                    898: #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_DOUBLE)
                    899:   tme_ieee754_${precision}_value_builtin_set
                    900:     (dst,
                    901:      TME_FLOAT_FORMAT_DOUBLE,
                    902:      tme_float_radix${radix}_scale_double(tme_ieee754_${precision}_value_builtin_get(src0), _n));
                    903: #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision} == TME_FLOAT_FORMAT_LONG_DOUBLE))
                    904:   tme_ieee754_${precision}_value_builtin_set
                    905:     (dst,
                    906:      TME_FLOAT_FORMAT_LONG_DOUBLE,
                    907:      tme_float_radix${radix}_scale_long_double(tme_ieee754_${precision}_value_builtin_get(src0), _n));
                    908: #else
                    909: 
                    910:   /* start this value: */
                    911:   tme_ieee754_${precision}_value_set(dst, *tme_ieee754_${precision}_value_get(src0, &src_buffer));
                    912: 
                    913:   /* start with the most significant exponent bit: */
                    914:   exponent_bit = TME_ARRAY_ELS(tme_ieee754_${precision}_constant_${radix}e2ex) - 1;
                    915:   exponent = (1 << exponent_bit);
                    916:   tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]);
                    917: 
                    918:   /* if n is negative: */
                    919:   if (_n < 0) {
                    920: 
                    921:     for (n = 0 - _n; n > 0;) {
                    922:       if (n >= exponent || exponent == 1) {
                    923:         *value = ${precision_sf}_div(*value, *constant);
                    924:         n -= exponent;
                    925:       }
                    926:       else {
                    927:         exponent >>= 1;
                    928:         exponent_bit--;
                    929:        tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]);
                    930:       }
                    931:     }
                    932:   }
                    933: 
                    934:   /* otherwise, n is positive: */
                    935:   else {
                    936:     for (n = _n; n > 0;) {
                    937:       if (n >= exponent || exponent == 1) {
                    938:         *value = ${precision_sf}_mul(*value, *constant);
                    939:         n -= exponent;
                    940:       }
                    941:       else {
                    942:         exponent >>= 1;
                    943:         exponent_bit--;
                    944:        tme_ieee754_${precision}_value_set_constant(&constant_buffer, &tme_ieee754_${precision}_constant_${radix}e2ex[exponent_bit]);
                    945:       }
                    946:     }
                    947:   }
                    948: #endif
                    949: }
                    950: EOF
                    951:        done
                    952: 
                    953:     fi
                    954: done
                    955: 
                    956: # done:
                    957: #
                    958: exit 0;

unix.superglobalmegacorp.com

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