beta-0.89.2
[luatex.git] / source / libs / mpfr / m4 / mpfr-long-double-format.m4
blob67c271a45aaadbf4bf870fc242bbfa1bfbf2d1d3
1 # Autoconf macros for the GNU MPFR Library.
2 # Copyright (C) 2000-2013 Free Software Foundation, Inc.
3 # Contributed by the AriC and Caramel projects, INRIA.
5 # Copyright (C) 2014 Peter Breitenlohner <tex-live@tug.org>
6 # Extracted from mpfr-3.1.2/acinclude.m4 and adapted for TeX Live.
8 # This file is free software; the copyright holders
9 # give unlimited permission to copy and/or distribute it,
10 # with or without modifications, as long as this notice is preserved.
12 # MPFR_C_LONG_DOUBLE_FORMAT
13 # -------------------------
14 # Determine the format of a long double.
16 # The object file is grepped, so as to work when cross compiling.  A
17 # start and end sequence is included to avoid false matches, and
18 # allowance is made for the desired data crossing an "od -b" line
19 # boundary.  The test number is a small integer so it should appear
20 # exactly, no rounding or truncation etc.
22 # "od -b" is supported even by Unix V7, and the awk script used doesn't
23 # have functions or anything, so even an "old" awk should suffice.
25 # The 10-byte IEEE extended format is generally padded to either 12 or 16
26 # bytes for alignment purposes.  The SVR4 i386 ABI is 12 bytes, or i386
27 # gcc -m128bit-long-double selects 16 bytes.  IA-64 is 16 bytes in LP64
28 # mode, or 12 bytes in ILP32 mode.  The first 10 bytes is the relevant
29 # part in all cases (big and little endian).
31 # Enhancements:
33 # Could match more formats, but no need to worry until there's code
34 # wanting to use them.
36 # Don't want to duplicate the double matching from GMP_C_DOUBLE_FORMAT,
37 # perhaps we should merge with that macro, to match data formats
38 # irrespective of the C type in question.  Or perhaps just let the code
39 # use DOUBLE macros when sizeof(double)==sizeof(long double).
41 AC_DEFUN([MPFR_C_LONG_DOUBLE_FORMAT], [dnl
42 AC_REQUIRE([AC_PROG_CC])
43 AC_REQUIRE([AC_PROG_AWK])
44 AC_CACHE_CHECK([format of `long double' floating point],
45                [mpfr_cv_c_long_double_format],
46 [mpfr_cv_c_long_double_format=unknown
47 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
48 /* "before" is 16 bytes to ensure there's no padding between it and "x".
49    We're not expecting any "long double" bigger than 16 bytes or with
50    alignment requirements stricter than 16 bytes.  */
51 struct {
52   char         before[16];
53   long double  x;
54   char         after[8];
55 } foo = {
56   { '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
57     '\001', '\043', '\105', '\147', '\211', '\253', '\315', '\357' },
58   -123456789.0,
59   { '\376', '\334', '\272', '\230', '\166', '\124', '\062', '\020' }
61 ]])],
62    [cat >conftest.awk <<\EOF
63 _mpfr_long_double_awk
64 EOF
65     mpfr_cv_c_long_double_format=`od -b conftest.$ac_objext | $AWK -f conftest.awk`
66     AS_CASE([$mpfr_cv_c_long_double_format],
67             [unknown*],
68               [echo "cannot match anything, conftest.$ac_objext contains" >&AS_MESSAGE_LOG_FD
69                od -b conftest.$ac_objext >&AS_MESSAGE_LOG_FD])],
70    [AC_MSG_WARN([oops, cannot compile test program])])
71 rm -f conftest.awk])
73 AH_VERBATIM([HAVE_LDOUBLE],
74 [/* Define one of the following to 1 for the format of a `long double'.
75    If your format is not among these choices, or you don't know what it is,
76    then leave all undefined.
77    IEEE_EXT is the 10-byte IEEE extended precision format.
78    IEEE_QUAD is the 16-byte IEEE quadruple precision format.
79    LITTLE or BIG is the endianness.  */
80 #undef HAVE_LDOUBLE_IEEE_EXT_LITTLE
81 #undef HAVE_LDOUBLE_IEEE_QUAD_LITTLE
82 #undef HAVE_LDOUBLE_IEEE_QUAD_BIG])
84 AS_CASE([$mpfr_cv_c_long_double_format],
85         ["IEEE extended, little endian"],
86           [AC_DEFINE([HAVE_LDOUBLE_IEEE_EXT_LITTLE], 1)],
87         ["IEEE quad, big endian"], 
88           [AC_DEFINE([HAVE_LDOUBLE_IEEE_QUAD_BIG], 1)],
89         ["IEEE quad, little endian"],
90           [AC_DEFINE([HAVE_LDOUBLE_IEEE_QUAD_LITTLE], 1)],
91         ["possibly double-double, big endian"],
92           [# Since we are not sure, we do not want to define a macro.
93            AC_MSG_WARN([This format is known on GCC/PowerPC platforms,])
94            AC_MSG_WARN([but due to GCC PR26374, we can't test further.])
95            AC_MSG_WARN([You can safely ignore this warning, though.])],
96         [unknown* | "not available"], [],
97         [AC_MSG_WARN([oops, unrecognised float format: $mpfr_cv_c_long_double_format])])
98 ]) # MPFR_C_LONG_DOUBLE_FORMAT
100 # _mpfr_long_double_awk
101 # ---------------------
102 # Internal subroutine defining contents of conftest.awk.
103 m4_define([_mpfr_long_double_awk], [[
104 BEGIN {
105   found = 0
108 # got[] holds a sliding window of bytes read the input.  got[0] is the most
109 # recent byte read, and got[31] the oldest byte read, so when looking to
110 # match some data the indices are "reversed".
113   for (f = 2; f <= NF; f++)
114     {
115       # new byte, shift others up
116       for (i = 31; i >= 0; i--)
117         got[i+1] = got[i];
118       got[0] = $f;
120       # end sequence
121       if (got[7] != "376") continue
122       if (got[6] != "334") continue
123       if (got[5] != "272") continue
124       if (got[4] != "230") continue
125       if (got[3] != "166") continue
126       if (got[2] != "124") continue
127       if (got[1] != "062") continue
128       if (got[0] != "020") continue
130       # start sequence, with 8-byte body
131       if (got[23] == "001" && \
132           got[22] == "043" && \
133           got[21] == "105" && \
134           got[20] == "147" && \
135           got[19] == "211" && \
136           got[18] == "253" && \
137           got[17] == "315" && \
138           got[16] == "357")
139         {
140           saw = " (" got[15] \
141                  " " got[14] \
142                  " " got[13] \
143                  " " got[12] \
144                  " " got[11] \
145                  " " got[10] \
146                  " " got[9]  \
147                  " " got[8] ")"
149           if (got[15] == "301" && \
150               got[14] == "235" && \
151               got[13] == "157" && \
152               got[12] == "064" && \
153               got[11] == "124" && \
154               got[10] == "000" && \
155               got[9] ==  "000" && \
156               got[8] ==  "000")
157             {
158               print "IEEE double, big endian"
159               found = 1
160               exit
161             }
163           if (got[15] == "000" && \
164               got[14] == "000" && \
165               got[13] == "000" && \
166               got[12] == "124" && \
167               got[11] == "064" && \
168               got[10] == "157" && \
169               got[9] ==  "235" && \
170               got[8] ==  "301")
171             {
172               print "IEEE double, little endian"
173               found = 1
174               exit
175             }
176         }
178       # start sequence, with 12-byte body
179       if (got[27] == "001" && \
180           got[26] == "043" && \
181           got[25] == "105" && \
182           got[24] == "147" && \
183           got[23] == "211" && \
184           got[22] == "253" && \
185           got[21] == "315" && \
186           got[20] == "357")
187         {
188           saw = " (" got[19] \
189                  " " got[18] \
190                  " " got[17] \
191                  " " got[16] \
192                  " " got[15] \
193                  " " got[14] \
194                  " " got[13] \
195                  " " got[12] \
196                  " " got[11] \
197                  " " got[10] \
198                  " " got[9]  \
199                  " " got[8] ")"
201           if (got[19] == "000" && \
202               got[18] == "000" && \
203               got[17] == "000" && \
204               got[16] == "000" && \
205               got[15] == "240" && \
206               got[14] == "242" && \
207               got[13] == "171" && \
208               got[12] == "353" && \
209               got[11] == "031" && \
210               got[10] == "300")
211             {
212               print "IEEE extended, little endian"
213               found = 1
214               exit
215             }
217           if (got[19] == "300" && \
218               got[18] == "031" && \
219               got[17] == "000" && \
220               got[16] == "000" && \
221               got[15] == "353" && \
222               got[14] == "171" && \
223               got[13] == "242" && \
224               got[12] == "240" && \
225               got[11] == "000" && \
226               got[10] == "000" && \
227               got[09] == "000" && \
228               got[08] == "000")
229             {
230               # format found on m68k
231               print "IEEE extended, big endian"
232               found = 1
233               exit
234             }
235         }
237       # start sequence, with 16-byte body
238       if (got[31] == "001" && \
239           got[30] == "043" && \
240           got[29] == "105" && \
241           got[28] == "147" && \
242           got[27] == "211" && \
243           got[26] == "253" && \
244           got[25] == "315" && \
245           got[24] == "357")
246         {
247           saw = " (" got[23] \
248                  " " got[22] \
249                  " " got[21] \
250                  " " got[20] \
251                  " " got[19] \
252                  " " got[18] \
253                  " " got[17] \
254                  " " got[16] \
255                  " " got[15] \
256                  " " got[14] \
257                  " " got[13] \
258                  " " got[12] \
259                  " " got[11] \
260                  " " got[10] \
261                  " " got[9]  \
262                  " " got[8] ")"
264           if (got[23] == "000" && \
265               got[22] == "000" && \
266               got[21] == "000" && \
267               got[20] == "000" && \
268               got[19] == "240" && \
269               got[18] == "242" && \
270               got[17] == "171" && \
271               got[16] == "353" && \
272               got[15] == "031" && \
273               got[14] == "300")
274             {
275               print "IEEE extended, little endian"
276               found = 1
277               exit
278             }
280           if (got[23] == "300" && \
281               got[22] == "031" && \
282               got[21] == "326" && \
283               got[20] == "363" && \
284               got[19] == "105" && \
285               got[18] == "100" && \
286               got[17] == "000" && \
287               got[16] == "000" && \
288               got[15] == "000" && \
289               got[14] == "000" && \
290               got[13] == "000" && \
291               got[12] == "000" && \
292               got[11] == "000" && \
293               got[10] == "000" && \
294               got[9]  == "000" && \
295               got[8]  == "000")
296             {
297               # format used on HP 9000/785 under HP-UX
298               print "IEEE quad, big endian"
299               found = 1
300               exit
301             }
303           if (got[23] == "000" && \
304               got[22] == "000" && \
305               got[21] == "000" && \
306               got[20] == "000" && \
307               got[19] == "000" && \
308               got[18] == "000" && \
309               got[17] == "000" && \
310               got[16] == "000" && \
311               got[15] == "000" && \
312               got[14] == "000" && \
313               got[13] == "100" && \
314               got[12] == "105" && \
315               got[11] == "363" && \
316               got[10] == "326" && \
317               got[9]  == "031" && \
318               got[8]  == "300")
319             {
320               print "IEEE quad, little endian"
321               found = 1
322               exit
323             }
325           if (got[23] == "301" && \
326               got[22] == "235" && \
327               got[21] == "157" && \
328               got[20] == "064" && \
329               got[19] == "124" && \
330               got[18] == "000" && \
331               got[17] == "000" && \
332               got[16] == "000" && \
333               got[15] == "000" && \
334               got[14] == "000" && \
335               got[13] == "000" && \
336               got[12] == "000" && \
337               got[11] == "000" && \
338               got[10] == "000" && \
339               got[9]  == "000" && \
340               got[8]  == "000")
341             {
342               # format used on 32-bit PowerPC (Mac OS X and Debian GNU/Linux)
343               print "possibly double-double, big endian"
344               found = 1
345               exit
346             }
347         }
348     }
351 END {
352   if (! found)
353     print "unknown", saw