1 dnl @synopsis AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
2 dnl @summary find target architecture name for gcc -march/-mtune flags
5 dnl This macro tries to guess the "native" arch corresponding to
6 dnl the target architecture for use with gcc's -march=arch or -mtune=arch
7 dnl flags. If found, the cache variable $ax_cv_gcc_archflag is set to this
8 dnl flag and ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is
9 dnl is set to "unknown" and ACTION-FAILURE is executed. The default
10 dnl ACTION-SUCCESS is to add $ax_cv_gcc_archflag to the end of $CFLAGS.
12 dnl PORTABLE? should be either [yes] (default) or [no]. In the former case,
13 dnl the flag is set to -mtune (or equivalent) so that the architecture
14 dnl is only used for tuning, but the instruction set used is still
15 dnl portable. In the latter case, the flag is set to -march (or equivalent)
16 dnl so that architecture-specific instructions are enabled.
18 dnl The user can specify --with-gcc-arch=<arch> in order to override
19 dnl the macro's choice of architecture, or --without-gcc-arch to
22 dnl When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
23 dnl called unless the user specified --with-gcc-arch manually.
25 dnl Requires macros: AX_CHECK_COMPILER_FLAGS, AX_GCC_X86_CPUID
27 dnl (The main emphasis here is on recent CPUs, on the principle that
28 dnl doing high-performance computing on old hardware is uncommon.)
30 dnl @version 2008-10-29
31 dnl @license GPLWithACException
32 dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Matteo Frigo.
33 AC_DEFUN([AX_GCC_ARCHFLAG],
34 [AC_REQUIRE([AC_PROG_CC])
35 AC_REQUIRE([AC_CANONICAL_HOST])
37 AC_ARG_WITH(gcc-arch, [AC_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
38 ax_gcc_arch=$withval, ax_gcc_arch=yes)
40 AC_MSG_CHECKING([for gcc architecture flag])
42 AC_CACHE_VAL(ax_cv_gcc_archflag,
44 ax_cv_gcc_archflag="unknown"
46 if test "$GCC" = yes; then
48 if test "x$ax_gcc_arch" = xyes; then
50 if test "$cross_compiling" = no; then
52 i[[3456]]86*|x86_64*|amd64*) # use cpuid codes, in part from x86info-1.21 by D. Jones
55 case $ax_cv_gcc_x86_cpuid_0 in
56 *:756e6547:*:*) # Intel
57 case $ax_cv_gcc_x86_cpuid_1 in
58 *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
59 *5??:*:*:*) ax_gcc_arch=pentium ;;
60 # This is an Intel core i3/i5/i7
61 *6[[520]]?:*:*:*) ax_gcc_arch="native nocona core2 prescott pentium4 pentiumpro" ;;
62 *6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
63 *6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
64 *6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
65 *6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
66 *6[[9d]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
67 *6[[e]]?:*:*:*) ax_gcc_arch="native pentium-m pentium3 pentiumpro" ;; # Core Duo
68 *6f?:*:*:*) ax_gcc_arch="core2 native pentium-m pentium3 pentiumpro" ;;
69 *6??:*:*:*) ax_gcc_arch="native pentiumpro" ;;
70 *f3[[347]]:*:*:*|*f4[[1347]]:*:*:*)
72 x86_64*|amd64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
73 *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
75 *f??:*:*:*) ax_gcc_arch="native pentium4 pentiumpro";;
78 case $ax_cv_gcc_x86_cpuid_1 in
79 *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
80 *5[[8c]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
81 *5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
82 *60?:*:*:*) ax_gcc_arch=k7 ;;
83 *6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
84 *6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
85 *67?:*:*:*) ax_gcc_arch="athlon-4 athlon k7" ;;
87 AX_GCC_X86_CPUID(0x80000006) # L2 cache size
88 case $ax_cv_gcc_x86_cpuid_0x80000006 in
89 *:*:*[[1-9a-f]]??????:*) # (L2 = ecx >> 16) >= 256
90 ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
91 *) ax_gcc_arch="athlon-4 athlon k7" ;;
93 *f[[4cef8b]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
94 *f5?:*:*:*) ax_gcc_arch="opteron k8" ;;
95 *f7?:*:*:*) ax_gcc_arch="athlon-fx opteron k8" ;;
96 *f??:*:*:*) ax_gcc_arch="native k8" ;;
99 case $ax_cv_gcc_x86_cpuid_1 in
100 *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
101 *58?:*:*:*) ax_gcc_arch=winchip2 ;;
102 *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
103 *69?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
106 if test x"$ax_gcc_arch" = x; then # fallback
108 i586*) ax_gcc_arch="native pentium" ;;
109 i686*) ax_gcc_arch="native pentiumpro" ;;
110 x86_64*|amd64*) ax_gcc_arch="native" ;;
116 AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
117 cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
118 cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
120 *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
121 *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
122 *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
123 *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
124 *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
125 *cypress*) ax_gcc_arch=cypress ;;
128 alphaev5) ax_gcc_arch=ev5 ;;
129 alphaev56) ax_gcc_arch=ev56 ;;
130 alphapca56) ax_gcc_arch="pca56 ev56" ;;
131 alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
132 alphaev6) ax_gcc_arch=ev6 ;;
133 alphaev67) ax_gcc_arch=ev67 ;;
134 alphaev68) ax_gcc_arch="ev68 ev67" ;;
135 alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
136 alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
137 alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
140 cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | sed 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
141 cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
143 *750*) ax_gcc_arch="750 G3" ;;
144 *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
145 *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
146 *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
147 *970*) ax_gcc_arch="970 G5 power4";;
148 *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
149 *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
150 603ev|8240) ax_gcc_arch="$cputype 603e 603";;
151 *Cell*) ax_gcc_arch="cellppu cell";;
152 *) ax_gcc_arch="$cputype native" ;;
154 ax_gcc_arch="$ax_gcc_arch powerpc"
157 fi # not cross-compiling
160 if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
161 for arch in $ax_gcc_arch; do
162 if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
164 # -mcpu=$arch and m$arch generate nonportable code on every arch except
165 # x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr.
166 case $host_cpu in i*86|x86_64*|amd64*) flags="$flags -mcpu=$arch -m$arch";; esac
168 flags="-march=$arch -mcpu=$arch -m$arch"
170 for flag in $flags; do
171 AX_CHECK_COMPILER_FLAGS($flag, [ax_cv_gcc_archflag=$flag; break])
173 test "x$ax_cv_gcc_archflag" = xunknown || break
179 AC_MSG_CHECKING([for gcc architecture flag])
180 AC_MSG_RESULT($ax_cv_gcc_archflag)
181 if test "x$ax_cv_gcc_archflag" = xunknown; then
184 m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
188 AC_DEFUN([AX_GCC_X86_CPUID],
189 [AC_REQUIRE([AC_PROG_CC])
191 AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
192 [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
193 int op = $1, eax, ebx, ecx, edx;
195 #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64)
196 __asm__("push %%rbx\n\t"
199 : "=a" (eax), "=c" (ecx), "=d" (edx)
201 __asm__("push %%rbx\n\t"
203 "mov %%rbx, %%rax\n\t"
205 : "=a" (ebx), "=c" (ecx), "=d" (edx)
208 __asm__("push %%ebx\n\t"
211 : "=a" (eax), "=c" (ecx), "=d" (edx)
213 __asm__("push %%ebx\n\t"
215 "mov %%ebx, %%eax\n\t"
217 : "=a" (ebx), "=c" (ecx), "=d" (edx)
220 f = fopen("conftest_cpuid", "w"); if (!f) return 1;
221 fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
225 [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
226 [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
227 [ax_cv_gcc_x86_cpuid_$1=unknown])])
231 AC_DEFUN([AX_CHECK_COMPILER_FLAGS],
232 [AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX
233 AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1])
234 dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname:
236 [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1), [
237 ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
238 _AC_LANG_PREFIX[]FLAGS="$1"
239 AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
240 AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes,
241 AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no)
242 _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])],
243 [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS
244 _AC_LANG_PREFIX[]FLAGS="$1"
245 AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
246 eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes,
247 eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no)
248 _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])
249 eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)
250 AC_MSG_RESULT($ax_check_compiler_flags)
251 if test "x$ax_check_compiler_flags" = xyes; then
256 ])dnl AX_CHECK_COMPILER_FLAGS