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