123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404 |
- #!/bin/sh
-
- # Print the gcc cpu specific options tailored for the current CPU
-
- # License: LGPLv2
- # Author:
- # http://www.pixelbeat.org/
- # Notes:
- # This script currently supports Linux,FreeBSD,Cygwin
- # This script is x86 (32 bit) specific
- # It should work on any gcc >= 2.95 at least
- # It only returns CPU specific options. You probably also want -03 etc.
- # Changes:
- # V0.1, 12 Mar 2003, Initial release
- # V0.2, 01 Jun 2005, Added support for 3.2>=gcc<=4.0
- # V0.3, 03 Jun 2005, Added support for pentium-m
- # V0.4, 03 Jun 2005, Fix silly bugs
- # V0.5, 07 Jun 2005, Clarify/Simplify confusing floating point expr usage
- # Print warning when CPU only supported on a newer gcc
- # V0.6, 15 Dec 2006, Added support for Intel Core and Core 2 processors
- # Added support for 4.1>=gcc<=4.3
- # Added support for gcc -msse3 option
- # Added support for new gcc -march=native option
- # V0.7, 18 Dec 2006, Changes from Conor McDermottroe
- # Added support for FreeBSD
- # Remove bash specific constructs
- # Better error handling
- # V0.8, 19 Dec 2006, Give warnings and 32 bit -march on 64 bit platforms.
- # Previously it just gave an invalid blank -march.
- # Reported and tested by Ewan Oughton.
- # V0.9, 30 Apr 2007, Give error if compiler not present.
- # Warn about rather than default to -march=native option.
- # V0.92, 08 Nov 2007, Change from Krzysztof Jankowski to support Cygwin.
- # Added support for AMD family 10 processors.
- # Add support for gcc -msse4 & -msse5 options.
- # Use "prescott" rather than "pentium4" for all
- # models >= 3 in intel family 15, not just model 3.
- # V0.93, 13 Nov 2007, Oops, actually not all intel family 15, model >= 3
- # are prescotts. Use the sse3 flag to distinguish.
- # V0.94, 31 Dec 2007, Oops, actually all intel family 15, model >= 3
- # are prescotts. This was indicated by Adam Drzewiecki.
- # I was confused by a bug in older linux kernels where pni
- # was not reported for my intel "F41" processor at least.
- # V0.95, 18 Jan 2008, Changes from Conor McDermottroe
- # Support for Mac OS X
- # Support for FreeBSD base system
- # V0.96, 17 Dec 2008, Following a report from Alfredo Pons, add support
- # for newer intel core2 processors (models 23,26,29,...)
- # by assuming models >= 15 are core2.
- # Report details of unrecognised CPUs.
- # V0.97, 19 Dec 2008, Use prescott for Intel Atom (model 28).
- # Ensure all errors are output to stderr.
- # V0.98, 24 Feb 2009, Actually Intel Atom (model 28) is core2 ISA compliant.
- # It's an in-order core (like i586) so mtune as such.
- # V0.99, 30 Apr 2009, Intel Atom (model 28) is getting a corresponding "atom"
- # option in GCC 4.5
- # V0.99.3, 11 Aug 2009, Support for AMD Geode LX processor.
- # V0.99.4, 24 Oct 2009, Following a report from Maxime de Roucy, add support
- # for AMD family 17 (griffin).
- # V0.99.12, 22 Oct 2013
- # http://github.com/pixelb/scripts/commits/master/scripts/gcccpuopt
-
- if [ "$1" = "--version" ]; then
- echo "0.99.12" && exit
- fi
-
- # This table shows when -march options were introduced into _official_ gcc releases.
- # Note there are vendor deviations that complicate this.
- # For e.g. Red Hat introduced the prescott option in 3.3-13.
- # gcc-2.95 = i386, i486, i586,pentium, i686,pentiumpro, k6
- # gcc-3.0 += athlon
- # gcc-3.1 += pentium-mmx, pentium2, pentium3, pentium4, k6-2, k6-3, athlon-{tbird, 4,xp,mp}
- # gcc-3.3 += winchip-c6, winchip2, c3
- # gcc-3.4.0 += k8,opteron,athlon64,athlon-fx, c3-2
- # gcc-3.4.1 += pentium-m, pentium3m, pentium4m, prescott, nocona
- # gcc-4.3 += core2, amdfam10, geode
- # gcc-4.5 += atom
- # gcc-4.6 += corei7, corei7-avx, bdver1, btver1
- # gcc-4.7 += core-avx-i, core-avx2, bdver2
- # gcc-4.8 += btver2
-
- [ -z "$CC" ] && CC=gcc
-
- try_gcc_options() {
- $CC $* -S -o /dev/null -xc /dev/null >/dev/null 2>&1
- }
-
- if ! try_gcc_options; then
- echo "Error: Couldn't execute your compiler ($CC)" >&2
- exit 1
- fi
-
- if try_gcc_options -march=native; then
- echo "Warning: Your compiler supports the -march=native option which you may prefer" >&2
- #gcc -march=native --verbose -xc /dev/null 2>&1 | sed -n 's|.*/dev/null \(-march.*-mtune[^ ]*\).*|\1|p' >&2
- fi
-
- if ! try_gcc_options -march=i386; then
- if ! try_gcc_options -m32 -march=i386; then
- echo "Error: This script only supports 32 bit x86 architectures" >&2
- exit 1
- else
- echo "Warning: The optimum *32 bit* architecture is reported" >&2
- m32="-m32 "
- fi
- fi
-
- try_line() {
- skip=0
- for arch in $1; do
- if try_gcc_options $m32 -march=$arch; then
- echo $arch
- return
- elif [ "$skip" = "0" ] && [ "$arch" != "native" ]; then
- skip=1
- echo "Warning: Newer versions of GCC better support your CPU with -march=$arch" >&2
- fi
- done
- return 1
- }
-
- read_cpu_data_linux() {
- IFS=":"
- while read name value; do
- unset IFS
- name=`echo $name` #strip spaces
- value=`echo $value` #strip spaces
- if [ "$name" = "vendor_id" ]; then
- value=`echo $value | sed 's/\([^ ]*\).*/\1/'` #take first word
- fi
- IFS=":"
- if [ "$name" = "vendor_id" ]; then
- vendor_id="$value"
- elif [ "$name" = "cpu family" ]; then
- cpu_family="$value"
- elif [ "$name" = "model" ]; then
- cpu_model="$value"
- elif [ "$name" = "flags" ]; then
- flags="$value"
- break #flags last so break early
- fi
- done < /proc/cpuinfo
- unset IFS
- }
-
- read_cpu_data_freebsd() {
- local _line _cpu_id
-
- if [ ! -r /var/run/dmesg.boot ]; then
- echo "Error: /var/run/dmesg.boot does not exist!" >&2
- exit 1;
- fi
-
- IFS="
- "
- for _line in `grep -A2 '^CPU: ' /var/run/dmesg.boot`; do
- if [ -n "`echo $_line | grep '^ Origin = '`" ]; then
- vendor_id="`echo $_line | sed -e 's/^ Origin = .//' -e 's/[^A-Za-z0-9].*$//'`"
- _cpu_id="`echo $_line | sed -e 's/^.*Id = //' -e 's/ .*$//' -e 'y/abcdef/ABCDEF/'`"
- cpu_family=$(( ($_cpu_id & 0xF0F) >> 8 )) #FreeBSD 5.0 sh doesn't support 0x
- cpu_model=$(( (($_cpu_id & 0xF0) >> 4) + (($_cpu_id & 0xF0000) >> 12) ))
- fi
- if [ -n "`echo $_line | grep '^ Features='`" ]; then
- flags="`echo $_line | sed -e 's/^.*<//' -e 's/>.*//' -e 's/,/ /g' | tr 'A-Z' 'a-z'`"
- fi
- done
- unset IFS
- }
-
- read_cpu_data_darwin() {
- vendor_id="`/usr/sbin/sysctl -n machdep.cpu.vendor`"
- cpu_family="`/usr/sbin/sysctl -n machdep.cpu.family`"
- cpu_model="`/usr/sbin/sysctl -n machdep.cpu.model`"
- flags="`/usr/sbin/sysctl -n machdep.cpu.features | tr 'A-Z' 'a-z'`"
- }
-
- read_cpu_data() {
- # Default values
- vendor_id="NotFound"
- cpu_family="-1"
- cpu_model="-1"
- flags=""
- case "$(uname)" in
- Linux|CYGWIN*)
- read_cpu_data_linux ;;
- FreeBSD)
- read_cpu_data_freebsd ;;
- Darwin)
- read_cpu_data_darwin ;;
- *)
- echo "Error: $(uname) is not a supported operating system" >&2
- exit 1 ;;
- esac
- }
-
- read_cpu_data
-
- if [ "$vendor_id" = "AuthenticAMD" ]; then
- if [ $cpu_family -eq 4 ]; then
- _CFLAGS="-march=i486"
- elif [ $cpu_family -eq 5 ]; then
- if [ $cpu_model -lt 4 ]; then
- _CFLAGS="-march=pentium"
- elif [ \( $cpu_model -eq 6 \) -o \( $cpu_model -eq 7 \) ]; then
- _CFLAGS="-march=k6"
- elif [ \( $cpu_model -eq 8 \) -o \( $cpu_model -eq 12 \) ]; then
- line="k6-2 k6"
- elif [ \( $cpu_model -eq 9 \) -o \( $cpu_model -eq 13 \) ]; then
- line="k6-3 k6-2 k6"
- elif [ $cpu_model -eq 10 ]; then #geode LX
- line="geode k6-2 k6"
- #The LX supports 3dnowext in addition to the k6-2 instructions,
- #however gcc doesn't support explicitly selecting that.
- fi
- elif [ $cpu_family -eq 6 ]; then
- if [ $cpu_model -le 3 ]; then
- line="athlon k6-3 k6-2 k6"
- elif [ $cpu_model -eq 4 ]; then
- line="athlon-tbird athlon k6-3 k6-2 k6"
- elif [ $cpu_model -ge 6 ]; then #athlon-{4,xp,mp} (also geode NX)
- line="athlon-4 athlon k6-3 k6-2 k6"
- fi
- elif [ $cpu_family -eq 15 ]; then #k8,opteron,athlon64,athlon-fx
- line="k8 athlon-4 athlon k6-3 k6-2 k6"
- elif [ $cpu_family -eq 16 ] || #barcelona,amdfam10
- [ $cpu_family -eq 17 ] || #griffin
- [ $cpu_family -eq 18 ]; then #llano
- line="amdfam10 k8 athlon-4 athlon k6-3 k6-2 k6"
- elif [ $cpu_family -eq 20 ]; then #bobcat
- line="btver1 amdfam10 k8 athlon-4 athlon k6-3 k6-2 k6"
- elif [ $cpu_family -eq 21 ]; then #bulldozer
- if echo "$flags" | grep -q bmi; then #piledriver
- line="bdver2 bdver1 btver1 amdfam10 k8 athlon-4 athlon k6-3 k6-2 k6"
- else
- line="bdver1 btver1 amdfam10 k8 athlon-4 athlon k6-3 k6-2 k6"
- fi
- elif [ $cpu_family -eq 22 ]; then #jaguar
- line="btver2 btver1 amdfam10 k8 athlon-4 athlon k6-3 k6-2 k6"
- fi
- elif [ "$vendor_id" = "CentaurHauls" ]; then
- if [ $cpu_family -eq 5 ]; then
- if [ $cpu_model -eq 4 ]; then
- line="winchip-c6 pentium"
- elif [ $cpu_model -eq 8 ]; then
- line="winchip2 winchip-c6 pentium"
- elif [ $cpu_model -ge 9 ]; then
- line="winchip2 winchip-c6 pentium" #actually winchip3 but gcc doesn't support this currently
- fi
- elif [ $cpu_family -eq 6 ]; then
- if echo "$flags" | grep -q cmov; then
- fallback=pentiumpro
- else
- fallback=pentium #gcc incorrectly assumes i686 always has cmov
- fi
- if [ $cpu_model -eq 6 ]; then
- _CFLAGS="-march=pentium" # ? Cyrix 3 (samuel)
- elif [ $cpu_model -eq 7 ] || [ $cpu_model -eq 8 ]; then
- line="c3 winchip2 winchip-c6 $fallback"
- elif [ $cpu_model -ge 9 ]; then
- line="c3-2 c3 winchip2 winchip-c6 $fallback"
- fi
- fi
- elif [ "$vendor_id" = "GenuineIntel" ]; then
- if [ $cpu_family -eq 3 ]; then
- _CFLAGS="-march=i386"
- elif [ $cpu_family -eq 4 ]; then
- _CFLAGS="-march=i486"
- elif [ $cpu_family -eq 5 ]; then
- if [ $cpu_model -ne 4 ]; then
- _CFLAGS="-march=pentium"
- else
- line="pentium-mmx pentium" #No overlap with other vendors
- fi
- elif [ $cpu_family -eq 6 ]; then
- if [ \( $cpu_model -eq 0 \) -o \( $cpu_model -eq 1 \) ]; then
- _CFLAGS="-march=pentiumpro"
- elif [ \( $cpu_model -ge 2 \) -a \( $cpu_model -le 6 \) ]; then #4=TM5600 at least
- line="pentium2 pentiumpro pentium-mmx pentium i486 i386"
- if [ \( $cpu_model -eq 2 \) ]; then #qemu generic
- echo "\
- Warning: Unspecified QEMU CPU model.
- Please consider upgrading QEMU or configuring it to use a specific model." >&2
- fi
- elif [ \( $cpu_model -eq 9 \) -o \( $cpu_model -eq 13 \) ]; then #centrino
- line="pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ \( $cpu_model -eq 14 \) ]; then #Core
- line="prescott pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ $cpu_model -eq 28 ] || # pine
- [ $cpu_model -eq 38 ] || # oak
- [ $cpu_model -eq 54 ]; then # cedar
- line="atom core2 pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ $cpu_model -eq 26 ] ||
- [ $cpu_model -eq 30 ] ||
- [ $cpu_model -eq 31 ] ||
- [ $cpu_model -eq 46 ] ||
- # ^ Nehalem ^
- [ $cpu_model -eq 37 ] ||
- [ $cpu_model -eq 44 ] ||
- [ $cpu_model -eq 47 ]; then
- # ^ Westmere ^
- line="corei7 core2 pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ $cpu_model -eq 42 ] || #Sandy Bridge
- [ $cpu_model -eq 45 ]; then #Sandy Bridge E
- line="corei7-avx corei7 core2 pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ $cpu_model -eq 58 ] || #Ivy Bridge
- [ $cpu_model -eq 62 ]; then #Ivy Bridge E
- line="core-avx-i corei7-avx corei7 core2 pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ $cpu_model -eq 60 ] || #Haswell
- [ $cpu_model -eq 63 ]; then #Haswell E
- line="core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ $cpu_model -eq 15 ] ||
- # ^ Merom ^
- [ $cpu_model -eq 22 ] ||
- # ^ Conroe-L ^
- [ $cpu_model -eq 23 ] ||
- [ $cpu_model -eq 29 ]; then
- # ^ Penryn ^
- line="core2 pentium-m pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- elif [ \( $cpu_model -ge 7 \) -a \( $cpu_model -le 11 \) ]; then
- line="pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- fi
- elif [ $cpu_family -eq 15 ]; then
- line="pentium4 pentium3 pentium2 pentiumpro pentium-mmx pentium i486 i386"
- if [ $cpu_model -ge 3 ]; then
- line="prescott $line"
- fi
- fi
- elif [ "$vendor_id" = "Geode" ]; then #by NSC
- if [ $cpu_family -eq 5 ]; then
- if [ \( $cpu_model -eq 4 \) -o \( $cpu_model -eq 9 \) ]; then
- # Note both models 4 and 9 have cmov.
- # In addition, model 9 has cxmmx.
- # Note also, the "geode" gcc arch is for newer AMD geode cores
- # and is not appropriate for this older core.
- line="pentium-mmx pentium"
- fi
- fi
- fi
-
- if [ \( -z "$_CFLAGS" \) -a \( -z "$line" \) ]; then
- echo "\
- Unrecognised CPU. Please email the following to: P@draigBrady.com
- Vendor:$vendor_id family:$cpu_family model:$cpu_model
- flags:$flags" >&2
- exit 1
- fi
-
- [ -z "$_CFLAGS" ] && _CFLAGS="-march=`try_line "$line"`"
-
- #The Atom CPU supports the full core2 instruction set,
- #but it's an in-order core, the last one of those being the i586.
- #Therefore if gcc hasn't explicit support for the Atom,
- #tune it for the i586 architecture.
- if ! echo "$_CFLAGS" | grep -q "atom"; then #gcc hasn't specific Atom support
- if echo "$line" | grep -q "core2"; then #atom ISA line
- if [ $cpu_model -eq 28 ]; then #atom
- if echo "$_CFLAGS" | grep -E -q "(core2|pentium[^ ])"; then #gcc chose out of order arch
- _CFLAGS="$_CFLAGS -mtune=pentium" #tune for last in-order core
- fi
- fi
- fi
- fi
-
- #SSE is not used for floating point by default in gcc 32 bit
- #so turn that on here.
- if echo "$flags" | grep -q "sse"; then
- if try_gcc_options "-mfpmath=sse"; then #gcc >= 3.1
- _CFLAGS="$_CFLAGS -mfpmath=sse"
- fi
- fi
-
- #The SSE options are mostly selected automatically
- #when a particular march option is selected.
- #There are a few exceptions unfortunately, which we handle here.
- #Note the sse instruction lines are:
- # intel: [sse4.2] [sse4.1] ssse3 sse3 sse2 sse ...
- # amd: [sse5] sse4a [sse3] sse2 sse ...
- # The bracketed ones are only available on some cpus
- # in a particular family and so need to be added explicitly.
- if echo "$_CFLAGS" | grep -q "amdfam10"; then
- if echo "$flags" | grep -q "sse5"; then
- if try_gcc_options "-msse5"; then #gcc >= 4.3
- _CFLAGS="$_CFLAGS -msse5"
- fi
- fi
- elif echo "$_CFLAGS" | grep -E -q "(k8|c3-2)"; then
- if echo "$flags" | grep -E -q "(sse3|pni)"; then
- if try_gcc_options "-msse3"; then #gcc >= 3.3.3
- _CFLAGS="$_CFLAGS -msse3"
- fi
- fi
- elif echo "$_CFLAGS" | grep -q "core2"; then
- if echo "$flags" | grep -q "sse4_2"; then
- if try_gcc_options "-msse4"; then #gcc >= 4.3
- _CFLAGS="$_CFLAGS -msse4"
- fi
- elif echo "$flags" | grep -q "sse4_1"; then
- if try_gcc_options "-msse4.1"; then #gcc >= 4.3
- _CFLAGS="$_CFLAGS -msse4.1"
- fi
- fi
- fi
-
- echo "$m32$_CFLAGS"
|