diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 2015-02-28 10:23:06 -0500 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2015-06-12 09:56:55 -0400 |
commit | 44521f3a1782026b7d25cc55af459c3e28cc9bdd (patch) | |
tree | a91ebe41a705b5562dee1eefde0e13aaf94a4c9b /Configure | |
parent | 63545cd8b35d0a75c86800927564a9879ba1e0bf (diff) | |
download | perl-44521f3a1782026b7d25cc55af459c3e28cc9bdd.tar.gz |
infnan: Configure scan for infnan bytes
Diffstat (limited to 'Configure')
-rwxr-xr-x | Configure | 178 |
1 files changed, 178 insertions, 0 deletions
@@ -631,7 +631,9 @@ d_log2='' d_logb='' d_ldexpl='' d_longdbl='' +longdblinfbytes='' longdblkind='' +longdblnanbytes='' longdblsize='' d_longlong='' longlongsize='' @@ -1096,6 +1098,8 @@ d_PRIfldbl='' d_PRIgldbl='' d_SCNfldbl='' doublekind='' +doubleinfbytes='' +doublenanbytes='' sPRIEUldbl='' sPRIFUldbl='' sPRIGUldbl='' @@ -10114,6 +10118,174 @@ case "$doublekind" in esac $rm_try +: see if this is a math.h system +set math.h i_math +eval $inhdr + +: Check what kind of inf/nan your system has +$echo "Checking the kind of infinities and nans you have..." >&4 +$cat >try.c <<EOP +#define DOUBLESIZE $doublesize +#$d_longdbl HAS_LONG_DOUBLE +#ifdef HAS_LONG_DOUBLE +#define LONGDBLSIZE $longdblsize +#define LONGDBLKIND $longdblkind +#endif +#$i_math I_MATH +#ifdef I_MATH +#include <math.h> +#endif +#include <stdio.h> +/* Note that whether the sign bit is on or off + * for NaN depends on the CPU/FPU, and possibly + * can be affected by the build toolchain. + * + * For example for older MIPS and HP-PA 2.0 the quiet NaN is: + * 0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff + * 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + * (respectively) as opposed to the more usual + * 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + */ +static void bytes(unsigned char *p, unsigned int n) { + int i; + for (i = 0; i < n; i++) { + printf("0x%02x%s", p[i], i < n - 1 ? ", " : "\n"); + } +} +int main(int argc, char *argv[]) { + /* We cannot use 1.0/0.0 and 0.0/0.0 (with L suffixes for long double) + * because some compilers are 'smart' and not only warn but refuse to + * compile such 'illegal' values. */ + double dinf = exp(1e9); + double dnan = sqrt(-1.0); +#ifdef HAS_LONG_DOUBLE + long double ldinf = (long double)exp(1e9); + long double ldnan = (long double)sqrt(-1.0); +#endif + if (argc == 2) { + switch (argv[1][0]) { + case '1': bytes(&dinf, sizeof(dinf)); break; + case '2': bytes(&dnan, sizeof(dnan)); break; +#ifdef HAS_LONG_DOUBLE +# if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4 +/* the 80-bit long doubles might have garbage in their excess bytes */ + memset((char *)&ldinf + 10, '\0', LONG_DOUBLESIZE - 10); +# endif + case '3': bytes(&ldinf, sizeof(ldinf)); break; + case '4': bytes(&ldnan, sizeof(ldnan)); break; +#endif + } + } + return 0; +} +EOP +set try +if eval $compile; then + doubleinfbytes=`$run ./try 1` + doublenanbytes=`$run ./try 2` + case "$d_longdbl" in + $define) + longdblinfbytes=`$run ./try 3` + longdblnanbytes=`$run ./try 4` + ;; + esac +else + # Defaults in case the above test program failed. + case "$doublekind" in + 1) # IEEE 754 32-bit LE + doubleinfbytes='0x00, 0x00, 0xf0, 0x7f' + doublenanbytes='0x00, 0x00, 0xf8, 0x7f' + ;; + 2) # IEEE 754 32-bit BE + doubleinfbytes='0x7f, 0xf0, 0x00, 0x00' + doublenanbytes='0x7f, 0xf8, 0x00, 0x00' + ;; + 3) # IEEE 754 64-bit LE + doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' + doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' + ;; + 4) # IEEE 754 64-bit BE + doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + 5) # IEEE 754 128-bit LE + doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' + doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' + ;; + 6) # IEEE 754 128-bit BE + doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + 7) # IEEE 754 64-bit mixed: 32-bit LEs in BE + doubleinfbytes='0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00' + doublenanbytes='0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00' + ;; + 8) # IEEE 754 64-bit mixed: 32-bit BEs in LE + doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00' + doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00' + ;; + *) # No idea. + doubleinfbytes=$undef + doublenanbytes=$undef + ;; + esac + case "$longdblkind" in + 1) # IEEE 754 128-bit LE + longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f' + longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f' + ;; + 2) # IEEE 754 128-bit BE + longdblinfbytes='0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + 3) # IEEE 754 80-bit LE, 12 or 16 bytes (x86) + case "$longdblsize" in + 12) # x86 32-bit (96 bits, or 4 x 32, or 12 x 8) + longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00' + longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00' + ;; + 16) # x86_64 + longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + *) # No idea. + longdblinfbytes=$undef + longdlnan=$undef + ;; + esac + ;; + 4) # IEEE 754 80-bit BE, 12 or 16 bytes + case "$longdblsize" in + 12) # 32-bit system + longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + 16) # 64-bit system + longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + *) # No idea. + longdblinfbytes=$undef + longdlnan=$undef + ;; + esac + ;; + 5) # 128-bit LE "double double" + longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f' + longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f' + ;; + 6) # 128-bit BE "double double" + longdblinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + longdblnanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00' + ;; + *) # No idea. + longdblinfbytes=$undef + longdlnan=$undef + ;; + esac +fi +$rm_try + : Check print/scan long double stuff echo " " @@ -24286,7 +24458,10 @@ db_version_patch='$db_version_patch' direntrytype='$direntrytype' dlext='$dlext' dlsrc='$dlsrc' +doubleinfbytes='$doubleinfbytes' doublekind='$doublekind' +doublemantbits='$doublemantbits' +doublenanbytes='$doublenanbytes' doublesize='$doublesize' drand01='$drand01' drand48_r_proto='$drand48_r_proto' @@ -24534,7 +24709,10 @@ lns='$lns' localtime_r_proto='$localtime_r_proto' locincpth='$locincpth' loclibpth='$loclibpth' +longdblinfbytes='$longdblinfbytes' longdblkind='$longdblkind' +longdblmantbits='$longdblmantbits' +longdblnanbytes='$longdblnanbytes' longdblsize='$longdblsize' longlongsize='$longlongsize' longsize='$longsize' |