--- tme/ic/ieee754/ieee754-misc-auto.sh 2018/04/24 16:40:26 1.1.1.1 +++ tme/ic/ieee754/ieee754-misc-auto.sh 2018/04/24 16:42:02 1.1.1.2 @@ -1,6 +1,6 @@ #! /bin/sh -# $Id: ieee754-misc-auto.sh,v 1.1.1.1 2018/04/24 16:40:26 root Exp $ +# $Id: ieee754-misc-auto.sh,v 1.1.1.2 2018/04/24 16:42:02 root Exp $ # ic/ieee754/ieee754-misc-auto.sh - automatically generates C code # for miscellaneous IEEE 754 emulation support: @@ -49,7 +49,7 @@ PROG=`basename $0` cat < -_TME_RCSID("\$Id: ieee754-misc-auto.sh,v 1.1.1.1 2018/04/24 16:40:26 root Exp $"); +_TME_RCSID("\$Id: ieee754-misc-auto.sh,v 1.1.1.2 2018/04/24 16:42:02 root Exp $"); EOF if $header; then @@ -247,7 +247,6 @@ EOF if (tme_float_is_inf(x, format)) { \\ \\ /* use the IEEE 754 ${precision} precision infinity: */ \\ - (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ (x)->tme_float_value_ieee754_${precision}${sexp} = ${mask_exp} | (tme_float_is_negative(x, (format)) ? ${mask_sign} : 0); \\ EOF case "${precision}" in @@ -266,6 +265,7 @@ EOF ;; esac cat <tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}; \\ } \\ \\ /* otherwise, if the result isn't already the builtin C type that \\ @@ -283,6 +283,7 @@ EOF assert((format) == TME_FLOAT_FORMAT_DOUBLE); \\ (x)->tme_float_value_ieee754_${precision}_builtin = (x)->tme_float_value_double; \\ } \\ + (x)->tme_float_format = TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN; \\ } \\ } \\ } while (/* CONSTCOND */ 0) @@ -382,6 +383,9 @@ EOF if ${implicit}; then echo " /* if the exponent is nonzero, add the implicit integer bit: */" echo " if (exponent != 0) chunk |= ((${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask})) + 1);" + else + echo " /* if the exponent is the biased maximum, clear the explicit integer bit: */" + echo " if (exponent == ${exp_biased_max}) fracor &= ~_TME_FIELD_MASK_MSBIT(${chunk_mask} / _TME_FIELD_MASK_FACTOR(${chunk_mask}));" fi echo " x_builtin = chunk;" else @@ -403,18 +407,15 @@ EOF assert (fracor == 0); /* x is an infinity. construct a builtin infinity: */ - /* XXX FIXME - we assume that multiplying the maximum builtin - value by +10 or -10 will not yield a value whose magnitude is - less than the maximum builtin value: */ x_builtin = #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) - FLOAT_MAX_FLOAT + tme_float_infinity_float #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) - FLOAT_MAX_DOUBLE + tme_float_infinity_double #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) - FLOAT_MAX_LONG_DOUBLE + tme_float_infinity_long_double #endif - * (sign ? -10 : 10); + (sign); } /* if the exponent is the biased minimum and the fraction is @@ -423,19 +424,16 @@ EOF && fracor == 0) { /* construct a builtin zero: */ - /* XXX FIXME - we assume that dividing the minimum builtin value - by +10 or -10 (in case the builtin type is radix 10) will yield - a value whose magnitude is not greater than the minimum builtin - value: */ x_builtin = + (sign ? #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) - FLOAT_MIN_FLOAT + tme_float_negative_zero_float() #elif (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_DOUBLE) - FLOAT_MIN_DOUBLE + tme_float_negative_zero_double() #elif (defined(_TME_HAVE_LONG_DOUBLE) && (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_LONG_DOUBLE)) - FLOAT_MIN_LONG_DOUBLE + tme_float_negative_zero_long_double() #endif - / (sign ? -10 : 10); + : 0.0); } /* otherwise, x is an in-range value that needs to be converted: */ @@ -471,6 +469,8 @@ tme_ieee754_${precision}_value_from_buil { tme_int32_t exponent; tme_uint32_t chunk; + tme_ieee754_${precision}_builtin_t x_builtin_buffer; + const tme_ieee754_${precision}_builtin_t pzero_builtin = +0.0; /* x must not be a NaN or an infinity: */ #if (TME_FLOAT_FORMAT_IEEE754_${capprecision}_BUILTIN == TME_FLOAT_FORMAT_FLOAT) @@ -498,17 +498,28 @@ tme_ieee754_${precision}_value_from_buil /* zero the IEEE 754 version: */ memset((char *) x_ieee754, 0, sizeof((*x_ieee754))); + /* if x is positive or negative zero: */ + if (x_builtin == 0 + || -x_builtin == 0) { + + /* set x's sign bit if x is not positive zero: */ + memcpy((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)); + x_builtin_buffer = x_builtin; + if (x_builtin < 0 + || memcmp((char *) &x_builtin_buffer, (char *) &pzero_builtin, sizeof(pzero_builtin)) != 0) { + (*x_ieee754)${sexp} |= ${mask_sign}; + } + + /* return the zero: */ + return (x_ieee754); + } + /* set x's sign bit: */ if (x_builtin < 0) { (*x_ieee754)${sexp} |= ${mask_sign}; x_builtin = -x_builtin; } - /* if x is zero, return now: */ - if (x_builtin == 0) { - return (x_ieee754); - } - /* bias the exponent: */ exponent += ${exp_bias}; @@ -566,10 +577,10 @@ EOF fi echo " x_builtin = x_builtin * ${factor};" echo " chunk = x_builtin;" + echo " chunk -= (chunk > x_builtin);" echo " x_builtin -= chunk;" echo " TME_FIELD_MASK_DEPOSITU((*x_ieee754)${chunk_member}, ${chunk_mask}, chunk);" chunk_i=`expr ${chunk_i} + 1` - factor=65536 done cat <