New upstream version 1.9
[debian/gzip] / m4 / host-cpu-c-abi.m4
1 # host-cpu-c-abi.m4 serial 8
2 dnl Copyright (C) 2002-2018 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 dnl From Bruno Haible and Sam Steingold.
8
9 dnl Sets the HOST_CPU variable to the canonical name of the CPU.
10 dnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its
11 dnl C language ABI (application binary interface).
12 dnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in
13 dnl config.h.
14 dnl
15 dnl This canonical name can be used to select a particular assembly language
16 dnl source file that will interoperate with C code on the given host.
17 dnl
18 dnl For example:
19 dnl * 'i386' and 'sparc' are different canonical names, because code for i386
20 dnl   will not run on SPARC CPUs and vice versa. They have different
21 dnl   instruction sets.
22 dnl * 'sparc' and 'sparc64' are different canonical names, because code for
23 dnl   'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code
24 dnl   contains 32-bit instructions, whereas 'sparc64' code contains 64-bit
25 dnl   instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit
26 dnl   mode, but not both.
27 dnl * 'mips' and 'mipsn32' are different canonical names, because they use
28 dnl   different argument passing and return conventions for C functions, and
29 dnl   although the instruction set of 'mips' is a large subset of the
30 dnl   instruction set of 'mipsn32'.
31 dnl * 'mipsn32' and 'mips64' are different canonical names, because they use
32 dnl   different sizes for the C types like 'int' and 'void *', and although
33 dnl   the instruction sets of 'mipsn32' and 'mips64' are the same.
34 dnl * The same canonical name is used for different endiannesses. You can
35 dnl   determine the endianness through preprocessor symbols:
36 dnl   - 'arm': test __ARMEL__.
37 dnl   - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL.
38 dnl   - 'powerpc64': test _BIG_ENDIAN vs. _LITTLE_ENDIAN.
39 dnl * The same name 'i386' is used for CPUs of type i386, i486, i586
40 dnl   (Pentium), AMD K7, Pentium II, Pentium IV, etc., because
41 dnl   - Instructions that do not exist on all of these CPUs (cmpxchg,
42 dnl     MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your
43 dnl     assembly language source files use such instructions, you will
44 dnl     need to make the distinction.
45 dnl   - Speed of execution of the common instruction set is reasonable across
46 dnl     the entire family of CPUs. If you have assembly language source files
47 dnl     that are optimized for particular CPU types (like GNU gmp has), you
48 dnl     will need to make the distinction.
49 dnl   See <https://en.wikipedia.org/wiki/X86_instruction_listings>.
50 AC_DEFUN([gl_HOST_CPU_C_ABI],
51 [
52   AC_REQUIRE([AC_CANONICAL_HOST])
53   AC_REQUIRE([gl_C_ASM])
54   AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi],
55     [case "$host_cpu" in
56
57 changequote(,)dnl
58        i[4567]86 )
59 changequote([,])dnl
60          gl_cv_host_cpu_c_abi=i386
61          ;;
62
63        x86_64 )
64          # On x86_64 systems, the C compiler may be generating code in one of
65          # these ABIs:
66          # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
67          # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
68          #   with native Windows (mingw, MSVC).
69          # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
70          # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
71          AC_COMPILE_IFELSE(
72            [AC_LANG_SOURCE(
73               [[#if (defined __x86_64__ || defined __amd64__ \
74                      || defined _M_X64 || defined _M_AMD64)
75                  int ok;
76                 #else
77                  error fail
78                 #endif
79               ]])],
80            [AC_COMPILE_IFELSE(
81               [AC_LANG_SOURCE(
82                  [[#if defined __ILP32__ || defined _ILP32
83                     int ok;
84                    #else
85                     error fail
86                    #endif
87                  ]])],
88               [gl_cv_host_cpu_c_abi=x86_64-x32],
89               [gl_cv_host_cpu_c_abi=x86_64])],
90            [gl_cv_host_cpu_c_abi=i386])
91          ;;
92
93 changequote(,)dnl
94        alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )
95 changequote([,])dnl
96          gl_cv_host_cpu_c_abi=alpha
97          ;;
98
99        arm* | aarch64 )
100          # Assume arm with EABI.
101          # On arm64 systems, the C compiler may be generating code in one of
102          # these ABIs:
103          # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
104          # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
105          # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
106          AC_COMPILE_IFELSE(
107            [AC_LANG_SOURCE(
108               [[#ifdef __aarch64__
109                  int ok;
110                 #else
111                  error fail
112                 #endif
113               ]])],
114            [AC_COMPILE_IFELSE(
115               [AC_LANG_SOURCE(
116                 [[#if defined __ILP32__ || defined _ILP32
117                    int ok;
118                   #else
119                    error fail
120                   #endif
121                 ]])],
122               [gl_cv_host_cpu_c_abi=arm64-ilp32],
123               [gl_cv_host_cpu_c_abi=arm64])],
124            [# Don't distinguish little-endian and big-endian arm, since they
125             # don't require different machine code for simple operations and
126             # since the user can distinguish them through the preprocessor
127             # defines __ARMEL__ vs. __ARMEB__.
128             # But distinguish arm which passes floating-point arguments and
129             # return values in integer registers (r0, r1, ...) - this is
130             # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which
131             # passes them in float registers (s0, s1, ...) and double registers
132             # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer
133             # sets the preprocessor defines __ARM_PCS (for the first case) and
134             # __ARM_PCS_VFP (for the second case), but older GCC does not.
135             echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c
136             # Look for a reference to the register d0 in the .s file.
137             AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1
138             if LC_ALL=C grep -E 'd0,' conftest.$gl_asmext >/dev/null; then
139               gl_cv_host_cpu_c_abi=armhf
140             else
141               gl_cv_host_cpu_c_abi=arm
142             fi
143             rm -f conftest*
144            ])
145          ;;
146
147        hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
148          # On hppa, the C compiler may be generating 32-bit code or 64-bit
149          # code. In the latter case, it defines _LP64 and __LP64__.
150          AC_COMPILE_IFELSE(
151            [AC_LANG_SOURCE(
152               [[#ifdef __LP64__
153                  int ok;
154                 #else
155                  error fail
156                 #endif
157               ]])],
158            [gl_cv_host_cpu_c_abi=hppa64],
159            [gl_cv_host_cpu_c_abi=hppa])
160          ;;
161
162        ia64* )
163          # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
164          # 32-bit code. In the latter case, it defines _ILP32.
165          AC_COMPILE_IFELSE(
166            [AC_LANG_SOURCE(
167               [[#ifdef _ILP32
168                  int ok;
169                 #else
170                  error fail
171                 #endif
172               ]])],
173            [gl_cv_host_cpu_c_abi=ia64-ilp32],
174            [gl_cv_host_cpu_c_abi=ia64])
175          ;;
176
177        mips* )
178          # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
179          # at 32.
180          AC_COMPILE_IFELSE(
181            [AC_LANG_SOURCE(
182               [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
183                  int ok;
184                 #else
185                  error fail
186                 #endif
187               ]])],
188            [gl_cv_host_cpu_c_abi=mips64],
189            [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but
190             # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32.
191             # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but
192             # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32.
193             AC_COMPILE_IFELSE(
194               [AC_LANG_SOURCE(
195                  [[#if (_MIPS_SIM == _ABIN32)
196                     int ok;
197                    #else
198                     error fail
199                    #endif
200                  ]])],
201               [gl_cv_host_cpu_c_abi=mipsn32],
202               [gl_cv_host_cpu_c_abi=mips])])
203          ;;
204
205        powerpc* )
206          # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
207          # No need to distinguish them here; the caller may distinguish
208          # them based on the OS.
209          # On powerpc64 systems, the C compiler may still be generating
210          # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
211          # be generating 64-bit code.
212          AC_COMPILE_IFELSE(
213            [AC_LANG_SOURCE(
214               [[#if defined __powerpc64__ || defined _ARCH_PPC64
215                  int ok;
216                 #else
217                  error fail
218                 #endif
219               ]])],
220            [# On powerpc64, there are two ABIs on Linux: The AIX compatible
221             # one and the ELFv2 one. The latter defines _CALL_ELF=2.
222             AC_COMPILE_IFELSE(
223               [AC_LANG_SOURCE(
224                  [[#if defined _CALL_ELF && _CALL_ELF == 2
225                     int ok;
226                    #else
227                     error fail
228                    #endif
229                  ]])],
230               [gl_cv_host_cpu_c_abi=powerpc64-elfv2],
231               [gl_cv_host_cpu_c_abi=powerpc64])
232            ],
233            [gl_cv_host_cpu_c_abi=powerpc])
234          ;;
235
236        rs6000 )
237          gl_cv_host_cpu_c_abi=powerpc
238          ;;
239
240        s390* )
241          # On s390x, the C compiler may be generating 64-bit (= s390x) code
242          # or 31-bit (= s390) code.
243          AC_COMPILE_IFELSE(
244            [AC_LANG_SOURCE(
245               [[#if defined __LP64__ || defined __s390x__
246                   int ok;
247                 #else
248                   error fail
249                 #endif
250               ]])],
251            [gl_cv_host_cpu_c_abi=s390x],
252            [gl_cv_host_cpu_c_abi=s390])
253          ;;
254
255        sparc | sparc64 )
256          # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
257          # C compiler still generates 32-bit code.
258          AC_COMPILE_IFELSE(
259            [AC_LANG_SOURCE(
260               [[#if defined __sparcv9 || defined __arch64__
261                  int ok;
262                 #else
263                  error fail
264                 #endif
265               ]])],
266            [gl_cv_host_cpu_c_abi=sparc64],
267            [gl_cv_host_cpu_c_abi=sparc])
268          ;;
269
270        *)
271          gl_cv_host_cpu_c_abi="$host_cpu"
272          ;;
273      esac
274     ])
275
276   dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.
277   HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'`
278   HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi"
279   AC_SUBST([HOST_CPU])
280   AC_SUBST([HOST_CPU_C_ABI])
281
282   # This was
283   #   AC_DEFINE_UNQUOTED([__${HOST_CPU}__])
284   #   AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])
285   # earlier, but KAI C++ 3.2d doesn't like this.
286   sed -e 's/-/_/g' >> confdefs.h <<EOF
287 #ifndef __${HOST_CPU}__
288 #define __${HOST_CPU}__ 1
289 #endif
290 #ifndef __${HOST_CPU_C_ABI}__
291 #define __${HOST_CPU_C_ABI}__ 1
292 #endif
293 EOF
294   AH_TOP([/* CPU and C ABI indicator */
295 #ifndef __i386__
296 #undef __i386__
297 #endif
298 #ifndef __x86_64_x32__
299 #undef __x86_64_x32__
300 #endif
301 #ifndef __x86_64__
302 #undef __x86_64__
303 #endif
304 #ifndef __alpha__
305 #undef __alpha__
306 #endif
307 #ifndef __arm__
308 #undef __arm__
309 #endif
310 #ifndef __armhf__
311 #undef __armhf__
312 #endif
313 #ifndef __arm64_ilp32__
314 #undef __arm64_ilp32__
315 #endif
316 #ifndef __arm64__
317 #undef __arm64__
318 #endif
319 #ifndef __hppa__
320 #undef __hppa__
321 #endif
322 #ifndef __hppa64__
323 #undef __hppa64__
324 #endif
325 #ifndef __ia64_ilp32__
326 #undef __ia64_ilp32__
327 #endif
328 #ifndef __ia64__
329 #undef __ia64__
330 #endif
331 #ifndef __m68k__
332 #undef __m68k__
333 #endif
334 #ifndef __mips__
335 #undef __mips__
336 #endif
337 #ifndef __mipsn32__
338 #undef __mipsn32__
339 #endif
340 #ifndef __mips64__
341 #undef __mips64__
342 #endif
343 #ifndef __powerpc__
344 #undef __powerpc__
345 #endif
346 #ifndef __powerpc64__
347 #undef __powerpc64__
348 #endif
349 #ifndef __powerpc64_elfv2__
350 #undef __powerpc64_elfv2__
351 #endif
352 #ifndef __s390__
353 #undef __s390__
354 #endif
355 #ifndef __s390x__
356 #undef __s390x__
357 #endif
358 #ifndef __sh__
359 #undef __sh__
360 #endif
361 #ifndef __sparc__
362 #undef __sparc__
363 #endif
364 #ifndef __sparc64__
365 #undef __sparc64__
366 #endif
367 ])
368
369 ])