Annotation of tme/generic/float-auto.sh, revision 1.1.1.1

1.1       root        1: #! /bin/sh
                      2: 
                      3: # $Id: float-auto.sh,v 1.1 2005/02/17 12:17:00 fredette Exp $
                      4: 
                      5: # generic/float-auto.sh - automatically generates C code for floating
                      6: # point conversion functions:
                      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: for option
                     41: do
                     42:     case $option in
                     43:     --header) header=true ;;
                     44:     esac
                     45: done
                     46: 
                     47: PROG=`basename $0`
                     48: cat <<EOF
                     49: /* automatically generated by $PROG, do not edit! */
                     50: 
                     51: EOF
                     52: if $header; then :; else
                     53:     cat <<EOF
                     54: #include <tme/common.h>
                     55: _TME_RCSID("\$Id: float-auto.sh,v 1.1 2005/02/17 12:17:00 fredette Exp $");
                     56: 
                     57: /* includes: */
                     58: #include <tme/generic/float.h>
                     59: 
                     60: EOF
                     61: fi
                     62: 
                     63: # permute over the builtin types:
                     64: #
                     65: for _builtin_type in float double long_double; do
                     66: 
                     67:     # make the builtin type without underscores, and in all caps:
                     68:     #
                     69:     builtin_type=`echo ${_builtin_type} | sed -e 's/_/ /g'`
                     70:     _BUILTIN_TYPE=`echo ${_builtin_type} | tr 'a-z' 'A-Z'`
                     71: 
                     72:     # dispatch on the builtin type to open any protection:
                     73:     #
                     74:     case ${_builtin_type} in
                     75:     long_double) 
                     76:        echo ; echo "#ifdef _TME_HAVE_${_BUILTIN_TYPE}" ;;
                     77:     *) ;;
                     78:     esac
                     79: 
                     80:     # permute over the radices:
                     81:     #
                     82:     for radix in 2 10; do
                     83: 
                     84:        # if we're generating a header:
                     85:        #
                     86:        if $header; then
                     87:            cat <<EOF
                     88: 
                     89: /* this returns the radix ${radix} mantissa and exponent of an in-range ${builtin_type}.
                     90:    the mantissa is either zero, or in the range [1,${radix}): */
                     91: ${builtin_type} tme_float_radix${radix}_mantissa_exponent_${_builtin_type} _TME_P((${builtin_type}, tme_int32_t *));
                     92: 
                     93: /* this scales a value by adding n to its radix ${radix} exponent: */
                     94: ${builtin_type} tme_float_radix${radix}_scale_${_builtin_type} _TME_P((${builtin_type}, tme_int32_t));
                     95: EOF
                     96:            continue
                     97:        fi
                     98: 
                     99:        # permute over the sign of the exponent:
                    100:        #
                    101:        for _sign in pos neg; do
                    102: 
                    103:            # make the sign into two operators:
                    104:            #
                    105:            if test ${_sign} = pos; then sign= ; combine='*' ; else sign=- ; combine='/' ; fi
                    106: 
                    107:            echo ""
                    108:            echo "/* a series of ${builtin_type} values of the form ${radix}^${sign}x, where x is a power of two: */"
                    109:            echo "static const ${builtin_type} _tme_float_radix${radix}_exponent_bits_${_builtin_type}_${_sign}[] = {"
                    110:            exponent=1
                    111:            formats_last=
                    112: 
                    113:            while true; do
                    114: 
                    115:                # dispatch on the radix to get the largest factor we will
                    116:                # use, its exponent, and a coarse upper bound on this
                    117:                # value's exponent in the worst-case radix of two:
                    118:                #
                    119:                case ${radix} in
                    120:                2)  exponent_radix2=${exponent} ; x=16777216 ; exponent_x=24 ;;
                    121:                10) exponent_radix2=`expr ${exponent} \* 4` ; x=10000 ; exponent_x=4 ;;
                    122:                *) 
                    123:                    echo "$PROG internal error: can't handle radix ${radix}" 1>&2 
                    124:                    exit 1
                    125:                    ;;
                    126:                esac
                    127: 
                    128:                # we assume that all floating-point formats that use a
                    129:                # radix of two support at least positive and negative
                    130:                # exponents of magnitude 16.  if this exponent's
                    131:                # magnitude is greater than that, dispatch to get the
                    132:                # list of floating-point formats that support it:
                    133:                #
                    134:                formats=
                    135:                if test `expr ${exponent_radix2} \> 16` != 0; then
                    136: 
                    137:                    # the IEEE 754 types:
                    138:                    #
                    139:                    if test `expr ${exponent_radix2} \< 16384` != 0; then
                    140:                        formats="${formats} | TME_FLOAT_FORMAT_IEEE754_EXTENDED80"
                    141:                    fi
                    142:                    if test `expr ${exponent_radix2} \< 1024` != 0; then
                    143:                        formats="${formats} | TME_FLOAT_FORMAT_IEEE754_DOUBLE"
                    144:                    fi
                    145:                    if test `expr ${exponent_radix2} \< 128` != 0; then
                    146:                        formats="${formats} | TME_FLOAT_FORMAT_IEEE754_SINGLE"
                    147:                    fi
                    148: 
                    149:                    # if we don't know any formats that support this
                    150:                    # exponent, stop now:
                    151:                    #
                    152:                    if test "x${formats}" = x; then
                    153:                        break
                    154:                    fi
                    155: 
                    156:                    # clean up the formats:
                    157:                    #
                    158:                    formats="((TME_FLOAT_FORMAT_${_BUILTIN_TYPE} & ("`echo "${formats}" | sed -e 's%^ | %%'`")) != 0)"
                    159:                fi
                    160: 
                    161:                # if the formats have changed: 
                    162:                #
                    163:                if test "x${formats}" != "x${formats_last}"; then
                    164: 
                    165:                    # close any old #if first:
                    166:                    #
                    167:                    if test "x${formats_last}" != x; then
                    168:                        echo ""
                    169:                        echo "#endif /* ${formats_last} */"
                    170:                    fi
                    171: 
                    172:                    # open the new #if:
                    173:                    #
                    174:                    echo ""
                    175:                    echo "#if ${formats}"
                    176:                    formats_last=${formats}
                    177:                fi
                    178: 
                    179:                # compute this value:
                    180:                #
                    181:                echo ""
                    182:                echo "  /* ${radix}^${sign}${exponent}: */"
                    183:                exponent_remaining=${exponent}
                    184:                value=1
                    185:                while test ${exponent_remaining} != 0; do
                    186:                    if test `expr ${exponent_remaining} \>= ${exponent_x}` = 1; then
                    187:                        value="(${value} ${combine} ((${builtin_type}) ((tme_uint32_t) ${x})))"
                    188:                        exponent_remaining=`expr ${exponent_remaining} - ${exponent_x}`
                    189:                    else
                    190:                        x=`expr ${x} / ${radix}`
                    191:                        exponent_x=`expr ${exponent_x} - 1`
                    192:                    fi
                    193:                done
                    194:                echo "  ${value},"
                    195: 
                    196:                # double the exponent:
                    197:                #
                    198:                exponent=`expr ${exponent} \* 2`
                    199:            done
                    200: 
                    201:            # close any #if:
                    202:            #
                    203:            if test "x${formats_last}" != x; then
                    204:                echo ""
                    205:                echo "#endif /* ${formats_last} */"
                    206:            fi
                    207: 
                    208:            echo "};"
                    209:        done
                    210: 
                    211: cat <<EOF
                    212: 
                    213: /* this returns the radix ${radix} mantissa and exponent of an in-range ${builtin_type}.
                    214:    the mantissa is either zero, or in the range [1,${radix}): */
                    215: ${builtin_type}
                    216: tme_float_radix${radix}_mantissa_exponent_${_builtin_type}(${builtin_type} value, tme_int32_t *_exponent)
                    217: {
                    218:   tme_int32_t exponent;
                    219:   tme_uint32_t exponent_bit;
                    220:   int negate;
                    221: 
                    222:   /* take the magnitude of the value, but remember if it was negative: */
                    223:   negate = (value < 0);
                    224:   if (negate) {
                    225:     value = 0 - value;
                    226:   }
                    227: 
                    228:   /* start with an exponent of zero: */
                    229:   exponent = 0;
                    230: 
                    231:   /* if the value is zero, return zero: */
                    232:   /* XXX FIXME this returns positive zero for a negative zero argument: */
                    233:   if (value == 0) {
                    234:     *_exponent = exponent;
                    235:     return (0);
                    236:   }
                    237: 
                    238:   /* while the value is less than one: */
                    239:   exponent_bit = TME_ARRAY_ELS(_tme_float_radix${radix}_exponent_bits_${_builtin_type}_neg) - 1;
                    240:   for (; value < 1; ) {
                    241: 
                    242:     /* if value is less than or equal to ${radix}^-(2^exponent_bit),
                    243:        divide value by ${radix}^-(2^exponent_bit), and subtract 2^exponent_bit
                    244:        from exponent: */
                    245:     if (value <= _tme_float_radix${radix}_exponent_bits_${_builtin_type}_neg[exponent_bit]
                    246:         || exponent_bit == 0) {
                    247:       value /= _tme_float_radix${radix}_exponent_bits_${_builtin_type}_neg[exponent_bit];
                    248:       exponent -= (1 << exponent_bit);
                    249:     }
                    250: 
                    251:     /* otherwise, move to the next exponent bit: */
                    252:     else {
                    253:       exponent_bit--;
                    254:     }
                    255:   }
                    256: 
                    257:   /* while the value is greater than ${radix}: */
                    258:   exponent_bit = TME_ARRAY_ELS(_tme_float_radix${radix}_exponent_bits_${_builtin_type}_pos) - 1;
                    259:   for (; value > ${radix}; ) {
                    260: 
                    261:     /* if value is greater than or equal to ${radix}^(2^exponent_bit),
                    262:        divide value by ${radix}^(2^exponent_bit), and add 2^exponent_bit
                    263:        to exponent: */
                    264:     if (value >= _tme_float_radix${radix}_exponent_bits_${_builtin_type}_pos[exponent_bit]
                    265:         || exponent_bit == 0) {
                    266:       value /= _tme_float_radix${radix}_exponent_bits_${_builtin_type}_pos[exponent_bit];
                    267:       exponent += (1 << exponent_bit);
                    268:     }
                    269: 
                    270:     /* otherwise, move to the next exponent bit: */
                    271:     else {
                    272:       exponent_bit--;
                    273:     }
                    274:   }
                    275: 
                    276:   /* done: */
                    277:   *_exponent = exponent;
                    278:   return (negate ? 0 - value : value);
                    279: }
                    280: 
                    281: /* this scales a value by adding n to its exponent: */
                    282: ${builtin_type}
                    283: tme_float_radix${radix}_scale_${_builtin_type}(${builtin_type} value, tme_int32_t _n)
                    284: {
                    285:   tme_uint32_t exponent_bit, exponent;
                    286:   tme_uint32_t n;
                    287: 
                    288:   /* start with the most significant exponent bit: */
                    289:   exponent_bit = TME_ARRAY_ELS(_tme_float_radix${radix}_exponent_bits_${_builtin_type}_pos) - 1;
                    290:   exponent = (1 << exponent_bit);
                    291: 
                    292:   /* if n is negative: */
                    293:   if (_n < 0) {
                    294: 
                    295:     for (n = 0 - _n; n > 0;) {
                    296:       if (n >= exponent || exponent == 1) {
                    297:         value /= _tme_float_radix${radix}_exponent_bits_${_builtin_type}_pos[exponent_bit];
                    298:         n -= exponent;
                    299:       }
                    300:       else {
                    301:         exponent >>= 1;
                    302:         exponent_bit--;
                    303:       }
                    304:     }
                    305:   }
                    306: 
                    307:   /* otherwise, n is positive: */
                    308:   else {
                    309:     for (n = _n; n > 0;) {
                    310:       if (n >= exponent || exponent == 1) {
                    311:         value *= _tme_float_radix${radix}_exponent_bits_${_builtin_type}_pos[exponent_bit];
                    312:         n -= exponent;
                    313:       }
                    314:       else {
                    315:         exponent >>= 1;
                    316:         exponent_bit--;
                    317:       }
                    318:     }
                    319:   }
                    320: 
                    321:   return (value);
                    322: }
                    323: EOF
                    324:     done
                    325: 
                    326:     # dispatch on the type to close any protection:
                    327:     #
                    328:     case ${_builtin_type} in
                    329:     long_double) 
                    330:        echo ; echo "#endif /* _TME_HAVE_${_BUILTIN_TYPE} */" ;;
                    331:     *) ;;
                    332:     esac
                    333: 
                    334: done
                    335:        
                    336: # done:
                    337: #
                    338: exit 0

unix.superglobalmegacorp.com

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