1 # host-cpu-c-abi.m4 serial 11
2 dnl Copyright (C) 2002-2019 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
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.
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
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],
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],
60 gl_cv_host_cpu_c_abi=i386
64 # On x86_64 systems, the C compiler may be generating code in one of
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.
73 [[#if (defined __x86_64__ || defined __amd64__ \
74 || defined _M_X64 || defined _M_AMD64)
82 [[#if defined __ILP32__ || defined _ILP32
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])
94 alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )
96 gl_cv_host_cpu_c_abi=alpha
100 # Assume arm with EABI.
101 # On arm64 systems, the C compiler may be generating code in one of
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.
116 [[#if defined __ILP32__ || defined _ILP32
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 'd0,' conftest.$gl_asmext >/dev/null; then
139 gl_cv_host_cpu_c_abi=armhf
141 gl_cv_host_cpu_c_abi=arm
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__.
158 [gl_cv_host_cpu_c_abi=hppa64],
159 [gl_cv_host_cpu_c_abi=hppa])
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.
173 [gl_cv_host_cpu_c_abi=ia64-ilp32],
174 [gl_cv_host_cpu_c_abi=ia64])
178 # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
182 [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
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.
195 [[#if (_MIPS_SIM == _ABIN32)
201 [gl_cv_host_cpu_c_abi=mipsn32],
202 [gl_cv_host_cpu_c_abi=mips])])
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.
214 [[#if defined __powerpc64__ || defined _ARCH_PPC64
220 [# On powerpc64, there are two ABIs on Linux: The AIX compatible
221 # one and the ELFv2 one. The latter defines _CALL_ELF=2.
224 [[#if defined _CALL_ELF && _CALL_ELF == 2
230 [gl_cv_host_cpu_c_abi=powerpc64-elfv2],
231 [gl_cv_host_cpu_c_abi=powerpc64])
233 [gl_cv_host_cpu_c_abi=powerpc])
237 gl_cv_host_cpu_c_abi=powerpc
241 # There are 2 architectures (with variants): rv32* and rv64*.
244 [[#if __riscv_xlen == 64
252 # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
253 # Size of 'long' and 'void *':
256 [[#if defined __LP64__
265 # __riscv_float_abi_double:
266 # 'float' and 'double' are passed in floating-point registers.
267 # __riscv_float_abi_single:
268 # 'float' are passed in floating-point registers.
269 # __riscv_float_abi_soft:
270 # No values are passed in floating-point registers.
273 [[#if defined __riscv_float_abi_double
282 [[#if defined __riscv_float_abi_single
291 gl_cv_host_cpu_c_abi="${cpu}-${main_abi}${float_abi}"
295 # On s390x, the C compiler may be generating 64-bit (= s390x) code
296 # or 31-bit (= s390) code.
299 [[#if defined __LP64__ || defined __s390x__
305 [gl_cv_host_cpu_c_abi=s390x],
306 [gl_cv_host_cpu_c_abi=s390])
310 # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
311 # C compiler still generates 32-bit code.
314 [[#if defined __sparcv9 || defined __arch64__
320 [gl_cv_host_cpu_c_abi=sparc64],
321 [gl_cv_host_cpu_c_abi=sparc])
325 gl_cv_host_cpu_c_abi="$host_cpu"
330 dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.
331 HOST_CPU=`echo "$gl_cv_host_cpu_c_abi" | sed -e 's/-.*//'`
332 HOST_CPU_C_ABI="$gl_cv_host_cpu_c_abi"
334 AC_SUBST([HOST_CPU_C_ABI])
337 # AC_DEFINE_UNQUOTED([__${HOST_CPU}__])
338 # AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])
339 # earlier, but KAI C++ 3.2d doesn't like this.
340 sed -e 's/-/_/g' >> confdefs.h <<EOF
341 #ifndef __${HOST_CPU}__
342 #define __${HOST_CPU}__ 1
344 #ifndef __${HOST_CPU_C_ABI}__
345 #define __${HOST_CPU_C_ABI}__ 1
348 AH_TOP([/* CPU and C ABI indicator */
352 #ifndef __x86_64_x32__
353 #undef __x86_64_x32__
367 #ifndef __arm64_ilp32__
368 #undef __arm64_ilp32__
379 #ifndef __ia64_ilp32__
380 #undef __ia64_ilp32__
400 #ifndef __powerpc64__
403 #ifndef __powerpc64_elfv2__
404 #undef __powerpc64_elfv2__
412 #ifndef __riscv32_ilp32__
413 #undef __riscv32_ilp32__
415 #ifndef __riscv32_ilp32f__
416 #undef __riscv32_ilp32f__
418 #ifndef __riscv32_ilp32d__
419 #undef __riscv32_ilp32d__
421 #ifndef __riscv64_ilp32__
422 #undef __riscv64_ilp32__
424 #ifndef __riscv64_ilp32f__
425 #undef __riscv64_ilp32f__
427 #ifndef __riscv64_ilp32d__
428 #undef __riscv64_ilp32d__
430 #ifndef __riscv64_lp64__
431 #undef __riscv64_lp64__
433 #ifndef __riscv64_lp64f__
434 #undef __riscv64_lp64f__
436 #ifndef __riscv64_lp64d__
437 #undef __riscv64_lp64d__
459 dnl Sets the HOST_CPU_C_ABI_32BIT variable to 'yes' if the C language ABI
460 dnl (application binary interface) is a 32-bit one, or to 'no' otherwise.
461 dnl This is a simplified variant of gl_HOST_CPU_C_ABI.
462 AC_DEFUN([gl_HOST_CPU_C_ABI_32BIT],
464 AC_REQUIRE([AC_CANONICAL_HOST])
465 AC_CACHE_CHECK([32-bit host C ABI], [gl_cv_host_cpu_c_abi_32bit],
466 [if test -n "$gl_cv_host_cpu_c_abi"; then
467 case "$gl_cv_host_cpu_c_abi" in
468 i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc)
469 gl_cv_host_cpu_c_abi_32bit=yes ;;
471 gl_cv_host_cpu_c_abi_32bit=no ;;
479 gl_cv_host_cpu_c_abi_32bit=yes
483 # On x86_64 systems, the C compiler may be generating code in one of
485 # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.
486 # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64
487 # with native Windows (mingw, MSVC).
488 # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.
489 # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.
492 [[#if (defined __x86_64__ || defined __amd64__ \
493 || defined _M_X64 || defined _M_AMD64) \
494 && !(defined __ILP32__ || defined _ILP32)
500 [gl_cv_host_cpu_c_abi_32bit=no],
501 [gl_cv_host_cpu_c_abi_32bit=yes])
505 # Assume arm with EABI.
506 # On arm64 systems, the C compiler may be generating code in one of
508 # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.
509 # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.
510 # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.
513 [[#if defined __aarch64__ && !(defined __ILP32__ || defined _ILP32)
519 [gl_cv_host_cpu_c_abi_32bit=no],
520 [gl_cv_host_cpu_c_abi_32bit=yes])
523 hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )
524 # On hppa, the C compiler may be generating 32-bit code or 64-bit
525 # code. In the latter case, it defines _LP64 and __LP64__.
534 [gl_cv_host_cpu_c_abi_32bit=no],
535 [gl_cv_host_cpu_c_abi_32bit=yes])
539 # On ia64 on HP-UX, the C compiler may be generating 64-bit code or
540 # 32-bit code. In the latter case, it defines _ILP32.
549 [gl_cv_host_cpu_c_abi_32bit=yes],
550 [gl_cv_host_cpu_c_abi_32bit=no])
554 # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this
558 [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)
564 [gl_cv_host_cpu_c_abi_32bit=no],
565 [gl_cv_host_cpu_c_abi_32bit=yes])
569 # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.
570 # No need to distinguish them here; the caller may distinguish
571 # them based on the OS.
572 # On powerpc64 systems, the C compiler may still be generating
573 # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may
574 # be generating 64-bit code.
577 [[#if defined __powerpc64__ || defined _ARCH_PPC64
583 [gl_cv_host_cpu_c_abi_32bit=no],
584 [gl_cv_host_cpu_c_abi_32bit=yes])
588 gl_cv_host_cpu_c_abi_32bit=yes
592 # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.
593 # Size of 'long' and 'void *':
596 [[#if defined __LP64__
602 [gl_cv_host_cpu_c_abi_32bit=no],
603 [gl_cv_host_cpu_c_abi_32bit=yes])
607 # On s390x, the C compiler may be generating 64-bit (= s390x) code
608 # or 31-bit (= s390) code.
611 [[#if defined __LP64__ || defined __s390x__
617 [gl_cv_host_cpu_c_abi_32bit=no],
618 [gl_cv_host_cpu_c_abi_32bit=yes])
622 # UltraSPARCs running Linux have `uname -m` = "sparc64", but the
623 # C compiler still generates 32-bit code.
626 [[#if defined __sparcv9 || defined __arch64__
632 [gl_cv_host_cpu_c_abi_32bit=no],
633 [gl_cv_host_cpu_c_abi_32bit=yes])
637 gl_cv_host_cpu_c_abi_32bit=no
643 HOST_CPU_C_ABI_32BIT="$gl_cv_host_cpu_c_abi_32bit"