#!/bin/sh # # Check cpu of current machine and find the # best compiler optimization flags for gcc # Will return result in: # cpu_arg : Type of CPU # check_cpu_args : Arguments for GCC compiler settings # check_cpu () { CPUINFO=/proc/cpuinfo if test -n "$TEST_CPUINFO" ; then CPUINFO=$TEST_CPUINFO fi if test -r "$CPUINFO" -a "$CPUINFO" != " " ; then # on Linux (and others?) we can get detailed CPU information out of /proc cpuinfo="cat $CPUINFO" # detect CPU family cpu_family=`$cpuinfo | grep 'family' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` if test -z "$cpu_family" ; then cpu_family=`$cpuinfo | grep 'cpu' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` fi # detect CPU vendor and model cpu_vendor=`$cpuinfo | grep 'vendor_id' | cut -d ':' -f 2 | cut -d ' ' -f 2 | head -1` model_name=`$cpuinfo | grep 'model name' | cut -d ':' -f 2 | head -1` if test -z "$model_name" ; then model_name=`$cpuinfo | grep 'cpu model' | cut -d ':' -f 2 | head -1` fi # fallback: get CPU model from uname output if test -z "$model_name" ; then model_name=`uname -m` fi # parse CPU flags for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //' -e 's/[^a-zA-Z0-9_ ]/_/g'`; do eval cpu_flag_$flag=yes done else # Fallback when there is no /proc/cpuinfo CPUINFO=" " case "`uname -s`" in FreeBSD|OpenBSD) cpu_family=`uname -m`; model_name=`sysctl -n hw.model` ;; Darwin) cpu_family=`uname -p` model_name=`machine` ;; *) cpu_family=`uname -m`; model_name=`uname -p`; ;; esac fi # detect CPU shortname as used by gcc options # this list is not complete, feel free to add further entries cpu_arg="" case "$cpu_family--$model_name" in # DEC Alpha Alpha*EV6*) cpu_arg="ev6"; ;; # Intel ia32 *Intel*Core*|*X[eE][oO][nN]*) # a Xeon is just another pentium4 ... # ... unless it has the "lm" (long-mode) flag set, # in that case it's a Xeon with EM64T support # If SSE3 support exists it is a Core2 Duo or newer # So is Intel Core. if [ -z "$cpu_flag_lm" ]; then cpu_arg="pentium4" else cpu_arg="nocona" fi if test -z "$cpu_flag_ssse3" ; then core2="no" else core2="yes" fi ;; *Pentium*4*Mobile*) cpu_arg="pentium4m" ;; *Pentium*4*) cpu_arg="pentium4" ;; *Pentium*III*Mobile*) cpu_arg="pentium3m" ;; *Pentium*III*) cpu_arg="pentium3" ;; *Pentium*M*pro*) cpu_arg="pentium-m" ;; *Celeron\(R\)*\ M*) cpu_arg="pentium-m" ;; *Celeron*Coppermine*) cpu_arg="pentium3" ;; *Celeron\(R\)*) cpu_arg="pentium4" ;; *Celeron*) cpu_arg="pentium2" ;; *Turion*) cpu_arg="athlon64" ;; *Athlon*64*) cpu_arg="athlon64" ;; *Athlon*) cpu_arg="athlon" ;; *Opteron*) cpu_arg="opteron" ;; # MacOSX / Intel *i386*i486*) cpu_arg="pentium-m" ;; *i386*) cpu_arg="i386" ;; #Core 2 Duo *Intel*Core\(TM\)2*) cpu_arg="nocona" ;; # Intel ia64 *Itanium*) cpu_arg="itanium" ;; # Solaris Sparc *sparc*sun4u*) cpu_arg="sparc" ;; # Power PC *ppc*) cpu_arg="powerpc" ;; *powerpc*) cpu_arg="powerpc" ;; # unknown *) cpu_arg="" ;; esac if test -z "$cpu_arg" ; then if test "$CPUINFO" != " " ; then # fallback to uname if necessary TEST_CPUINFO=" " check_cpu_cflags="" check_cpu return fi echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." >&2 check_cpu_cflags="" return fi # different compiler versions have different option names # for CPU specific command line options if test -z "$CC" ; then cc="gcc"; else cc=$CC fi cc_ver=`$cc --version | sed 1q` cc_verno=`echo $cc_ver | sed -e 's/^.*gcc/gcc/g; s/[^0-9. ]//g; s/^ *//g; s/ .*//g'` set -- `echo $cc_verno | tr '.' ' '` cc_major=$1 cc_minor=$2 cc_patch=$3 cc_comp=`expr $cc_major '*' 100 '+' $cc_minor` case "$cc_ver--$cc_verno" in *GCC*) # different gcc backends (and versions) have different CPU flags case `gcc -dumpmachine` in i?86-* | x86_64-*) if test "$cc_comp" -lt 304 ; then check_cpu_cflags="-mcpu=${cpu_arg}" elif test "$cc_comp" -ge 402 ; then check_cpu_cflags="-mtune=native" else check_cpu_cflags="-mtune=${cpu_arg}" fi ;; ppc-*) check_cpu_cflags="-mcpu=${cpu_arg} -mtune=${cpu_arg}" ;; *) check_cpu_cflags="" return ;; esac ;; 2.95.*) # GCC 2.95 doesn't expose its name in --version output check_cpu_cflags="-m${cpu_arg}" ;; *) check_cpu_cflags="" return ;; esac # now we check whether the compiler really understands the cpu type touch __test.c if test "x$core2" = "xyes" ; then cpu_arg="core2" fi while [ "$cpu_arg" ] ; do printf "testing $cpu_arg ... " >&2 # compile check eval "$cc -c $check_cpu_cflags __test.c" 2>/dev/null if test "x$?" = "x0" ; then echo ok >&2 break; fi echo failed >&2 check_cpu_cflags="" break; done rm __test.* } check_cpu