Annotation of tme/generic/float-auto.sh, revision 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.