summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>2014-08-10 19:46:12 -0400
committerJarkko Hietaniemi <jhi@iki.fi>2014-08-13 22:20:16 -0400
commitdc91db6cfbf31ad1bbc0d43f7c74251f6411d2d2 (patch)
treeeae92263b65fc3449f1529b76b17e2ca1287ca4c
parentf4ef132eeaba0ed558de187afbee10205ae09a38 (diff)
downloadperl-dc91db6cfbf31ad1bbc0d43f7c74251f6411d2d2.tar.gz
Configure scan for the kind of long double we have
(Somewhat like quadkind, but for the format of the long double)
-rwxr-xr-xConfigure86
-rw-r--r--Cross/config.sh-arm-linux1
-rw-r--r--NetWare/config.wc1
-rw-r--r--Porting/Glossary7
-rw-r--r--Porting/config.sh1
-rwxr-xr-xconfig_h.SH21
-rw-r--r--configure.com3
-rw-r--r--plan9/config_sh.sample1
-rw-r--r--symbian/config.sh1
-rw-r--r--uconfig.h19
-rw-r--r--uconfig.sh1
-rw-r--r--uconfig64.sh1
-rw-r--r--win32/config.ce1
-rw-r--r--win32/config.gc1
-rw-r--r--win32/config.vc1
15 files changed, 144 insertions, 2 deletions
diff --git a/Configure b/Configure
index 4453f38e5b..b76458790e 100755
--- a/Configure
+++ b/Configure
@@ -593,6 +593,7 @@ localtime_r_proto=''
d_locconv=''
d_lockf=''
d_longdbl=''
+longdblkind=''
longdblsize=''
d_longlong=''
longlongsize=''
@@ -15958,6 +15959,90 @@ $echo "(IV will be "$ivtype", $ivsize bytes)"
$echo "(UV will be "$uvtype", $uvsize bytes)"
$echo "(NV will be "$nvtype", $nvsize bytes)"
+$echo "Checking the kind of long doubles you have..." >&4
+: volatile so that the compiler has to store it out to memory.
+if test X"$d_volatile" = X"$define"; then
+ volatile=volatile
+fi
+case "$d_longdbl" in
+define)
+$cat <<EOP >try.c
+#$i_float I_FLOAT
+#$i_stdlib I_STDLIB
+#define LONGDBLSIZE $longdblsize
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifdef I_STDLIB
+#include <stdlib.h>
+#endif
+#include <stdio.h>
+static const long double d = -0.1L;
+int main() {
+ unsigned const char* b = (unsigned const char*)(&d);
+#if LDBL_MANT_DIG == 113 && LONGDBLSIZE == 16
+ if (b[0] == 0x9A && b[1] == 0x99 && b[15] == 0xBF) {
+ /* IEEE 754 128-bit little-endian */
+ printf("1\n");
+ exit(0);
+ }
+ if (b[0] == 0xBF && b[14] == 0x99 && b[15] == 0x9A) {
+ /* IEEE 128-bit big-endian, e.g. solaris sparc */
+ printf("2\n");
+ exit(0);
+ }
+#endif
+#if LDBL_MANT_DIG == 64 && (LONGDBLSIZE == 16 || LONGDBLSIZE == 12)
+ if (b[0] == 0xCD && b[9] == 0xBF && b[10] == 0x00) {
+ /* x86 80-bit little-endian, sizeof 12 (ILP32, Solaris x86)
+ * or 16 (LP64, Linux and OS X), 4 or 6 bytes of padding.
+ * Also known as "extended precision". */
+ printf("3\n");
+ exit(0);
+ }
+ if (b[LONGDBLSIZE - 11] == 0x00 && b[LONGDBLSIZE - 10] == 0xBF &&
+ b[LONGDBLSIZE - 1] == 0xCD) {
+ /* is there ever big-endian 80-bit, really? */
+ printf("4\n");
+ exit(0);
+ }
+#endif
+#if LDBL_MANT_DIG == 106 && LONGDBLSIZE == 16
+ /* software "double double", the 106 is 53+53 */
+ if (b[0] == 0xCD && b[7] == 0x3C && b[8] == 0x9A && b[15] == 0xBF) {
+ /* double double 128-bit little-endian */
+ printf("5\n");
+ exit(0);
+ }
+ if (b[0] == 0xBF && b[7] == 0x9A && b[8] == 0x3C && b[15] == 0x9A) {
+ /* double double 128-bit big-endian, e.g. PPC/Power and MIPS:
+ * bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a */
+ printf("6\n");
+ exit(0);
+ }
+#endif
+ printf("-1\n"); /* unknown */
+ exit(0);
+}
+EOP
+set try
+if eval $compile; then
+ longdblkind=`$run ./try`
+else
+ longdblkind=-1
+fi
+;;
+*) longdblkind=0 ;;
+esac
+case "$longdblkind" in
+0) echo "Your long doubles are doubles." >&4 ;;
+1) echo "You have IEEE 754 128-bit little endian long doubles." >&4 ;;
+2) echo "You have IEEE 754 128-bit big endian long doubles." >&4 ;;
+3) echo "You have x86 80-bit little endian long doubles." >& 4 ;;
+*) echo "Cannot figure out your long double." >&4 ;;
+esac
+$rm_try
+
$cat >try.c <<EOCP
#$i_inttypes I_INTTYPES
#ifdef I_INTTYPES
@@ -23727,6 +23812,7 @@ lns='$lns'
localtime_r_proto='$localtime_r_proto'
locincpth='$locincpth'
loclibpth='$loclibpth'
+longdblkind='$longdblkind'
longdblsize='$longdblsize'
longlongsize='$longlongsize'
longsize='$longsize'
diff --git a/Cross/config.sh-arm-linux b/Cross/config.sh-arm-linux
index 7fbaca4f44..e0ba68b2a8 100644
--- a/Cross/config.sh-arm-linux
+++ b/Cross/config.sh-arm-linux
@@ -795,6 +795,7 @@ lns='/bin/ln -s'
localtime_r_proto='0'
locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+longdblkind='0'
longdblsize='8'
longlongsize='8'
longsize='4'
diff --git a/NetWare/config.wc b/NetWare/config.wc
index 9dcb1e48db..54b4c9d453 100644
--- a/NetWare/config.wc
+++ b/NetWare/config.wc
@@ -769,6 +769,7 @@ lns='copy'
localtime_r_proto='0'
locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+longdblkind='3'
longdblsize='10'
longlongsize='8'
longsize='4'
diff --git a/Porting/Glossary b/Porting/Glossary
index 67e87d655a..99cef06a97 100644
--- a/Porting/Glossary
+++ b/Porting/Glossary
@@ -3796,6 +3796,13 @@ loclibpth (libpth.U):
libraries. It is prepended to libpth, and is intended to be easily
set from the command line.
+longdblkind (longdblkind.U):
+ This variable, if defined, encodes the type of a long double:
+ 0 = double, 1 = IEEE 754 128-bit big little endian,
+ 2 = IEEE 754 128-bit big big endian, 3 = x86 80-bit little endian,
+ 4 = x86 80-bit big endian, 5 = double-double 128-bit little endian,
+ 6 = double-double 128-bit big endian, -1 = unknown format.
+
longdblsize (d_longdbl.U):
This variable contains the value of the LONG_DOUBLESIZE symbol, which
indicates to the C program how many bytes there are in a long double,
diff --git a/Porting/config.sh b/Porting/config.sh
index 29d14f326c..1c30d0862b 100644
--- a/Porting/config.sh
+++ b/Porting/config.sh
@@ -813,6 +813,7 @@ lns='/usr/bin/ln -s'
localtime_r_proto='0'
locincpth='/pro/local/include'
loclibpth='/pro/local/lib'
+longdblkind='3'
longdblsize='12'
longlongsize='8'
longsize='4'
diff --git a/config_h.SH b/config_h.SH
index c565a6c1f6..ff7308e860 100755
--- a/config_h.SH
+++ b/config_h.SH
@@ -1935,9 +1935,30 @@ sed <<!GROK!THIS! >$CONFIG_H -e 's!^#undef\(.*/\)\*!/\*#define\1 \*!' -e 's!^#un
* C preprocessor can make decisions based on it. It is only
* defined if the system supports long doubles.
*/
+/* LONG_DOUBLEKIND:
+ * LONG_DOUBLEKIND will be one of
+ * LONG_DOUBLE_IS_DOUBLE
+ * LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+ * LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+ * LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
+ * LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
+ * LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
+ * LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+ * LONG_DOUBLE_IS_UNKNOWN_FORMAT
+ * It is only defined if the system supports long doubles.
+ */
#$d_longdbl HAS_LONG_DOUBLE /**/
#ifdef HAS_LONG_DOUBLE
#define LONG_DOUBLESIZE $longdblsize /**/
+#define LONG_DOUBLEKIND $longdblkind /**/
+#define LONG_DOUBLE_IS_DOUBLE 0
+#define LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN 1
+#define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN 2
+#define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN 3
+#define LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN 4
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN 5
+#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN 6
+#define LONG_DOUBLE_IS_UNKNOWN_FORMAT -1
#endif
/* HAS_LONG_LONG:
diff --git a/configure.com b/configure.com
index abea303ff6..a147e5d7ae 100644
--- a/configure.com
+++ b/configure.com
@@ -3586,6 +3586,7 @@ $ GOSUB link_ok
$ IF link_status .NE. good_link
$ THEN
$ longdblsize="0"
+$ longdblkind="-1"
$ d_longdbl="undef"
$ echo "You do not have long double."
$ ELSE
@@ -3593,6 +3594,7 @@ $ echo "You have long double."
$ echo4 "Checking to see how big your long doubles are..."
$ GOSUB just_mcr_it
$ longdblsize = tmp
+$ longdblkind = "1"
$ d_longdbl = "define"
$ echo "Your long doubles are ''longdblsize' bytes long."
$ ENDIF
@@ -6507,6 +6509,7 @@ $ WC "libs='" + libs + "'"
$ WC "libswanted='" + "'"
$ WC "libswanted_uselargefiles='" + "'"
$ WC "longdblsize='" + longdblsize + "'"
+$ WC "longdblkind='" + longdblkind + "'"
$ WC "longlongsize='" + longlongsize + "'"
$ WC "longsize='" + longsize + "'"
$ IF uselargefiles .OR. uselargefiles .EQS. "define"
diff --git a/plan9/config_sh.sample b/plan9/config_sh.sample
index 1b45f15977..c8ae07a32e 100644
--- a/plan9/config_sh.sample
+++ b/plan9/config_sh.sample
@@ -777,6 +777,7 @@ lns='/bin/ln -s'
localtime_r_proto='0'
locincpth=''
loclibpth=''
+longdblkind='0'
longdblsize='8'
longlongsize='8'
longsize='4'
diff --git a/symbian/config.sh b/symbian/config.sh
index d86c71ed61..fa1249324b 100644
--- a/symbian/config.sh
+++ b/symbian/config.sh
@@ -672,6 +672,7 @@ libc='stdlib'
libm_lib_version='0'
libperl='libperl.a'
localtime_r_proto='0'
+longdblkind=0
longdblsize=8
longlongsize=8
longsize='4'
diff --git a/uconfig.h b/uconfig.h
index b5648d49bb..ba38e02576 100644
--- a/uconfig.h
+++ b/uconfig.h
@@ -1900,9 +1900,24 @@
* C preprocessor can make decisions based on it. It is only
* defined if the system supports long doubles.
*/
+/* LONG_DOUBLEKIND:
+ * LONG_DOUBLEKIND will be one of
+ * LONG_DOUBLE_IS_DOUBLE
+ * LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+ * LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+ * LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
+ * LONG_DOUBLE_IS_UNKNOWN_FORMAT
+ * It is only defined if the system supports long doubles.
+ */
/*#define HAS_LONG_DOUBLE / **/
#ifdef HAS_LONG_DOUBLE
#define LONG_DOUBLESIZE 8 /**/
+#define LONG_DOUBLEKIND 0 /**/
+#define LONG_DOUBLE_IS_DOUBLE 0
+#define LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN 1
+#define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN 2
+#define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN 3
+#define LONG_DOUBLE_IS_UNKNOWN_FORMAT -1
#endif
/* HAS_LONG_LONG:
@@ -4742,6 +4757,6 @@
#endif
/* Generated from:
- * 727eb338c23fdd320f556ca32fd7eb5473f68b6ce74db8cec7d83399a2621346 config_h.SH
- * 4b709c0b049c660c04c0932eaa8481f9ca6fdc697ec4ffaa86b7bef21ee886a8 uconfig.sh
+ * c4bf570c111b3c66095fb11639d17a0af192b7c0a37356b5aee77aba07159a26 config_h.SH
+ * bcda3e57ce7783c031fe7cc8670ceac0dd6344d01f9a36ede1b34c48cb7d4f21 uconfig.sh
* ex: set ro: */
diff --git a/uconfig.sh b/uconfig.sh
index e8df3c2ea0..e840f3ea77 100644
--- a/uconfig.sh
+++ b/uconfig.sh
@@ -648,6 +648,7 @@ ivtype='long'
ld_can_script='define'
lib_ext='.a'
localtime_r_proto='0'
+longdblkind=0
longdblsize=8
longlongsize=8
longsize='4'
diff --git a/uconfig64.sh b/uconfig64.sh
index a4adccb3ec..600962b176 100644
--- a/uconfig64.sh
+++ b/uconfig64.sh
@@ -648,6 +648,7 @@ ivsize='8'
ivtype='long'
lib_ext='.a'
localtime_r_proto='0'
+longdblkind=0
longdblsize=8
longlongsize=8
longsize='8'
diff --git a/win32/config.ce b/win32/config.ce
index 0601162d92..aa8f756545 100644
--- a/win32/config.ce
+++ b/win32/config.ce
@@ -761,6 +761,7 @@ lns='copy'
localtime_r_proto='0'
locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+longdblkind='3'
longdblsize='10'
longlongsize='8'
longsize='4'
diff --git a/win32/config.gc b/win32/config.gc
index 11b490e42f..2cf0fb9be0 100644
--- a/win32/config.gc
+++ b/win32/config.gc
@@ -788,6 +788,7 @@ lns='copy'
localtime_r_proto='0'
locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+longdblkind='3'
longdblsize='12'
longlongsize='8'
longsize='4'
diff --git a/win32/config.vc b/win32/config.vc
index d4b0b83877..8ebdb617cf 100644
--- a/win32/config.vc
+++ b/win32/config.vc
@@ -787,6 +787,7 @@ lns='copy'
localtime_r_proto='0'
locincpth='/usr/local/include /opt/local/include /usr/gnu/include /opt/gnu/include /usr/GNU/include /opt/GNU/include'
loclibpth='/usr/local/lib /opt/local/lib /usr/gnu/lib /opt/gnu/lib /usr/GNU/lib /opt/GNU/lib'
+longdblkind='0'
longdblsize='8'
longlongsize='8'
longsize='4'