From 1924012666b33dd9d093de801ffadfba38d141bf Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 29 Aug 2005 13:10:54 +0000 Subject: [PATCH] Determination of floating-point types parameters when cross-compiling. --- m4/floatparam.m4 | 129 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 m4/floatparam.m4 diff --git a/m4/floatparam.m4 b/m4/floatparam.m4 new file mode 100644 index 0000000..56dd53e --- /dev/null +++ b/m4/floatparam.m4 @@ -0,0 +1,129 @@ +# floatparam.m4 serial 1 +dnl Copyright (C) 2005 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl From Bruno Haible. + +AC_DEFUN([CL_FLOATPARAM_CROSS], +[ + AC_REQUIRE([CL_LONGDOUBLE]) + cl_machine_file_h=$1 + { + echo "/* Rounding modes, for use below */" + echo "#define rounds_to_nearest 0 /* 0.5 ulp */" + echo "#define rounds_to_zero 1 /* 1 ulp */" + echo "#define rounds_to_infinity 2 /* 1 ulp */" + echo "#define rounds_to_minus_infinity 3 /* 1 ulp */" + echo + for type in float double "`if test $cl_cv_c_longdouble = yes; then echo 'long double'; fi`"; do + if test -n "$type"; then + epsilon_bits=-1; y="($type)1.0" + while true; do + AC_TRY_COMPILE([], + [typedef int verify[2*( + (($type)(($type)1.0 + ($type)($y)) == ($type)1.0) + || ($type)(($type)(($type)1.0 + ($type)($y)) - ($type)1.0) != ($type)($y) + ) - 1];], + [break;]) + epsilon_bits=`expr $epsilon_bits + 1`; y="$y * ($type)0.5" + done + negepsilon_bits=-1; y="($type)-1.0" + while true; do + AC_TRY_COMPILE([], + [typedef int verify[2*( + (($type)(($type)1.0 + ($type)($y)) == ($type)1.0) + || ($type)(($type)(($type)1.0 + ($type)($y)) - ($type)1.0) != ($type)($y) + ) - 1];], + [break;]) + negepsilon_bits=`expr $negepsilon_bits + 1`; y="$y * ($type)0.5" + done + echo "/* Properties of type \`$type': */" + echo "/* Largest n for which 1+2^(-n) is exactly represented is $epsilon_bits. */" + echo "/* Largest n for which 1-2^(-n) is exactly represented is $negepsilon_bits. */" + if test `expr $negepsilon_bits '<=' $epsilon_bits` = 1; then + echo "#error \"No exponent jump at 1.0 for type $type!\"" + else + if test `expr $negepsilon_bits '>' $epsilon_bits + 1` = 1; then + echo "/* Base for type '$type' is 2^"`expr $negepsilon_bits - $epsilon_bits` + fi + echo "#define "`echo $type | sed -e 's, ,_,g'`"_mant_bits "`expr $epsilon_bits + 1` + fi + x="($type)1.0" + i=$epsilon_bits + while test $i != 0; do + x="$x * ($type)0.5" + i=`expr $i - 1` + done + x="($type)($x)" + y1="($type)(($type)1.0 + ($type)5.0*$x)" + y2="($type)(($type)1.0 + ($type)6.0*$x)" + ys1="($type)(($type)1.0 + ($type)5.4*$x)" + ys2="($type)(($type)1.0 + ($type)5.6*$x)" + z1="($type)(($type)-1.0 + ($type)(-5.0)*$x)" + z2="($type)(($type)-1.0 + ($type)(-6.0)*$x)" + zs1="($type)(($type)-1.0 + ($type)(-5.4)*$x)" + zs2="($type)(($type)-1.0 + ($type)(-5.6)*$x)" + rounds= + if test -z "$rounds"; then + AC_TRY_COMPILE([], + [typedef int verify[2*( + $ys1 == $y1 && $ys2 == $y2 && $zs1 == $z1 && $zs2 == $z2 + ) - 1];], + [rounds=rounds_to_nearest]) + fi + if test -z "$rounds"; then + AC_TRY_COMPILE([], + [typedef int verify[2*( + $ys1 == $y1 && $ys2 == $y1 && $zs1 == $z1 && $zs2 == $z1 + ) - 1];], + [rounds=rounds_to_zero]) + fi + if test -z "$rounds"; then + AC_TRY_COMPILE([], + [typedef int verify[2*( + $ys1 == $y2 && $ys2 == $y2 && $zs1 == $z1 && $zs2 == $z1 + ) - 1];], + [rounds=rounds_to_infinity]) + fi + if test -z "$rounds"; then + AC_TRY_COMPILE([], + [typedef int verify[2*( + $ys1 == $y1 && $ys2 == $y1 && $zs1 == $z2 && $zs2 == $z2 + ) - 1];], + [rounds=rounds_to_minus_infinity]) + fi + if test -n "$rounds"; then + echo "#define "`echo $type | sed -e 's, ,_,g'`"_rounds $rounds" + else + echo "#error \"Unknown rounding mode for type $type!\"" + fi + echo + fi + done + dnl Words-in-a-double endianness test. Note that, assuming IEEE 754 format, + dnl 2.5479915693083957 = { 0x40 0x04 0x62 0x49 0x67 0x65 0x4E 0x64 } ..bIgeNd + dnl 1.4396527506122064e164 = { 0x62 0x04 0x00 0x00 0x4E 0x65 0x67 0x49 } b...NegI + dnl 2.5495230282078065 = { 0x40 0x04 0x65 0x6C 0x54 0x54 0x69 0x4C } ..elTTiL + dnl 1.4139248369879473e214 = { 0x6C 0x65 0x00 0x00 0x4C 0x69 0x54 0x54 } le..LiTT + double_wordorder_bigendian_p= + AC_TRY_COMPILE([double a[9] = { + 0, 2.5479915693083957, 0, 1.4396527506122064e164, + 0, 2.5495230282078065, 0, 1.4139248369879473e214, + 0 };], [], [ + if grep LiTTle conftest.$ac_objext >/dev/null ; then + double_wordorder_bigendian_p=0 + else + if grep bIgeN conftest.$ac_objext >/dev/null ; then + double_wordorder_bigendian_p=1 + fi + fi]) + if test -n "$double_wordorder_bigendian_p"; then + echo "#define double_wordorder_bigendian_p $double_wordorder_bigendian_p" + else + echo "/* Dazed and confused! Better not define anything. */" + fi + echo + } > "$cl_machine_file_h" +])