|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.