1dnl @synopsis AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
2dnl
3dnl @summary find target architecture name for gcc -march/-mtune flags
4dnl
5dnl This macro tries to guess the "native" arch corresponding to the
6dnl target architecture for use with gcc's -march=arch or -mtune=arch
7dnl flags. If found, the cache variable $ax_cv_gcc_archflag is set to
8dnl this flag and ACTION-SUCCESS is executed; otherwise
9dnl $ax_cv_gcc_archflag is is set to "unknown" and ACTION-FAILURE is
10dnl executed. The default ACTION-SUCCESS is to add $ax_cv_gcc_archflag
11dnl to the end of $CFLAGS.
12dnl
13dnl PORTABLE? should be either [yes] (default) or [no]. In the former
14dnl case, the flag is set to -mtune (or equivalent) so that the
15dnl architecture is only used for tuning, but the instruction set used
16dnl is still portable. In the latter case, the flag is set to -march
17dnl (or equivalent) so that architecture-specific instructions are
18dnl enabled.
19dnl
20dnl The user can specify --with-gcc-arch=<arch> in order to override
21dnl the macro's choice of architecture, or --without-gcc-arch to
22dnl disable this.
23dnl
24dnl When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
25dnl called unless the user specified --with-gcc-arch manually.
26dnl
27dnl Requires macros: AX_CHECK_COMPILER_FLAGS, AX_GCC_X86_CPUID
28dnl
29dnl (The main emphasis here is on recent CPUs, on the principle that
30dnl doing high-performance computing on old hardware is uncommon.)
31dnl
32dnl @category Misc
33dnl @author Steven G. Johnson <stevenj@alum.mit.edu> and Matteo Frigo.
34dnl @version 2006-01-04
35dnl @license GPLWithACException
36
37AC_DEFUN([AX_GCC_ARCHFLAG],
38[AC_REQUIRE([AC_PROG_CC])
39AC_REQUIRE([AC_CANONICAL_HOST])
40
41AC_ARG_WITH(gcc-arch, [AC_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
42	ax_gcc_arch=$withval, ax_gcc_arch=yes)
43
44AC_MSG_CHECKING([for gcc architecture flag])
45AC_MSG_RESULT([])
46AC_CACHE_VAL(ax_cv_gcc_archflag,
47[
48ax_cv_gcc_archflag="unknown"
49
50if test "$GCC" = yes; then
51
52if test "x$ax_gcc_arch" = xyes; then
53ax_gcc_arch=""
54if test "$cross_compiling" = no; then
55case $host_cpu in
56  i[[3456]]86*|x86_64*) # use cpuid codes, in part from x86info-1.7 by D. Jones
57     AX_GCC_X86_CPUID(0)
58     AX_GCC_X86_CPUID(1)
59     case $ax_cv_gcc_x86_cpuid_0 in
60       *:756e6547:*:*) # Intel
61          case $ax_cv_gcc_x86_cpuid_1 in
62	    *5[[48]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
63	    *5??:*:*:*) ax_gcc_arch=pentium ;;
64	    *6[[3456]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
65	    *6a?:*[[01]]:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
66	    *6a?:*[[234]]:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
67	    *6[[9d]]?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
68	    *6[[78b]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
69	    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;
70            *f3[[347]]:*:*:*|*f4[1347]:*:*:*)
71		case $host_cpu in
72                  x86_64*) ax_gcc_arch="nocona pentium4 pentiumpro" ;;
73                  *) ax_gcc_arch="prescott pentium4 pentiumpro" ;;
74                esac ;;
75            *f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro";;
76          esac ;;
77       *:68747541:*:*) # AMD
78          case $ax_cv_gcc_x86_cpuid_1 in
79	    *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
80	    *5[[8d]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
81	    *5[[9]]?:*:*:*) 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" ;;
86	    *6[[68a]]?:*:*:*)
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" ;;
92	       esac ;;
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="k8" ;;
97          esac ;;
98	*:746e6543:*:*) # IDT
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" ;;
104	   esac ;;
105     esac
106     if test x"$ax_gcc_arch" = x; then # fallback
107	case $host_cpu in
108	  i586*) ax_gcc_arch=pentium ;;
109	  i686*) ax_gcc_arch=pentiumpro ;;
110        esac
111     fi
112     ;;
113
114  sparc*)
115     AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
116     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`
117     cputype=`echo "$cputype" | tr -d ' -' |tr $as_cr_LETTERS $as_cr_letters`
118     case $cputype in
119         *ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
120         *ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
121         *ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
122         *supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
123         *hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
124         *cypress*) ax_gcc_arch=cypress ;;
125     esac ;;
126
127  alphaev5) ax_gcc_arch=ev5 ;;
128  alphaev56) ax_gcc_arch=ev56 ;;
129  alphapca56) ax_gcc_arch="pca56 ev56" ;;
130  alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
131  alphaev6) ax_gcc_arch=ev6 ;;
132  alphaev67) ax_gcc_arch=ev67 ;;
133  alphaev68) ax_gcc_arch="ev68 ev67" ;;
134  alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
135  alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
136  alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
137
138  powerpc*)
139     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`
140     cputype=`echo $cputype | sed -e 's/ppc//g;s/ *//g'`
141     case $cputype in
142       *750*) ax_gcc_arch="750 G3" ;;
143       *740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
144       *74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
145       *74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
146       *970*) ax_gcc_arch="970 G5 power4";;
147       *POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
148       *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
149       603ev|8240) ax_gcc_arch="$cputype 603e 603";;
150       *) ax_gcc_arch=$cputype ;;
151     esac
152     ax_gcc_arch="$ax_gcc_arch powerpc"
153     ;;
154esac
155fi # not cross-compiling
156fi # guess arch
157
158if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
159for arch in $ax_gcc_arch; do
160  if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
161    flags="-mtune=$arch"
162    # -mcpu=$arch and m$arch generate nonportable code on every arch except
163    # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.
164    case $host_cpu in i*86|x86_64*) flags="$flags -mcpu=$arch -m$arch";; esac
165  else
166    flags="-march=$arch -mcpu=$arch -m$arch"
167  fi
168  for flag in $flags; do
169    AX_CHECK_COMPILER_FLAGS($flag, [ax_cv_gcc_archflag=$flag; break])
170  done
171  test "x$ax_cv_gcc_archflag" = xunknown || break
172done
173fi
174
175fi # $GCC=yes
176])
177AC_MSG_CHECKING([for gcc architecture flag])
178AC_MSG_RESULT($ax_cv_gcc_archflag)
179if test "x$ax_cv_gcc_archflag" = xunknown; then
180  m4_default([$3],:)
181else
182  m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
183fi
184])
185