This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
6cd9f5f51ca006a47374061ee6ed03036b07de28
[metaconfig.git] / U / modified / d_longdbl.U
1 ?RCS: $Id: d_longdbl.U,v $
2 ?RCS:
3 ?RCS: Copyright (c) 1998 Andy Dougherty
4 ?RCS:
5 ?RCS: You may distribute under the terms of either the GNU General Public
6 ?RCS: License or the Artistic License, as specified in the README file.
7 ?RCS:
8 ?RCS: $Log: d_longdbl.U,v $
9 ?RCS:
10 ?MAKE:d_longdbl longdblsize d_ldexpl longdblkind: Compile Setvar Myread \
11         Inlibc run echo cat rm_try test doublesize i_stdlib i_float
12 ?MAKE:  -pick add $@ %<
13 ?S:d_longdbl:
14 ?S:     This variable conditionally defines HAS_LONG_DOUBLE if
15 ?S:     the long double type is supported.
16 ?S:.
17 ?S:d_ldexpl:
18 ?S:     This variable conditionally defines the HAS_LDEXPL symbol, which
19 ?S:     indicates to the C program that the ldexpl() routine is available.
20 ?S:.
21 ?S:longdblsize:
22 ?S:     This variable contains the value of the LONG_DOUBLESIZE symbol, which
23 ?S:     indicates to the C program how many bytes there are in a long double,
24 ?S:     if this system supports long doubles.
25 ?S:.
26 ?S:longdblkind:
27 ?S:     This variable, if defined, encodes the type of a long double:
28 ?S:     0 = double, 1 = IEEE 754 128-bit big little endian,
29 ?S:     2 = IEEE 754 128-bit big big endian, 3 = x86 80-bit little endian,
30 ?S:     4 = x86 80-bit big endian, 5 = double-double 128-bit little endian,
31 ?S:     6 = double-double 128-bit big endian, -1 = unknown format.
32 ?S:.
33 ?C:HAS_LONG_DOUBLE:
34 ?C:     This symbol will be defined if the C compiler supports long
35 ?C:     doubles.
36 ?C:.
37 ?C:LONG_DOUBLESIZE:
38 ?C:     This symbol contains the size of a long double, so that the
39 ?C:     C preprocessor can make decisions based on it.  It is only
40 ?C:     defined if the system supports long doubles.
41 ?C:.
42 ?C:HAS_LDEXPL:
43 ?C:     This symbol, if defined, indicates that the ldexpl routine is
44 ?C:     available to shift a long double floating-point number
45 ?C:     by an integral power of 2.
46 ?C:.
47 ?C:LONG_DOUBLEKIND:
48 ?C:     LONG_DOUBLEKIND will be one of
49 ?C:     LONG_DOUBLE_IS_DOUBLE
50 ?C:     LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
51 ?C:     LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
52 ?C:     LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
53 ?C:     LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
54 ?C:     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
55 ?C:     LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
56 ?C:     LONG_DOUBLE_IS_UNKNOWN_FORMAT
57 ?C:     It is only defined if the system supports long doubles.
58 ?C:.
59 ?H:#$d_ldexpl  HAS_LDEXPL               /**/
60 ?H:#$d_longdbl HAS_LONG_DOUBLE          /**/
61 ?H:?LONG_DOUBLESIZE:#ifdef HAS_LONG_DOUBLE
62 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLESIZE $longdblsize                /**/
63 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLEKIND $longdblkind                /**/
64 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_DOUBLE                               0
65 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN       1
66 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN  2
67 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN             3
68 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN                4
69 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN   5
70 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN      6
71 ?H:?LONG_DOUBLESIZE:#define LONG_DOUBLE_IS_UNKNOWN_FORMAT                       -1
72 ?H:?LONG_DOUBLESIZE:#endif
73 ?H:.
74 ?F:!try
75 ?LINT:known LONG_DOUBLE_IS_DOUBLE LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
76 ?LINT:known LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN
77 ?LINT:known LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
78 ?LINT:known LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN LONG_DOUBLE_IS_UNKNOWN_FORMAT
79 ?LINT:set d_longdbl
80 ?LINT:set d_ldexpl
81 : check for long doubles
82 echo " "
83 echo "Checking to see if you have long double..." >&4
84 echo 'int main() { long double x = 7.0; }' > try.c
85 set try
86 if eval $compile; then
87         val="$define"
88         echo "You have long double."
89 else
90         val="$undef"
91         echo "You do not have long double."
92 fi
93 $rm_try
94 set d_longdbl
95 eval $setvar
96
97 : see if ldexpl exists
98 set ldexpl d_ldexpl
99 eval $inlibc
100
101 @if LONG_DOUBLESIZE || longdblsize
102 : check for length of long double
103 ?X:  Check only if d_longdbl and if longdblsize is not already set.
104 case "${d_longdbl}${longdblsize}" in
105 $define)
106         echo " "
107         echo "Checking to see how big your long doubles are..." >&4
108         $cat >try.c <<'EOCP'
109 #include <stdio.h>
110 int main()
111 {
112         printf("%d\n", sizeof(long double));
113 }
114 EOCP
115         set try
116 ?X:     Don't use compile_ok because some compilers warn you that they have
117 ?X:     'long double' as just 'double'.
118         set try
119         if eval $compile; then
120                 longdblsize=`$run ./try`
121                 echo "Your long doubles are $longdblsize bytes long."
122         else
123                 dflt='8'
124                 echo " "
125                 echo "(I can't seem to compile the test program.  Guessing...)" >&4
126                 rp="What is the size of a long double (in bytes)?"
127                 . ./myread
128                 longdblsize="$ans"
129         fi
130         if $test "X$doublesize" = "X$longdblsize"; then
131                 echo "That isn't any different from an ordinary double."
132                 echo "I'll keep your setting anyway, but you may see some"
133                 echo "harmless compilation warnings."
134         fi
135         ;;
136 esac
137 $rm_try
138 @end
139
140 $echo "Checking the kind of long doubles you have..." >&4
141 case "$d_longdbl" in
142 define)
143 $cat <<EOP >try.c
144 #$i_float I_FLOAT
145 #$i_stdlib I_STDLIB
146 #define LONGDBLSIZE $longdblsize
147 #define DOUBLESIZE $doublesize
148 #ifdef I_FLOAT
149 #include <float.h>
150 #endif
151 #ifdef I_STDLIB
152 #include <stdlib.h>
153 #endif
154 #include <stdio.h>
155 static const long double d = -0.1L;
156 int main() {
157   unsigned const char* b = (unsigned const char*)(&d);
158 #if DOUBLESIZE == LONGDBLSIZE
159   printf("0\n"); /* if it floats like double */
160   exit(0);
161 #endif
162 #if (LDBL_MANT_DIG == 113 || FLT128_MANT_DIG == 113) && LONGDBLSIZE == 16
163   if (b[0] == 0x9A && b[1] == 0x99 && b[15] == 0xBF) {
164     /* IEEE 754 128-bit little-endian */
165     printf("1\n");
166     exit(0);
167   }
168   if (b[0] == 0xBF && b[14] == 0x99 && b[15] == 0x9A) {
169     /* IEEE 128-bit big-endian, e.g. solaris sparc */
170     printf("2\n");
171     exit(0);
172   }
173 #endif
174 /* For alignment 32-bit platforms have the 80 bits in 12 bytes,
175  * while 64-bits platforms have it in 16 bytes. */
176 #if LDBL_MANT_DIG == 64 && (LONGDBLSIZE == 16 || LONGDBLSIZE == 12)
177   if (b[0] == 0xCD && b[9] == 0xBF && b[10] == 0x00) {
178     /* x86 80-bit little-endian, sizeof 12 (ILP32, Solaris x86)
179      * or 16 (LP64, Linux and OS X), 4 or 6 bytes of padding.
180      * Also known as "extended precision". */
181     printf("3\n");
182     exit(0);
183   }
184   if (b[0] == 0xBF && b[9] == 0xCD && b[10] == 0x00) {
185     /* is there ever big-endian 80-bit, really? */
186     printf("4\n");
187     exit(0);
188   }
189 #endif
190 #if (LDBL_MANT_DIG == 106 || LDBL_MANT_DIG == 107) && LONGDBLSIZE == 16
191   /* software "double double", the 106 is 53+53.
192    * but irix thinks it is 107. */
193   if (b[0] == 0x9A && b[7] == 0x3C && b[8] == 0x9A && b[15] == 0xBF) {
194     /* double double 128-bit little-endian,
195      * 9a 99 99 99 99 99 59 3c 9a 99 99 99 99 99 b9 bf */
196     printf("5\n");
197     exit(0);
198   }
199   if (b[0] == 0xBF && b[7] == 0x9A && b[8] == 0x3C && b[15] == 0x9A) {
200     /* double double 128-bit big-endian, e.g. PPC/Power and MIPS:
201      * bf b9 99 99 99 99 99 9a 3c 59 99 99 99 99 99 9a */
202     printf("6\n");
203     exit(0);
204   }
205 #endif
206   printf("-1\n"); /* unknown */
207   exit(0);
208 }
209 EOP
210 set try
211 if eval $compile; then
212     longdblkind=`$run ./try`
213 else
214     longdblkind=-1
215 fi
216 ;;
217 *) longdblkind=0 ;;
218 esac
219 case "$longdblkind" in
220 0) echo "Your long doubles are doubles." >&4 ;;
221 1) echo "You have IEEE 754 128-bit little endian long doubles." >&4 ;;
222 2) echo "You have IEEE 754 128-bit big endian long doubles." >&4 ;;
223 3) echo "You have x86 80-bit little endian long doubles." >& 4 ;;
224 4) echo "You have x86 80-bit big endian long doubles." >& 4 ;;
225 5) echo "You have 128-bit little-endian double-double long doubles." >& 4 ;;
226 6) echo "You have 128-bit big-endian double-double long doubles." >& 4 ;;
227 *) echo "Cannot figure out your long double." >&4 ;;
228 esac
229 $rm_try
230