warnings: fix compilation with old autoconf
[gnulib/ericb.git] / m4 / host-cpu-c-abi.m4
blob02f7b8a7d475eb9876d2f0e20c5de4308b78417f
1 # host-cpu-c-abi.m4 serial 7
2 dnl Copyright (C) 2002-2017 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.
7 dnl From Bruno Haible and Sam Steingold.
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 <http://en.wikipedia.org/wiki/X86_instruction_listings>.
50 AC_DEFUN([gl_HOST_CPU_C_ABI],
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
57 changequote(,)dnl
58        i[4567]86 )
59 changequote([,])dnl
60          gl_cv_host_cpu_c_abi=i386
61          ;;
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_EGREP_CPP([yes],
72            [#if defined __x86_64__ || defined __amd64__ || defined _M_X64 || defined _M_AMD64
73             yes
74             #endif],
75            [AC_EGREP_CPP([yes],
76               [#if defined __ILP32__ || defined _ILP32
77                yes
78                #endif],
79               [gl_cv_host_cpu_c_abi=x86_64-x32],
80               [gl_cv_host_cpu_c_abi=x86_64])],
81            [gl_cv_host_cpu_c_abi=i386])
82          ;;
84 changequote(,)dnl
85        alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )
86 changequote([,])dnl
87          gl_cv_host_cpu_c_abi=alpha
88          ;;
90        arm* | aarch64 )
91          # Assume arm with EABI.
92          # On arm64 systems, the C compiler may be generating code in one of
93          # these ABIs:
94          # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
95          # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
96          # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
97          AC_EGREP_CPP([yes],
98            [#if defined __aarch64__
99             yes
100             #endif],
101            [AC_EGREP_CPP([yes],
102               [#if defined __ILP32__ || defined _ILP32
103                yes
104                #endif],
105               [gl_cv_host_cpu_c_abi=arm64-ilp32],
106               [gl_cv_host_cpu_c_abi=arm64])],
107            [# Don't distinguish little-endian and big-endian arm, since they
108             # don't require different machine code for simple operations and
109             # since the user can distinguish them through the preprocessor
110             # defines __ARMEL__ vs. __ARMEB__.
111             # But distinguish arm which passes floating-point arguments and
112             # return values in integer registers (r0, r1, ...) - this is
113             # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which
114             # passes them in float registers (s0, s1, ...) and double registers
115             # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer
116             # sets the preprocessor defines __ARM_PCS (for the first case) and
117             # __ARM_PCS_VFP (for the second case), but older GCC does not.
118             echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c
119             # Look for a reference to the register d0 in the .s file.
120             AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1
121             if LC_ALL=C grep -E 'd0,' conftest.$gl_asmext >/dev/null; then
122               gl_cv_host_cpu_c_abi=armhf
123             else
124               gl_cv_host_cpu_c_abi=arm
125             fi
126             rm -f conftest*
127            ])
128          ;;
130        hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
131          # On hppa, the C compiler may be generating 32-bit code or 64-bit
132          # code. In the latter case, it defines _LP64 and __LP64__.
133          AC_EGREP_CPP([yes],
134            [#if defined(__LP64__)
135             yes
136             #endif],
137            [gl_cv_host_cpu_c_abi=hppa64],
138            [gl_cv_host_cpu_c_abi=hppa])
139          ;;
141        ia64* )
142          # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
143          # 32-bit code. In the latter case, it defines _ILP32.
144          AC_EGREP_CPP([yes],
145            [#if defined _ILP32
146             yes
147             #endif],
148            [gl_cv_host_cpu_c_abi=ia64-ilp32],
149            [gl_cv_host_cpu_c_abi=ia64])
150          ;;
152        mips* )
153          # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
154          # at 32.
155          AC_EGREP_CPP([yes],
156            [#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
157             yes
158             #endif],
159            [gl_cv_host_cpu_c_abi=mips64],
160            [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but
161             # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32.
162             # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but
163             # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32.
164             AC_EGREP_CPP([yes],
165               [#if (_MIPS_SIM == _ABIN32)
166                yes
167                #endif],
168               [gl_cv_host_cpu_c_abi=mipsn32],
169               [gl_cv_host_cpu_c_abi=mips])])
170          ;;
172        powerpc* )
173          # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
174          # No need to distinguish them here; the caller may distinguish
175          # them based on the OS.
176          # On powerpc64 systems, the C compiler may still be generating
177          # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
178          # be generating 64-bit code.
179          AC_EGREP_CPP([yes],
180            [#if defined __powerpc64__ || defined _ARCH_PPC64
181             yes
182             #endif],
183            [# On powerpc64, there are two ABIs on Linux: The AIX compatible
184             # one and the ELFv2 one. The latter defines _CALL_ELF=2.
185             AC_EGREP_CPP([yes],
186               [#if defined _CALL_ELF && _CALL_ELF == 2
187                yes
188                #endif],
189               [gl_cv_host_cpu_c_abi=powerpc64-elfv2],
190               [gl_cv_host_cpu_c_abi=powerpc64])
191            ],
192            [gl_cv_host_cpu_c_abi=powerpc])
193          ;;
195        rs6000 )
196          gl_cv_host_cpu_c_abi=powerpc
197          ;;
199        s390* )
200          # On s390x, the C compiler may be generating 64-bit (= s390x) code
201          # or 31-bit (= s390) code.
202          AC_EGREP_CPP([yes],
203            [#if defined(__LP64__) || defined(__s390x__)
204             yes
205             #endif],
206            [gl_cv_host_cpu_c_abi=s390x],
207            [gl_cv_host_cpu_c_abi=s390])
208          ;;
210        sparc | sparc64 )
211          # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
212          # C compiler still generates 32-bit code.
213          AC_EGREP_CPP([yes],
214            [#if defined __sparcv9 || defined __arch64__
215             yes
216             #endif],
217            [gl_cv_host_cpu_c_abi=sparc64],
218            [gl_cv_host_cpu_c_abi=sparc])
219          ;;
221        *)
222          gl_cv_host_cpu_c_abi="$host_cpu"
223          ;;
224      esac
225     ])
227   dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.
228   HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'`
229   HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi"
230   AC_SUBST([HOST_CPU])
231   AC_SUBST([HOST_CPU_C_ABI])
233   # This was
234   #   AC_DEFINE_UNQUOTED([__${HOST_CPU}__])
235   #   AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])
236   # earlier, but KAI C++ 3.2d doesn't like this.
237   sed -e 's/-/_/g' >> confdefs.h <<EOF
238 #ifndef __${HOST_CPU}__
239 #define __${HOST_CPU}__ 1
240 #endif
241 #ifndef __${HOST_CPU_C_ABI}__
242 #define __${HOST_CPU_C_ABI}__ 1
243 #endif
245   AH_TOP([/* CPU and C ABI indicator */
246 #ifndef __i386__
247 #undef __i386__
248 #endif
249 #ifndef __x86_64_x32__
250 #undef __x86_64_x32__
251 #endif
252 #ifndef __x86_64__
253 #undef __x86_64__
254 #endif
255 #ifndef __alpha__
256 #undef __alpha__
257 #endif
258 #ifndef __arm__
259 #undef __arm__
260 #endif
261 #ifndef __armhf__
262 #undef __armhf__
263 #endif
264 #ifndef __arm64_ilp32__
265 #undef __arm64_ilp32__
266 #endif
267 #ifndef __arm64__
268 #undef __arm64__
269 #endif
270 #ifndef __hppa__
271 #undef __hppa__
272 #endif
273 #ifndef __hppa64__
274 #undef __hppa64__
275 #endif
276 #ifndef __ia64_ilp32__
277 #undef __ia64_ilp32__
278 #endif
279 #ifndef __ia64__
280 #undef __ia64__
281 #endif
282 #ifndef __m68k__
283 #undef __m68k__
284 #endif
285 #ifndef __mips__
286 #undef __mips__
287 #endif
288 #ifndef __mipsn32__
289 #undef __mipsn32__
290 #endif
291 #ifndef __mips64__
292 #undef __mips64__
293 #endif
294 #ifndef __powerpc__
295 #undef __powerpc__
296 #endif
297 #ifndef __powerpc64__
298 #undef __powerpc64__
299 #endif
300 #ifndef __powerpc64_elfv2__
301 #undef __powerpc64_elfv2__
302 #endif
303 #ifndef __s390__
304 #undef __s390__
305 #endif
306 #ifndef __s390x__
307 #undef __s390x__
308 #endif
309 #ifndef __sh__
310 #undef __sh__
311 #endif
312 #ifndef __sparc__
313 #undef __sparc__
314 #endif
315 #ifndef __sparc64__
316 #undef __sparc64__
317 #endif