#!/bin/sh # # Check cpu of current machine and find the # best compiler optimization flags for gcc # 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 *Xeon*) # 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 [ -z "$cpu_flag_lm" ]; then cpu_arg="pentium4"; else cpu_arg="nocona"; 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"; ;; *Athlon*64*) cpu_arg="athlon64"; ;; *Turion*) cpu_arg="athlon64"; ;; *Opteron*) cpu_arg="athlon64"; ;; *Athlon*) cpu_arg="athlon"; ;; *Opteron*) cpu_arg="opteron"; ;; # MacOSX / Intel *i386*i486*) cpu_arg="pentium-m"; ;; #Core 2 Duo *Intel*Core\(TM\)2*) cpu_arg="nocona"; ;; # Intel ia64 *Itanium*) # Don't need to set any flags for itanium(at the moment) cpu_arg=""; ;; # *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)//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-*) if test "$cc_comp" -lt 304 then check_cpu_args='-mcpu=$cpu_arg' else check_cpu_args='-mtune=$cpu_arg' fi ;; ppc-*) check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg' ;; x86_64-*) if test "$cc_comp" -lt 304 then check_cpu_args='-mcpu=$cpu_arg' else check_cpu_args='-mtune=$cpu_arg' fi ;; *) check_cpu_cflags="" return ;; esac ;; 2.95.*) # GCC 2.95 doesn't expose its name in --version output check_cpu_args='-m$cpu_arg' ;; *) check_cpu_cflags="" return ;; esac # now we check whether the compiler really understands the cpu type touch __test.c while [ "$cpu_arg" ] ; do printf "testing $cpu_arg ... " >&2 # compile check check_cpu_cflags=`eval echo $check_cpu_args` if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then echo ok >&2 break; fi echo failed >&2 check_cpu_cflags="" # if compile failed: check whether it supports a predecessor of this CPU # this list is not complete, feel free to add further entries case "$cpu_arg" in # Intel ia32 nocona) cpu_arg=pentium4 ;; prescott) cpu_arg=pentium4 ;; pentium4m) cpu_arg=pentium4 ;; pentium4) cpu_arg=pentium3 ;; pentium3m) cpu_arg=pentium3 ;; pentium3) cpu_arg=pentium2 ;; pentium2) cpu_arg=pentiumpro ;; pentiumpro) cpu_arg=pentium ;; pentium) cpu_arg=i486 ;; i486) cpu_arg=i386 ;; # power / powerPC 7450) cpu_arg=7400 ;; *) cpu_arg="" ;; esac done rm __test.* } check_cpu