This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
infnan: Configure scan for infnan bytes
[metaconfig.git] / U / perl / infnan.U
1 ?RCS: $Id$
2 ?RCS:
3 ?RCS: Copyright (c) 2015 Jarkko Hietaniemi, H.Merijn Brand
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:longdblinfbytes longdblnanbytes doubleinfbytes doublenanbytes: Inlibc \
9         cat i_math Compile run rm_try Setvar echo d_longdbl \
10         doublekind doublesize longdblkind longdblsize
11 ?MAKE:  -pick add $@ %<
12 ?S:longdblinfbytes:
13 ?S:     This variable contains comma-separated list of hexadecimal bytes
14 ?S:     for the double precision infinity.
15 ?S:.
16 ?S:longdblnanbytes:
17 ?S:     This variable contains comma-separated list of hexadecimal bytes
18 ?S:     for the double precision not-a-number.
19 ?S:.
20 ?S:doubleinfbytes:
21 ?S:     This variable contains comma-separated list of hexadecimal bytes
22 ?S:     for the long double precision infinity.
23 ?S:.
24 ?S:doublenanbytes:
25 ?S:     This variable contains comma-separated list of hexadecimal bytes
26 ?S:     for the long double precision not-a-number.
27 ?S:.
28 ?C:DOUBLEINFBYTES:
29 ?C:     This symbol, if defined, is a comma-separated list of
30 ?C:     hexadecimal bytes for the double precision infinity.
31 ?C:.
32 ?C:DOUBLENANBYTES:
33 ?C:     This symbol, if defined, is a comma-separated list of
34 ?C:     hexadecimal bytes (0xHH) for the double precision not-a-number.
35 ?C:.
36 ?C:LONGDBLINFBYTES:
37 ?C:     This symbol, if defined, is a comma-separated list of
38 ?C:     hexadecimal bytes for the long double precision infinity.
39 ?C:.
40 ?C:LONGDBLNANBYTES:
41 ?C:     This symbol, if defined, is a comma-separated list of
42 ?C:     hexadecimal bytes (0xHH) for the long double precision not-a-number.
43 ?C:.
44 ?H:#define DOUBLEINFBYTES  $doubleinfbytes              /**/
45 ?H:#define DOUBLENANBYTES  $doublenanbytes              /**/
46 ?H:#define LONGDBLINFBYTES $longdblinfbytes             /**/
47 ?H:#define LONGDBLNANBYTES $longdblnanbytes             /**/
48 ?H:.
49 ?F:!try
50 : Check what kind of inf/nan your system has
51 $echo "Checking the kind of infinities and nans you have..." >&4
52 $cat >try.c <<EOP
53 #define DOUBLESIZE $doublesize
54 #$d_longdbl HAS_LONG_DOUBLE
55 #ifdef HAS_LONG_DOUBLE
56 #define LONGDBLSIZE $longdblsize
57 #define LONGDBLKIND $longdblkind
58 #endif
59 #$i_math I_MATH
60 #ifdef I_MATH
61 #include <math.h>
62 #endif
63 #include <stdio.h>
64 /* Note that whether the sign bit is on or off
65  * for NaN depends on the CPU/FPU, and possibly
66  * can be affected by the build toolchain.
67  *
68  * For example for older MIPS and HP-PA 2.0 the quiet NaN is:
69  * 0x7f, 0xf7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
70  * 0x7f, 0xf4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
71  * (respectively) as opposed to the more usual
72  * 0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
73  */
74 static void bytes(unsigned char *p, unsigned int n) {
75   int i;
76   for (i = 0; i < n; i++) {
77     printf("0x%02x%s", p[i], i < n - 1 ? ", " : "\n");
78   }
79 }
80 int main(int argc, char *argv[]) {
81    /* We cannot use 1.0/0.0 and 0.0/0.0 (with L suffixes for long double)
82     * because some compilers are 'smart' and not only warn but refuse to
83     * compile such 'illegal' values. */
84    double dinf = exp(1e9);
85    double dnan = sqrt(-1.0);
86 #ifdef HAS_LONG_DOUBLE
87    long double ldinf = (long double)exp(1e9);
88    long double ldnan = (long double)sqrt(-1.0);
89 #endif
90   if (argc == 2) {
91     switch (argv[1][0]) {
92     case '1': bytes(&dinf, sizeof(dinf)); break;
93     case '2': bytes(&dnan, sizeof(dnan)); break;
94 #ifdef HAS_LONG_DOUBLE
95 # if LONG_DOUBLEKIND == 3 || LONG_DOUBLEKIND == 4
96 /* the 80-bit long doubles might have garbage in their excess bytes */
97     memset((char *)&ldinf + 10, '\0', LONG_DOUBLESIZE - 10);
98 # endif
99     case '3': bytes(&ldinf, sizeof(ldinf)); break;
100     case '4': bytes(&ldnan, sizeof(ldnan)); break;
101 #endif
102     }
103   }
104   return 0;
105 }
106 EOP
107 set try
108 if eval $compile; then
109     doubleinfbytes=`$run ./try 1`
110     doublenanbytes=`$run ./try 2`
111     case "$d_longdbl" in
112     $define)
113       longdblinfbytes=`$run ./try 3`
114       longdblnanbytes=`$run ./try 4`
115       ;;
116     esac
117 else
118     # Defaults in case the above test program failed.
119     case "$doublekind" in
120     1) # IEEE 754 32-bit LE
121        doubleinfbytes='0x00, 0x00, 0xf0, 0x7f'
122        doublenanbytes='0x00, 0x00, 0xf8, 0x7f'
123        ;;
124     2) # IEEE 754 32-bit BE
125        doubleinfbytes='0x7f, 0xf0, 0x00, 0x00'
126        doublenanbytes='0x7f, 0xf8, 0x00, 0x00'
127        ;;
128     3) # IEEE 754 64-bit LE
129        doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
130        doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f'
131        ;;
132     4) # IEEE 754 64-bit BE
133        doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
134        doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
135        ;;
136     5) # IEEE 754 128-bit LE
137        doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
138        doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f'
139        ;;
140     6) # IEEE 754 128-bit BE
141        doubleinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
142        doublenanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
143        ;;
144     7) # IEEE 754 64-bit mixed: 32-bit LEs in BE
145        doubleinfbytes='0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0x00, 0x00'
146        doublenanbytes='0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x00, 0x00'
147        ;;
148     8) # IEEE 754 64-bit mixed: 32-bit BEs in LE
149        doubleinfbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf0, 0x00, 0x00'
150        doublenanbytes='0x00, 0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00'
151        ;;
152     *) # No idea.
153        doubleinfbytes=$undef
154        doublenanbytes=$undef
155        ;;
156     esac
157     case "$longdblkind" in
158     1) # IEEE 754 128-bit LE
159        longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x7f'
160        longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f'
161        ;;
162     2) # IEEE 754 128-bit BE
163        longdblinfbytes='0x7f, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
164        longdblnanbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
165        ;;
166     3) # IEEE 754 80-bit LE, 12 or 16 bytes (x86)
167        case "$longdblsize" in
168        12) # x86 32-bit (96 bits, or 4 x 32, or 12 x 8)
169            longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00'
170            longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00'
171            ;;
172        16) # x86_64
173            longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
174            longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
175            ;;
176        *)  # No idea.
177            longdblinfbytes=$undef
178            longdblnanbytes=$undef
179        ;;
180        esac
181        ;;
182     4) # IEEE 754 80-bit BE, 12 or 16 bytes
183        case "$longdblsize" in
184        12) # 32-bit system
185            longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
186            longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
187            ;;
188        16) # 64-bit system
189            longdblinfbytes='0x7f, 0xff, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
190            longdblnanbytes='0x7f, 0xff, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
191            ;;
192        *)  # No idea.
193            longdblinfbytes=$undef
194            longdblnanbytes=$undef
195        ;;
196        esac
197        ;;
198     5) # 128-bit LE "double double"
199        longdblinfbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x7f'
200        longdblnanbytes='0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x7f'
201        ;;
202     6) # 128-bit BE "double double"
203        longdblinfbytes='0x7f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
204        longdblnanbytes='0x7f, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00'
205        ;;
206     *) # No idea.
207        longdblinfbytes=$undef
208        longdblnanbytes=$undef
209        ;;
210     esac
211 fi
212 $rm_try
213