This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Configure: add note about nvsize sometimes lying
[metaconfig.git] / U / perl / perlxv.U
CommitLineData
6cadf241 1?RCS: $Id: perlxv.U,v 1.1 2000/08/31 17:53:56 jhi Exp jhi $
b4d5f732
JH
2?RCS:
3?RCS: Copyright (c) 1999 Jarkko Hietaniemi
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?MAKE:ivtype uvtype nvtype ivsize uvsize nvsize \
074df96b
MB
9 i8type u8type i16type u16type i32type u32type i64type u64type \
10 i8size u8size i16size u16size i32size u32size i64size u64size \
11 d_nv_preserves_uv nv_preserves_uv_bits nv_overflows_integers_at \
12 d_nv_zero_is_allbits_zero: \
63a4f1f4
MBT
13 echo rm_try use64bitint d_quad quadtype uquadtype usequadmath \
14 d_longdbl uselongdouble longdblsize doublesize i_quadmath \
15 shortsize intsize longsize i_stdlib i_string libs gccversion \
0f00356b 16 cat Compile i_inttypes test d_volatile signal_t run
b4d5f732
JH
17?MAKE: -pick add $@ %<
18?S:ivtype:
19?S: This variable contains the C type used for Perl's IV.
20?S:.
21?S:uvtype:
22?S: This variable contains the C type used for Perl's UV.
23?S:.
24?S:nvtype:
25?S: This variable contains the C type used for Perl's NV.
26?S:.
27?S:i8type:
28?S: This variable contains the C type used for Perl's I8.
29?S:.
30?S:u8type:
31?S: This variable contains the C type used for Perl's U8.
32?S:.
33?S:i16type:
34?S: This variable contains the C type used for Perl's I16.
35?S:.
36?S:u16type:
37?S: This variable contains the C type used for Perl's U16.
38?S:.
39?S:i32type:
40?S: This variable contains the C type used for Perl's I32.
41?S:.
42?S:u32type:
43?S: This variable contains the C type used for Perl's U32.
44?S:.
45?S:i64type:
46?S: This variable contains the C type used for Perl's I64.
47?S:.
48?S:u64type:
49?S: This variable contains the C type used for Perl's U64.
50?S:.
51?S:ivsize:
52?S: This variable is the size of an IV in bytes.
53?S:.
54?S:uvsize:
55?S: This variable is the size of a UV in bytes.
56?S:.
57?S:i8size:
58?S: This variable is the size of an I8 in bytes.
59?S:.
60?S:u8size:
61?S: This variable is the size of an U8 in bytes.
62?S:.
63?S:i16size:
64?S: This variable is the size of an I16 in bytes.
65?S:.
66?S:u16size:
67?S: This variable is the size of an U16 in bytes.
68?S:.
69?S:i32size:
70?S: This variable is the size of an I32 in bytes.
71?S:.
72?S:u32size:
73?S: This variable is the size of an U32 in bytes.
74?S:.
75?S:i64size:
76?S: This variable is the size of an I64 in bytes.
77?S:.
78?S:u64size:
79?S: This variable is the size of an U64 in bytes.
80?S:.
81?S:nvsize:
c4037aaf
MBT
82?S: This variable is the size of a Perl NV in bytes.
83?S: Note that some floating point formats have unused bytes.
b4d5f732 84?S:.
ebebf7f4 85?S:d_nv_preserves_uv:
d7ef793b
JH
86?S: This variable indicates whether a variable of type nvtype
87?S: can preserve all the bits a variable of type uvtype.
88?S:.
2c06d0fa 89?S:nv_preserves_uv_bits:
31ebece7
JH
90?S: This variable indicates how many of bits type uvtype
91?S: a variable nvtype can preserve.
92?S:.
074df96b
MB
93?S:nv_overflows_integers_at:
94?S: This variable gives the largest integer value that NVs can hold
95?S: as a constant floating point expression.
96?S: If it could not be determined, it holds the value 0.
97?S:.
913e5e82
MB
98?S:d_nv_zero_is_allbits_zero:
99?S: This variable indicates whether a variable of type nvtype
100?S: stores 0.0 in memory as all bits zero.
101?S:.
b4d5f732
JH
102?C:IVTYPE:
103?C: This symbol defines the C type used for Perl's IV.
104?C:.
105?C:UVTYPE:
106?C: This symbol defines the C type used for Perl's UV.
107?C:.
108?C:I8TYPE:
109?C: This symbol defines the C type used for Perl's I8.
110?C:.
111?C:U8TYPE:
112?C: This symbol defines the C type used for Perl's U8.
113?C:.
114?C:I16TYPE:
115?C: This symbol defines the C type used for Perl's I16.
116?C:.
117?C:U16TYPE:
118?C: This symbol defines the C type used for Perl's U16.
119?C:.
120?C:I32TYPE:
121?C: This symbol defines the C type used for Perl's I32.
122?C:.
123?C:U32TYPE:
124?C: This symbol defines the C type used for Perl's U32.
125?C:.
126?C:I64TYPE:
127?C: This symbol defines the C type used for Perl's I64.
128?C:.
129?C:U64TYPE:
130?C: This symbol defines the C type used for Perl's U64.
131?C:.
132?C:NVTYPE:
133?C: This symbol defines the C type used for Perl's NV.
134?C:.
135?C:IVSIZE:
136?C: This symbol contains the sizeof(IV).
137?C:.
138?C:UVSIZE:
139?C: This symbol contains the sizeof(UV).
140?C:.
141?C:I8SIZE:
142?C: This symbol contains the sizeof(I8).
143?C:.
144?C:U8SIZE:
145?C: This symbol contains the sizeof(U8).
146?C:.
147?C:I16SIZE:
148?C: This symbol contains the sizeof(I16).
149?C:.
150?C:U16SIZE:
151?C: This symbol contains the sizeof(U16).
152?C:.
153?C:I32SIZE:
154?C: This symbol contains the sizeof(I32).
155?C:.
156?C:U32SIZE:
157?C: This symbol contains the sizeof(U32).
158?C:.
159?C:I64SIZE:
160?C: This symbol contains the sizeof(I64).
161?C:.
162?C:U64SIZE:
163?C: This symbol contains the sizeof(U64).
164?C:.
165?C:NVSIZE:
166?C: This symbol contains the sizeof(NV).
c4037aaf
MBT
167?C: Note that some floating point formats have unused bytes.
168?C: The most notable example is the x86* 80-bit extended precision
169?C: which comes in byte sizes of 12 and 16 (for 32 and 64 bit
170?C: platforms, respectively), but which only uses 10 bytes.
171?C: Perl compiled with -Duselongdouble on x86* is like this.
b4d5f732 172?C:.
d7ef793b
JH
173?C:NV_PRESERVES_UV:
174?C: This symbol, if defined, indicates that a variable of type NVTYPE
31ebece7
JH
175?C: can preserve all the bits of a variable of type UVTYPE.
176?C:.
846df602 177?C:NV_PRESERVES_UV_BITS:
31ebece7
JH
178?C: This symbol contains the number of bits a variable of type NVTYPE
179?C: can preserve of a variable of type UVTYPE.
d7ef793b 180?C:.
074df96b
MB
181?C:NV_OVERFLOWS_INTEGERS_AT:
182?C: This symbol gives the largest integer value that NVs can hold. This
183?C: value + 1.0 cannot be stored accurately. It is expressed as constant
04c34a22 184?C: floating point expression to reduce the chance of decimal/binary
074df96b
MB
185?C: conversion issues. If it can not be determined, the value 0 is given.
186?C:.
913e5e82
MB
187?C:NV_ZERO_IS_ALLBITS_ZERO:
188?C: This symbol, if defined, indicates that a variable of type NVTYPE
189?C: stores 0.0 in memory as all bits zero.
190?C:.
b4d5f732
JH
191?H:#define IVTYPE $ivtype /**/
192?H:#define UVTYPE $uvtype /**/
193?H:#define I8TYPE $i8type /**/
194?H:#define U8TYPE $u8type /**/
195?H:#define I16TYPE $i16type /**/
196?H:#define U16TYPE $u16type /**/
197?H:#define I32TYPE $i32type /**/
198?H:#define U32TYPE $u32type /**/
500277eb 199?H:?%<:#ifdef HAS_QUAD
b4d5f732
JH
200?H:?%<:#define I64TYPE $i64type /**/
201?H:?%<:#define U64TYPE $u64type /**/
202?H:?%<:#endif
203?H:#define NVTYPE $nvtype /**/
204?H:#define IVSIZE $ivsize /**/
205?H:#define UVSIZE $uvsize /**/
206?H:#define I8SIZE $i8size /**/
207?H:#define U8SIZE $u8size /**/
208?H:#define I16SIZE $i16size /**/
209?H:#define U16SIZE $u16size /**/
210?H:#define I32SIZE $i32size /**/
211?H:#define U32SIZE $u32size /**/
500277eb 212?H:?%<:#ifdef HAS_QUAD
b4d5f732
JH
213?H:?%<:#define I64SIZE $i64size /**/
214?H:?%<:#define U64SIZE $u64size /**/
215?H:?%<:#endif
216?H:#define NVSIZE $nvsize /**/
ebebf7f4 217?H:#$d_nv_preserves_uv NV_PRESERVES_UV
2c06d0fa 218?H:#define NV_PRESERVES_UV_BITS $nv_preserves_uv_bits
074df96b 219?H:#define NV_OVERFLOWS_INTEGERS_AT $nv_overflows_integers_at
913e5e82 220?H:#$d_nv_zero_is_allbits_zero NV_ZERO_IS_ALLBITS_ZERO
6b4048d7
JH
221?H:?%<:#if UVSIZE == 8
222?H:?%<:# ifdef BYTEORDER
223?H:?%<:# if BYTEORDER == 0x1234
224?H:?%<:# undef BYTEORDER
225?H:?%<:# define BYTEORDER 0x12345678
226?H:?%<:# else
227?H:?%<:# if BYTEORDER == 0x4321
228?H:?%<:# undef BYTEORDER
229?H:?%<:# define BYTEORDER 0x87654321
230?H:?%<:# endif
231?H:?%<:# endif
232?H:?%<:# endif
233?H:?%<:#endif
b4d5f732 234?H:.
8c100f95 235?T:volatile
913e5e82
MB
236?T:xxx
237?T:d
0065f4af
MB
238?F:!try
239: Check basic sizes
b4d5f732
JH
240echo " "
241$echo "Choosing the C types to be used for Perl's internal types..." >&4
242
33b2427b 243case "$use64bitint:$d_quad:$quadtype" in
500277eb 244define:define:?*)
b4d5f732
JH
245 ivtype="$quadtype"
246 uvtype="$uquadtype"
247 ivsize=8
248 uvsize=8
249 ;;
250*) ivtype="long"
251 uvtype="unsigned long"
252 ivsize=$longsize
253 uvsize=$longsize
254 ;;
255esac
256
257case "$uselongdouble:$d_longdbl" in
258define:define)
259 nvtype="long double"
260 nvsize=$longdblsize
261 ;;
262*) nvtype=double
263 nvsize=$doublesize
264 ;;
265esac
266
63a4f1f4
MBT
267case "$usequadmath:$i_quadmath" in
268define:define)
269 nvtype="__float128"
270 nvsize=16
271 case "$libs" in
272 *quadmath*) ;;
273 *) $cat <<EOM >&4
274
275*** You requested the use of the quadmath library, but you
276*** do not seem to have the quadmath library installed.
277*** Cannot continue, aborting.
278EOM
279 exit 1
280 ;;
281 esac
282 ;;
283define:*) $cat <<EOM >&4
284
285*** You requested the use of the quadmath library, but you
286*** do not seem to have the required header, <quadmath.h>.
287EOM
288 case "$gccversion" in
289 [23].*|4.[0-5]*)
290 $cat <<EOM >&4
291*** Your gcc looks a bit old:
292*** $gccversion
293EOM
294 ;;
295 '')
296 $cat <<EOM >&4
297*** You are not running a gcc.
298EOM
299 ;;
300 esac
301 $cat <<EOM >&4
302*** For the quadmath library you need at least gcc 4.6.
303*** Cannot continue, aborting.
304EOM
305 exit 1
306 ;;
307esac
308
d7ef793b
JH
309$echo "(IV will be "$ivtype", $ivsize bytes)"
310$echo "(UV will be "$uvtype", $uvsize bytes)"
311$echo "(NV will be "$nvtype", $nvsize bytes)"
b4d5f732
JH
312
313$cat >try.c <<EOCP
314#$i_inttypes I_INTTYPES
315#ifdef I_INTTYPES
316#include <inttypes.h>
317#endif
318#include <stdio.h>
319int main() {
320#ifdef INT8
321 int8_t i = INT8_MAX;
322 uint8_t u = UINT8_MAX;
323 printf("int8_t\n");
324#endif
325#ifdef INT16
326 int16_t i = INT16_MAX;
9691dd35 327 uint16_t u = UINT16_MAX;
b4d5f732
JH
328 printf("int16_t\n");
329#endif
330#ifdef INT32
331 int32_t i = INT32_MAX;
332 uint32_t u = UINT32_MAX;
333 printf("int32_t\n");
334#endif
b4d5f732
JH
335}
336EOCP
c9f0ccae 337
a12a5d34 338i8type="signed char"
5107cfb0
MB
339u8type="unsigned char"
340i8size=1
341u8size=1
c9f0ccae
JH
342
343case "$i16type" in
344'') case "$shortsize" in
345 2) i16type=short
346 u16type="unsigned short"
347 i16size=$shortsize
348 u16size=$shortsize
b4d5f732
JH
349 ;;
350 esac
c9f0ccae
JH
351 ;;
352esac
b4d5f732 353case "$i16type" in
c9f0ccae
JH
354'') set try -DINT16
355 if eval $compile; then
0f00356b 356 case "`$run ./try`" in
c9f0ccae
JH
357 int16_t)
358 i16type=int16_t
359 u16type=uint16_t
360 i16size=2
361 u16size=2
362 ;;
363 esac
364 fi
b4d5f732
JH
365 ;;
366esac
c9f0ccae
JH
367case "$i16type" in
368'') if $test $shortsize -ge 2; then
369 i16type=short
370 u16type="unsigned short"
371 i16size=$shortsize
372 u16size=$shortsize
373 fi
374 ;;
375esac
376
b4d5f732
JH
377case "$i32type" in
378'') case "$longsize" in
379 4) i32type=long
380 u32type="unsigned long"
c9f0ccae 381 i32size=$longsize
b4d5f732
JH
382 u32size=$longsize
383 ;;
384 *) case "$intsize" in
385 4) i32type=int
386 u32type="unsigned int"
387 i32size=$intsize
388 u32size=$intsize
389 ;;
390 esac
391 ;;
392 esac
393 ;;
394esac
c9f0ccae
JH
395case "$i32type" in
396'') set try -DINT32
397 if eval $compile; then
0f00356b 398 case "`$run ./try`" in
c9f0ccae
JH
399 int32_t)
400 i32type=int32_t
401 u32type=uint32_t
402 i32size=4
403 u32size=4
404 ;;
405 esac
406 fi
407 ;;
408esac
409case "$i32type" in
410'') if $test $intsize -ge 4; then
411 i32type=int
412 u32type="unsigned int"
413 i32size=$intsize
414 u32size=$intsize
415 fi
416 ;;
417esac
418
b4d5f732 419case "$i64type" in
500277eb
JH
420'') case "$d_quad:$quadtype" in
421 define:?*)
422 i64type="$quadtype"
b4d5f732
JH
423 u64type="$uquadtype"
424 i64size=8
425 u64size=8
426 ;;
427 esac
428 ;;
429esac
430
8c100f95
NC
431$echo "Checking how many bits of your UVs your NVs can preserve..." >&4
432: volatile so that the compiler has to store it out to memory.
433if test X"$d_volatile" = X"$define"; then
434 volatile=volatile
435fi
d7ef793b
JH
436$cat <<EOP >try.c
437#include <stdio.h>
1273bb5e
JH
438#$i_stdlib I_STDLIB
439#ifdef I_STDLIB
440#include <stdlib.h>
441#endif
8c100f95
NC
442#include <sys/types.h>
443#include <signal.h>
444#ifdef SIGFPE
445$volatile int bletched = 0;
dc952a08 446$signal_t blech(int s) { bletched = 1; }
8c100f95 447#endif
31ebece7
JH
448int main() {
449 $uvtype u = 0;
8c100f95 450 $nvtype d;
31ebece7
JH
451 int n = 8 * $uvsize;
452 int i;
8c100f95
NC
453#ifdef SIGFPE
454 signal(SIGFPE, blech);
455#endif
456
31ebece7
JH
457 for (i = 0; i < n; i++) {
458 u = u << 1 | ($uvtype)1;
8c100f95
NC
459 d = ($nvtype)u;
460 if (($uvtype)d != u)
461 break;
462 if (d <= 0)
463 break;
464 d = ($nvtype)(u - 1);
465 if (($uvtype)d != (u - 1))
31ebece7 466 break;
8c100f95 467#ifdef SIGFPE
a0115d2f 468 if (bletched)
8c100f95
NC
469 break;
470#endif
31ebece7 471 }
74b7c8a4 472 printf("%d\n", ((i == n) ? -n : i));
31ebece7
JH
473 exit(0);
474}
475EOP
8c100f95
NC
476set try
477
478d_nv_preserves_uv="$undef"
479if eval $compile; then
2c06d0fa 480 nv_preserves_uv_bits="`$run ./try`"
8c100f95 481fi
2c06d0fa 482case "$nv_preserves_uv_bits" in
2cb64bf6 483\-[1-9]*)
2c06d0fa
JH
484 nv_preserves_uv_bits=`expr 0 - $nv_preserves_uv_bits`
485 $echo "Your NVs can preserve all $nv_preserves_uv_bits bits of your UVs." 2>&1
8c100f95 486 d_nv_preserves_uv="$define"
31ebece7 487 ;;
2c06d0fa 488[1-9]*) $echo "Your NVs can preserve only $nv_preserves_uv_bits bits of your UVs." 2>&1
8c100f95
NC
489 d_nv_preserves_uv="$undef" ;;
490*) $echo "Can't figure out how many bits your NVs preserve." 2>&1
cfa76520 491 nv_preserves_uv_bits="0" ;;
31ebece7 492esac
2cb64bf6 493$rm_try
8c100f95 494
074df96b
MB
495$echo "Checking to find the largest integer value your NVs can hold..." >&4
496: volatile so that the compiler has to store it out to memory.
497if test X"$d_volatile" = X"$define"; then
498 volatile=volatile
499fi
500$cat <<EOP >try.c
501#include <stdio.h>
502
503typedef $nvtype NV;
504
505int
506main() {
507 NV value = 2;
508 int count = 1;
509
510 while(count < 256) {
511 $volatile NV up = value + 1.0;
512 $volatile NV negated = -value;
513 $volatile NV down = negated - 1.0;
514 $volatile NV got_up = up - value;
515 int up_good = got_up == 1.0;
516 int got_down = down - negated;
517 int down_good = got_down == -1.0;
518
519 if (down_good != up_good) {
520 fprintf(stderr,
521 "Inconsistency - up %d %f; down %d %f; for 2**%d (%.20f)\n",
522 up_good, (double) got_up, down_good, (double) got_down,
523 count, (double) value);
524 return 1;
525 }
526 if (!up_good) {
527 while (1) {
528 if (count > 8) {
529 count -= 8;
530 fputs("256.0", stdout);
531 } else {
532 count--;
533 fputs("2.0", stdout);
534 }
535 if (!count) {
536 puts("");
537 return 0;
538 }
539 fputs("*", stdout);
540 }
541 }
542 value *= 2;
543 ++count;
544 }
545 fprintf(stderr, "Cannot overflow integer range, even at 2**%d (%.20f)\n",
546 count, (double) value);
547 return 1;
548}
549EOP
550set try
551
552nv_overflows_integers_at='0'
553if eval $compile; then
554 xxx="`$run ./try`"
555 case "$?" in
556 0)
557 case "$xxx" in
558 2*) cat >&4 <<EOM
559The largest integer your NVs can preserve is equal to $xxx
560EOM
561 nv_overflows_integers_at="$xxx"
562 ;;
563 *) cat >&4 <<EOM
564Cannot determine the largest integer value your NVs can hold, unexpected output
565'$xxx'
566EOM
567 ;;
568 esac
569 ;;
570 *) cat >&4 <<EOM
571Cannot determine the largest integer value your NVs can hold
572EOM
573 ;;
574 esac
575fi
576$rm_try
577
913e5e82
MB
578$echo "Checking whether NV 0.0 is all bits zero in memory..." >&4
579: volatile so that the compiler has to store it out to memory.
580if test X"$d_volatile" = X"$define"; then
581 volatile=volatile
582fi
583$cat <<EOP >try.c
584#include <stdio.h>
585#$i_stdlib I_STDLIB
586#ifdef I_STDLIB
587#include <stdlib.h>
588#endif
589#$i_string I_STRING
590#ifdef I_STRING
591# include <string.h>
592#else
593# include <strings.h>
594#endif
595#include <sys/types.h>
596#include <signal.h>
597#ifdef SIGFPE
598$volatile int bletched = 0;
dc952a08 599$signal_t blech(int s) { bletched = 1; }
913e5e82
MB
600#endif
601
602int checkit($nvtype d, char *where) {
603 unsigned char *p = (char *)&d;
604 unsigned char *end = p + sizeof(d);
605 int fail = 0;
606
607 while (p < end)
608 fail += *p++;
609
610 if (!fail)
611 return 0;
612
613 p = (char *)&d;
614 printf("No - %s: 0x", where);
615 while (p < end)
616 printf ("%02X", *p++);
617 printf("\n");
618 return 1;
619}
620
621int main(int argc, char **argv) {
622 $nvtype d = 0.0;
623 int fail = 0;
624 fail += checkit(d, "0.0");
625
626 /* The compiler shouldn't be assuming that bletched is 0 */
627 d = bletched;
628
629 fail += checkit(d, "bleched");
630
631#ifdef SIGFPE
632 signal(SIGFPE, blech);
633#endif
634
635 /* Paranoia - the compiler should have no way of knowing that ANSI says
636 that argv[argc] will always be NULL. Actually, if it did assume this it
637 would be buggy, as this is C and main() can be called from elsewhere in
638 the program. */
639 d = argv[argc] ? 1 : 0;
640
641 if (d) {
642 printf("Odd argv[argc]=%p, d=%g\n", argv[argc], d);
643 }
644
645 fail += checkit(d, "ternary");
646
647 memset(&d, sizeof(d), argv[argc] ? 1 : 0);
648
649 if (d != 0.0) {
650 printf("No - memset doesn't give 0.0\n");
651 /* This might just blow up: */
652 printf("(gives %g)\n", d);
653 return 1;
654 }
2cb64bf6 655
913e5e82
MB
656#ifdef SIGFPE
657 if (bletched) {
658 printf("No - something bleched\n");
659 return 1;
660 }
661#endif
662 if (fail) {
663 printf("No - %d fail(s)\n", fail);
664 return 1;
665 }
666 printf("Yes\n");
667 return 0;
668}
669EOP
670set try
671
672d_nv_zero_is_allbits_zero="$undef"
673if eval $compile; then
674 xxx="`$run ./try`"
675 case "$?" in
676 0)
677 case "$xxx" in
678 Yes) cat >&4 <<EOM
6790.0 is represented as all bits zero in memory
680EOM
681 d_nv_zero_is_allbits_zero="$define"
682 ;;
683 *) cat >&4 <<EOM
6840.0 is not represented as all bits zero in memory
685EOM
686 d_nv_zero_is_allbits_zero="$undef"
687 ;;
688 esac
689 ;;
690 *) cat >&4 <<EOM
6910.0 is not represented as all bits zero in memory
692EOM
693 d_nv_zero_is_allbits_zero="$undef"
694 ;;
695 esac
696fi
2cb64bf6 697$rm_try
913e5e82 698