beta-0.89.2
[luatex.git] / source / libs / gmp / m4 / gmp-double-format.m4
blobfee679067ce7ee9843ba404c296d955c4d5c0a62
1 # Autoconf macros for the GNU MP Library.
2 # Copyright (C) 2000-2014 Free Software Foundation, Inc.
4 # Copyright (C) 2014 Peter Breitenlohner <tex-live@tug.org>
5 # Extracted from gmp-6.0.0/acinclude.m4 and adapted for TeX Live.
7 # This file is free software; the copyright holders
8 # give unlimited permission to copy and/or distribute it,
9 # with or without modifications, as long as this notice is preserved.
11 # GMP_C_DOUBLE_FORMAT
12 # -------------------
13 # Determine the floating point format.
15 # The object file is grepped, in order to work when cross compiling.  A
16 # start and end sequence is included to avoid false matches, and allowance
17 # is made for the desired data crossing an "od -b" line boundary.  The test
18 # number is a small integer so it should appear exactly, no rounding or
19 # truncation etc.
21 # "od -b", incidentally, is supported even by Unix V7, and the awk script
22 # used doesn't have functions or anything, so even an "old" awk should
23 # suffice.
25 # The C code here declares the variable foo as extern; without that, some
26 # C++ compilers will not put foo in the object file.
28 AC_DEFUN([GMP_C_DOUBLE_FORMAT], [dnl
29 AC_REQUIRE([AC_PROG_CC])
30 AC_REQUIRE([AC_PROG_AWK])
31 AC_CACHE_CHECK([format of `double' floating point],
32                [gmp_cv_c_double_format],
33 [gmp_cv_c_double_format=unknown
34 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
35 struct foo {
36   char    before[8];
37   double  x;
38   char    after[8];
40 extern struct foo foo;
41 struct foo foo = {
42   { '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
43   -123456789.0,
44   { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' },
46 ]])],
47    [cat >conftest.awk <<\EOF
48 _gmp_double_awk
49 EOF
50   gmp_cv_c_double_format=`od -b conftest.$ac_objext | $AWK -f conftest.awk`
51   AS_CASE([$gmp_cv_c_double_format],
52           [unknown*],
53             [echo "cannot match anything, conftest.$ac_objext contains" >&AS_MESSAGE_LOG_FD
54              od -b conftest.$ac_objext >&AS_MESSAGE_LOG_FD])],
55    [AC_MSG_WARN([oops, cannot compile test program])])
56 rm -f conftest.awk])
58 AH_VERBATIM([HAVE_DOUBLE],
59 [/* Define one of the following to 1 for the format of a `double'.
60    If your format is not among these choices, or you don't know what it is,
61    then leave all undefined.
62    IEEE_LITTLE_SWAPPED means little endian, but with the two 4-byte halves
63    swapped, as used by ARM CPUs in little endian mode.  */
64 #undef HAVE_DOUBLE_IEEE_BIG_ENDIAN
65 #undef HAVE_DOUBLE_IEEE_LITTLE_ENDIAN
66 #undef HAVE_DOUBLE_IEEE_LITTLE_SWAPPED
67 #undef HAVE_DOUBLE_VAX_D
68 #undef HAVE_DOUBLE_VAX_G
69 #undef HAVE_DOUBLE_CRAY_CFP])
71 AS_CASE([$gmp_cv_c_double_format],
72         ["IEEE big endian"],
73           [AC_DEFINE([HAVE_DOUBLE_IEEE_BIG_ENDIAN], 1)],
74         ["IEEE little endian"],
75           [AC_DEFINE([HAVE_DOUBLE_IEEE_LITTLE_ENDIAN], 1)],
76         ["IEEE little endian, swapped halves"],
77           [AC_DEFINE([HAVE_DOUBLE_IEEE_LITTLE_SWAPPED], 1)],
78         ["VAX D"],
79           [AC_DEFINE([HAVE_DOUBLE_VAX_D], 1)],
80         ["VAX G"],
81           [AC_DEFINE([HAVE_DOUBLE_VAX_G], 1)],
82         ["Cray CFP"],
83           [AC_DEFINE([HAVE_DOUBLE_CRAY_CFP], 1)],
84         ["bad ARM software floats"], [],
85         [unknown*],
86           [AC_MSG_WARN([Could not determine float format.])
87            AC_MSG_WARN([Conversions to and from "double" may be slow.])],
88         [AC_MSG_WARN([oops, unrecognised float format: $gmp_cv_c_double_format])])
89 ]) # GMP_C_DOUBLE_FORMAT
91 # _gmp_double_awk
92 # ---------------
93 # Internal subroutine defining contents of conftest.awk.
94 m4_define([_gmp_double_awk], [[
95 BEGIN {
96   found = 0
100   for (f = 2; f <= NF; f++)
101     {
102       for (i = 0; i < 23; i++)
103         got[i] = got[i+1];
104       got[23] = $f;
106       # match the special begin and end sequences
107       if (got[0] != "001") continue
108       if (got[1] != "043") continue
109       if (got[2] != "105") continue
110       if (got[3] != "147") continue
111       if (got[4] != "211") continue
112       if (got[5] != "253") continue
113       if (got[6] != "315") continue
114       if (got[7] != "357") continue
115       if (got[16] != "376") continue
116       if (got[17] != "334") continue
117       if (got[18] != "272") continue
118       if (got[19] != "230") continue
119       if (got[20] != "166") continue
120       if (got[21] != "124") continue
121       if (got[22] != "062") continue
122       if (got[23] != "020") continue
124       saw = " (" got[8] " " got[9] " " got[10] " " got[11] " " got[12] " " got[13] " " got[14] " " got[15] ")"
126       if (got[8]  == "000" &&  \
127           got[9]  == "000" &&  \
128           got[10] == "000" &&  \
129           got[11] == "124" &&  \
130           got[12] == "064" &&  \
131           got[13] == "157" &&  \
132           got[14] == "235" &&  \
133           got[15] == "301")
134         {
135           print "IEEE little endian"
136           found = 1
137           exit
138         }
140       # Little endian with the two 4-byte halves swapped, as used by ARM
141       # when the chip is in little endian mode.
142       #
143       if (got[8]  == "064" &&  \
144           got[9]  == "157" &&  \
145           got[10] == "235" &&  \
146           got[11] == "301" &&  \
147           got[12] == "000" &&  \
148           got[13] == "000" &&  \
149           got[14] == "000" &&  \
150           got[15] == "124")
151         {
152           print "IEEE little endian, swapped halves"
153           found = 1
154           exit
155         }
157       # gcc 2.95.4 on one GNU/Linux ARM system was seen generating 000 in
158       # the last byte, whereas 124 is correct.  Not sure where the bug
159       # actually lies, but a running program didn't seem to get a full
160       # mantissa worth of working bits.
161       #
162       # We match this case explicitly so we can give a nice result message,
163       # but we deliberately exclude it from the normal IEEE double setups
164       # since it's too broken.
165       #
166       if (got[8]  == "064" &&  \
167           got[9]  == "157" &&  \
168           got[10] == "235" &&  \
169           got[11] == "301" &&  \
170           got[12] == "000" &&  \
171           got[13] == "000" &&  \
172           got[14] == "000" &&  \
173           got[15] == "000")
174         {
175           print "bad ARM software floats"
176           found = 1
177           exit
178         }
180       if (got[8]  == "301" &&  \
181           got[9]  == "235" &&  \
182           got[10] == "157" &&  \
183           got[11] == "064" &&  \
184           got[12] == "124" &&  \
185           got[13] == "000" &&  \
186           got[14] == "000" &&  \
187           got[15] == "000")
188         {
189           print "IEEE big endian"
190           found = 1
191           exit
192         }
194       if (got[8]  == "353" &&  \
195           got[9]  == "315" &&  \
196           got[10] == "242" &&  \
197           got[11] == "171" &&  \
198           got[12] == "000" &&  \
199           got[13] == "240" &&  \
200           got[14] == "000" &&  \
201           got[15] == "000")
202         {
203           print "VAX D"
204           found = 1
205           exit
206         }
208       if (got[8]  == "275" &&  \
209           got[9]  == "301" &&  \
210           got[10] == "064" &&  \
211           got[11] == "157" &&  \
212           got[12] == "000" &&  \
213           got[13] == "124" &&  \
214           got[14] == "000" &&  \
215           got[15] == "000")
216         {
217           print "VAX G"
218           found = 1
219           exit
220         }
222       if (got[8]  == "300" &&  \
223           got[9]  == "033" &&  \
224           got[10] == "353" &&  \
225           got[11] == "171" &&  \
226           got[12] == "242" &&  \
227           got[13] == "240" &&  \
228           got[14] == "000" &&  \
229           got[15] == "000")
230         {
231           print "Cray CFP"
232           found = 1
233           exit
234         }
235     }
238 END {
239   if (! found)
240     print "unknown", saw