?RCS: License or the Artistic License, as specified in the README file.
?RCS:
?MAKE:ivtype uvtype nvtype ivsize uvsize nvsize \
- i8type u8type i16type u16type i32type u32type i64type u64type \
- i8size u8size i16size u16size i32size u32size i64size u64size \
- d_nv_preserves_uv nv_preserves_uv_bits d_nv_zero_is_allbits_zero: \
- echo rm_try use64bitint d_quad quadtype uquadtype \
- d_longdbl uselongdouble longdblsize doublesize \
- shortsize intsize longsize i_stdlib i_string \
- cat Compile i_inttypes test d_volatile signal_t run
+ i8type u8type i16type u16type i32type u32type i64type u64type \
+ i8size u8size i16size u16size i32size u32size i64size u64size \
+ d_nv_preserves_uv nv_preserves_uv_bits nv_overflows_integers_at \
+ d_nv_zero_is_allbits_zero: \
+ echo rm_try use64bitint d_quad quadtype uquadtype usequadmath \
+ d_longdbl uselongdouble longdblsize doublesize i_quadmath \
+ shortsize intsize longsize i_stdlib libs gccversion \
+ cat Compile i_inttypes test signal_t run
?MAKE: -pick add $@ %<
?S:ivtype:
?S: This variable contains the C type used for Perl's IV.
?S: This variable is the size of an U64 in bytes.
?S:.
?S:nvsize:
-?S: This variable is the size of an NV in bytes.
+?S: This variable is the size of a Perl NV in bytes.
+?S: Note that some floating point formats have unused bytes.
?S:.
?S:d_nv_preserves_uv:
?S: This variable indicates whether a variable of type nvtype
?S: This variable indicates how many of bits type uvtype
?S: a variable nvtype can preserve.
?S:.
+?S:nv_overflows_integers_at:
+?S: This variable gives the largest integer value that NVs can hold
+?S: as a constant floating point expression.
+?S: If it could not be determined, it holds the value 0.
+?S:.
?S:d_nv_zero_is_allbits_zero:
?S: This variable indicates whether a variable of type nvtype
?S: stores 0.0 in memory as all bits zero.
?C:.
?C:NVSIZE:
?C: This symbol contains the sizeof(NV).
+?C: Note that some floating point formats have unused bytes.
+?C: The most notable example is the x86* 80-bit extended precision
+?C: which comes in byte sizes of 12 and 16 (for 32 and 64 bit
+?C: platforms, respectively), but which only uses 10 bytes.
+?C: Perl compiled with -Duselongdouble on x86* is like this.
?C:.
?C:NV_PRESERVES_UV:
?C: This symbol, if defined, indicates that a variable of type NVTYPE
?C: This symbol contains the number of bits a variable of type NVTYPE
?C: can preserve of a variable of type UVTYPE.
?C:.
+?C:NV_OVERFLOWS_INTEGERS_AT:
+?C: This symbol gives the largest integer value that NVs can hold. This
+?C: value + 1.0 cannot be stored accurately. It is expressed as constant
+?C: floating point expression to reduce the chance of decimal/binary
+?C: conversion issues. If it can not be determined, the value 0 is given.
+?C:.
?C:NV_ZERO_IS_ALLBITS_ZERO:
?C: This symbol, if defined, indicates that a variable of type NVTYPE
?C: stores 0.0 in memory as all bits zero.
?H:#define NVSIZE $nvsize /**/
?H:#$d_nv_preserves_uv NV_PRESERVES_UV
?H:#define NV_PRESERVES_UV_BITS $nv_preserves_uv_bits
+?H:#define NV_OVERFLOWS_INTEGERS_AT ($nv_overflows_integers_at)
?H:#$d_nv_zero_is_allbits_zero NV_ZERO_IS_ALLBITS_ZERO
?H:?%<:#if UVSIZE == 8
?H:?%<:# ifdef BYTEORDER
?H:?%<:# endif
?H:?%<:#endif
?H:.
-?T:volatile
?T:xxx
?T:d
?F:!try
;;
esac
+case "$usequadmath:$i_quadmath" in
+define:define)
+ nvtype="__float128"
+ nvsize=16
+ : libquadmath is not in the usual places, and the place
+ : changes if the compiler is upgraded. So ask the compiler if it
+ : can find it.
+ : We do not need to save this, if it fails we abort.
+ libs="$libs -lquadmath"
+ set try
+ $cat >try.c <<EOM
+#include <quadmath.h>
+#include <stdio.h>
+int main(int argc, char *argv[]) {
+ __float128 x = 1.0;
+ if (fabsq(logq(x)) > 1e-6) {
+ fputs("quadmath is broken\n", stderr);
+ return 1;
+ }
+ puts("define");
+ return 0;
+}
+EOM
+ yyy=''
+ if eval $compile_ok; then
+ yyy=`$run ./try`
+ case "$yyy" in
+ define) ;;
+ *) cat <<EOM >&4
+
+*** You requested the use of the quadmath library, but
+*** it appears to be nonfunctional.
+*** Cannot continue, aborting.
+
+EOM
+ exit 1
+ ;;
+ esac
+ else
+ $cat <<EOM >&4
+
+*** You requested the use of the quadmath library, but you
+*** do not seem to have the quadmath library installed.
+*** Cannot continue, aborting.
+EOM
+ exit 1
+ fi
+ ;;
+define:*) $cat <<EOM >&4
+
+*** You requested the use of the quadmath library, but you
+*** do not seem to have the required header, <quadmath.h>.
+EOM
+ case "$gccversion" in
+ [23].*|4.[0-5]*)
+ $cat <<EOM >&4
+*** Your gcc looks a bit old:
+*** $gccversion
+EOM
+ ;;
+ '')
+ $cat <<EOM >&4
+*** You are not running a gcc.
+EOM
+ ;;
+ esac
+ $cat <<EOM >&4
+*** For the quadmath library you need at least gcc 4.6.
+*** Cannot continue, aborting.
+EOM
+ exit 1
+ ;;
+esac
+
$echo "(IV will be "$ivtype", $ivsize bytes)"
$echo "(UV will be "$uvtype", $uvsize bytes)"
$echo "(NV will be "$nvtype", $nvsize bytes)"
#endif
#ifdef INT16
int16_t i = INT16_MAX;
- uint16_t i = UINT16_MAX;
+ uint16_t u = UINT16_MAX;
printf("int16_t\n");
#endif
#ifdef INT32
esac
$echo "Checking how many bits of your UVs your NVs can preserve..." >&4
-: volatile so that the compiler has to store it out to memory.
-if test X"$d_volatile" = X"$define"; then
- volatile=volatile
-fi
$cat <<EOP >try.c
#include <stdio.h>
#$i_stdlib I_STDLIB
#ifdef I_STDLIB
#include <stdlib.h>
#endif
+#$i_inttypes I_INTTYPES
+#ifdef I_INTTYPES
+#include <inttypes.h>
+#endif
#include <sys/types.h>
#include <signal.h>
#ifdef SIGFPE
-$volatile int bletched = 0;
+/* volatile so that the compiler has to store it out to memory */
+volatile int bletched = 0;
$signal_t blech(int s) { bletched = 1; }
#endif
int main() {
case "$nv_preserves_uv_bits" in
\-[1-9]*)
nv_preserves_uv_bits=`expr 0 - $nv_preserves_uv_bits`
- $echo "Your NVs can preserve all $nv_preserves_uv_bits bits of your UVs." 2>&1
+ $echo "Your NVs can preserve all $nv_preserves_uv_bits bits of your UVs." >&4
d_nv_preserves_uv="$define"
;;
-[1-9]*) $echo "Your NVs can preserve only $nv_preserves_uv_bits bits of your UVs." 2>&1
+[1-9]*) $echo "Your NVs can preserve only $nv_preserves_uv_bits bits of your UVs." >&4
d_nv_preserves_uv="$undef" ;;
-*) $echo "Can't figure out how many bits your NVs preserve." 2>&1
+*) $echo "Can't figure out how many bits your NVs preserve." >&4
nv_preserves_uv_bits="0" ;;
esac
$rm_try
-$echo "Checking whether NV 0.0 is all bits zero in memory..." >&4
-: volatile so that the compiler has to store it out to memory.
-if test X"$d_volatile" = X"$define"; then
- volatile=volatile
+$echo "Checking to find the largest integer value your NVs can hold..." >&4
+$cat <<EOP >try.c
+#include <stdio.h>
+
+typedef $nvtype NV;
+
+int
+main() {
+ NV value = 2;
+ int count = 1;
+
+ while(count < 256) {
+ /* volatile so that the compiler has to store it out to memory */
+ volatile NV up = value + 1.0;
+ volatile NV negated = -value;
+ volatile NV down = negated - 1.0;
+ volatile NV got_up = up - value;
+ int up_good = got_up == 1.0;
+ int got_down = down - negated;
+ int down_good = got_down == -1.0;
+
+ if (down_good != up_good) {
+ fprintf(stderr,
+ "Inconsistency - up %d %f; down %d %f; for 2**%d (%.20f)\n",
+ up_good, (double) got_up, down_good, (double) got_down,
+ count, (double) value);
+ return 1;
+ }
+ if (!up_good) {
+ while (1) {
+ if (count > 8) {
+ count -= 8;
+ fputs("256.0", stdout);
+ } else {
+ count--;
+ fputs("2.0", stdout);
+ }
+ if (!count) {
+ puts("");
+ return 0;
+ }
+ fputs("*", stdout);
+ }
+ }
+ value *= 2;
+ ++count;
+ }
+ fprintf(stderr, "Cannot overflow integer range, even at 2**%d (%.20f)\n",
+ count, (double) value);
+ return 1;
+}
+EOP
+set try
+
+nv_overflows_integers_at='0'
+if eval $compile; then
+ xxx="`$run ./try`"
+ case "$?" in
+ 0)
+ case "$xxx" in
+ 2*) cat >&4 <<EOM
+The largest integer your NVs can preserve is equal to $xxx
+EOM
+ nv_overflows_integers_at="$xxx"
+ ;;
+ *) cat >&4 <<EOM
+Cannot determine the largest integer value your NVs can hold, unexpected output
+'$xxx'
+EOM
+ ;;
+ esac
+ ;;
+ *) cat >&4 <<EOM
+Cannot determine the largest integer value your NVs can hold
+EOM
+ ;;
+ esac
fi
+$rm_try
+
+$echo "Checking whether NV 0.0 is all bits zero in memory..." >&4
$cat <<EOP >try.c
#include <stdio.h>
#$i_stdlib I_STDLIB
#ifdef I_STDLIB
#include <stdlib.h>
#endif
-#$i_string I_STRING
-#ifdef I_STRING
-# include <string.h>
-#else
-# include <strings.h>
-#endif
+#include <string.h>
#include <sys/types.h>
#include <signal.h>
#ifdef SIGFPE
-$volatile int bletched = 0;
+/* volatile so that the compiler has to store it out to memory */
+volatile int bletched = 0;
$signal_t blech(int s) { bletched = 1; }
#endif
-int checkit($nvtype d, char *where) {
- unsigned char *p = (char *)&d;
+int checkit($nvtype d, const char *where) {
+ void *v = &d;
+ unsigned char *p = (unsigned char *)v;
unsigned char *end = p + sizeof(d);
int fail = 0;
if (!fail)
return 0;
- p = (char *)&d;
+ p = (unsigned char *)v;
printf("No - %s: 0x", where);
while (p < end)
printf ("%02X", *p++);