#!/usr/bin/env perl # # CPUflags provides database for cpuflags (with and without # optimisation) for different operating systems and processors. # By autodetecting the current CPU, optimal cflags for the # target system are returned. # # supported platforms : Linux, Solaris, AIX, IRIX, # Darwin, Tru64, HP-UX, Win32 # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation (version 2 of the License). # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # use Getopt::Long; ############################################################### ############################################################### ## ## default settings ## ############################################################### ############################################################### $system = ""; $cpu = $ENV{"PROCESSOR"}; $bits = 64; $show_cpu = "0"; $show_cflags = "1"; $show_opt = "0"; $compiler = "cc"; $compversion = ""; $compsubver = 0; $version = "0.7.0"; $verbosity = 0; $cflags = ""; $oflags = "-O"; ############################################################### ############################################################### ## ## misc. functions ## ############################################################### ############################################################### ############################################################### # # print error message # sub error { print( stderr $_[0] ); } ############################################################### # # show usage # sub usage { print "cpuflags v$version by Ronald Kriemann\n"; print "usage: cpuflags [ options ] \n"; print " where options include :\n"; print " --cpu : show flags for given cpu-identifier (default autodetect)\n"; print " --comp : set compiler to use (default: cc)\n"; print " --showcpu : print CPU identifier (default off)\n"; print " --[no]cflags : (don't) print compiler flags (default on)\n"; print " --[no]opt : (don't) print optimisation flags (default off)\n"; print " -32|-64 : set bitsize (default: max. available)\n"; print " -h, --help : print this message\n"; print " -v, --verbose [int] : verbosity level (default 0)\n"; print " -V, --version : print version number\n"; print "\n"; print " Supported systems and compilers:\n"; print " Linux : gcc-[234].x, icc-[5678], pgi\n"; print " Solaris : gcc-[234].x, Sun-CC-5.x, kcc\n"; print " AIX : gcc, xlC\n"; print " IRIX : gcc, mipscc\n"; print " Darwin : gcc-[234].x\n"; print " Tru64 : Compaq-CC-6.x\n"; print " HP-UX : HP Ansi C 3.x \n"; print " Win32 : MS Visual C/C++ 14.x\n"; print "\n"; print " Supported CPUs:\n"; print " Linux : i386, i486, i586, pentium, pentium-mmx, pentium-pro,\n"; print " p2, p3, p3-sse, p3-xeon, centrino, p4, p4-(w|p|n|f),\n"; print " k6, k6-2, k6-3, athlon, athlon-tbird, athlon-xp,\n"; print " opteron, via-c3a, ppc750, ppc7450\n"; print " Solaris : ultra1, ultra2, ultra3, ultra3cu\n"; print " AIX : power4\n"; print " IRIX : mips4\n"; print " Darwin : ppc750, ppc7400, ppc7450, ppc970\n"; print " Tru64 : ev5, ev56, ev6, ev67\n"; print " HP-UX : PA7xxx, PA8xxx\n"; print " Win32 : native\n"; print "\n"; exit 0; } ############################################################### # # parse command-line # sub parse_cmdline { my $help, $show_version, $bit32, $bit64; my %options = ( 'cpu=s' => \$cpu, 'showcpu' => \$show_cpu, 'cflags!' => \$show_cflags, 'opt!' => \$show_oflags, 'comp=s' => \$compiler, 'h|help' => \$help, 'v|verbose:i' => \$verbosity, 'V|version' => \$show_version, '32' => \$bit32, '64' => \$bit64 ); Getopt::Long::Configure( "no_ignore_case", "pass_through", "no_auto_abbrev" ); GetOptions( %options ) || usage; usage if $help; if ( $show_version ) { print "cpuflags v$version by Ronald Kriemann\n"; exit 0; } $bits = 32 if ( $bit32 ); $bits = 64 if ( $bit64 ); } ############################################################### ############################################################### ## ## setup compiler-flags ## ############################################################### ############################################################### ############################################################### # # setup basic CFLAGS # sub set_cflags { if ( $system =~ /Linux|CYGWIN/ ) { if ( $compversion =~ /gcc-2/ ) { for ( $cpu ) { if ( /i386/ ) { $cflags = "-march=i386"; } elsif ( /i486/ ) { $cflags = "-march=i486"; } elsif ( /i586|pentium($|-mmx)/ ) { $cflags = "-march=i586"; } elsif ( /via-c3/ ) { $cflags = "-march=i586"; } elsif ( /k6/ ) { $cflags = "-march=k6"; } elsif ( /pentiumpro|p2|p3|p4/ ) { $cflags = "-march=i686"; } elsif ( /athlon|opteron/ ) { $cflags = "-march=i686"; } elsif ( /ppc750/ ) { $cflags = "-mcpu=750 -mpowerpc-gfxopt -fsigned-char"; } elsif ( /ppc7400/ ) { $cflags = "-mcpu=7400 -mpowerpc-gfxopt -fsigned-char" } elsif ( /ppc7450/ ) { $cflags = "-mcpu=7450 -mpowerpc-gfxopt -fsigned-char" } elsif ( /itanium2/ ) { $cflags = " "; } } } elsif ( $compversion =~ /gcc-3.[0123]/ ) { for ( $cpu ) { if ( /i386/ ) { $cflags = "-march=i386"; } elsif ( /i486/ ) { $cflags = "-march=i486"; } elsif ( /i586|pentium/ ) { $cflags = "-march=i586"; } elsif ( /k6$/ ) { $cflags = "-march=k6"; } elsif ( /k6-2/ ) { $cflags = "-march=k6-2"; } elsif ( /k6-3/ ) { $cflags = "-march=k6-3"; } elsif ( /pentium-mmx/ ) { $cflags = "-march=pentium-mmx"; } elsif ( /pentiumpro/ ) { $cflags = "-march=i686"; } elsif ( /p2/ ) { $cflags = "-march=pentium2"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "-march=pentium3 -mfpmath=sse"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "-march=pentium3"; } elsif ( /centrino/ ) { $cflags = "-march=pentium3 -mfpmath=sse"; } elsif ( /p4/ ) { $cflags = "-march=pentium4 -mfpmath=sse"; } elsif ( /athlon-tbird/ ) { $cflags = "-march=athlon-tbird"; } elsif ( /athlon-xp/ ) { $cflags = "-march=athlon-xp -msse -mfpmath=sse,387"; } elsif ( /athlon/ ) { $cflags = "-march=athlon"; } elsif ( /opteron/ ) { $cflags = "-march=opteron -m$bits -mfpmath=sse,387"; } elsif ( /via-c3a/ ) { $cflags = "-march=c3 -msse -mfpmath=sse"; } elsif ( /ppc750/ ) { $cflags = "-mcpu=750 -mpowerpc-gfxopt -fsigned-char"; } elsif ( /ppc7400/ ) { $cflags = "-mcpu=7400 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /ppc7450/ ) { $cflags = "-mcpu=7450 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /itanium2/ ) { $cflags = " "; } } } elsif ( $compversion =~ /gcc-(3.4|4.?)/ ) { for ( $cpu ) { if ( /i386/ ) { $cflags = "-march=i386"; } elsif ( /i486/ ) { $cflags = "-march=i486"; } elsif ( /i586|pentium/ ) { $cflags = "-march=i586"; } elsif ( /k6$/ ) { $cflags = "-march=k6"; } elsif ( /k6-2/ ) { $cflags = "-march=k6-2"; } elsif ( /k6-3/ ) { $cflags = "-march=k6-3"; } elsif ( /pentium-mmx/ ) { $cflags = "-march=pentium-mmx"; } elsif ( /pentiumpro/ ) { $cflags = "-march=i686"; } elsif ( /p2/ ) { $cflags = "-march=pentium2"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "-march=pentium3 -mfpmath=sse"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "-march=pentium3"; } elsif ( /centrino/ ) { $cflags = "-march=pentium-m -msse2 -mfpmath=sse"; } elsif ( /p4-p/ ) { $cflags = "-march=prescott -msse3 -mfpmath=sse"; } elsif ( /p4-n/ ) { $cflags = "-march=nocona -msse3 -mfpmath=sse"; } elsif ( /p4/ ) { $cflags = "-march=pentium4 -msse2 -mfpmath=sse"; } elsif ( /athlon-tbird/ ) { $cflags = "-march=athlon-tbird"; } elsif ( /athlon-xp/ ) { $cflags = "-march=athlon-xp -msse -mfpmath=sse,387"; } elsif ( /athlon/ ) { $cflags = "-march=athlon"; } elsif ( /opteron/ ) { $cflags = "-march=opteron -m$bits -mfpmath=sse,387"; } elsif ( /via-c3a/ ) { $cflags = "-march=c3 -msse -mfpmath=sse"; } elsif ( /ppc750/ ) { $cflags = "-mcpu=750 -mpowerpc-gfxopt -fsigned-char"; } elsif ( /ppc7400/ ) { $cflags = "-mcpu=7400 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /ppc7450/ ) { $cflags = "-mcpu=7450 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /itanium2/ ) { $cflags = " "; } } } elsif ( $compversion =~ /icc-[567]/ ) { for ( $cpu ) { if ( /pentium$/ ) { $cflags = "-tpp5"; } elsif ( /pentium-mmx/ ) { $cflags = "-tpp5 -xM"; } elsif ( /k6/ ) { $cflags = "-tpp5 -xM"; } elsif ( /pentiumpro/ ) { $cflags = "-tpp6"; } elsif ( /p2/ ) { $cflags = "-tpp6 -xM"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "-tpp6 -march=pentiumiii -xK"; } elsif ( /p3/ ) { $cflags = "-tpp6 -march=pentiumii -xM"; } elsif ( /centrino/ ) { $cflags = "-tpp7 -xB"; } elsif ( /p4/ ) { $cflags = "-tpp7 -xW"; } elsif ( /athlon-xp/ ) { $cflags = "-tpp6 -xK"; } elsif ( /athlon/ ) { $cflags = "-tpp6 -xM"; } elsif ( /opteron/ ) { $cflags = "-tpp7 -xW"; } elsif ( /via-c3a/ ) { $cflags = "-tpp5 -xK"; } elsif ( /itanium2/ ) { $cflags = "-tpp2"; } } } elsif ( $compversion =~ /icc-[89]/ ) { for ( $cpu ) { if ( /pentium|k6/ ) { $cflags = "-tpp5"; } elsif ( /pentiumpro/ ) { $cflags = "-tpp6"; } elsif ( /p2/ ) { $cflags = "-tpp6"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "-tpp6 -march=pentiumiii -xK"; } elsif ( /p3/ ) { $cflags = "-tpp6 -march=pentiumii"; } elsif ( /centrino/ ) { $cflags = "-tpp7 -xB"; } elsif ( /p4-n/ ) { $cflags = "-tpp7 -xN"; } elsif ( /p4-(p|f)/ ) { $cflags = "-tpp7 -xP"; } elsif ( /p4/ ) { $cflags = "-tpp7 -xW"; } elsif ( /athlon-xp/ ) { $cflags = "-tpp6 -xK"; } elsif ( /athlon/ ) { $cflags = "-tpp6 -march=pentiumii"; } elsif ( /opteron/ ) { $cflags = "-tpp7 -xW"; } elsif ( /via-c3a/ ) { $cflags = "-tpp5 -xK"; } elsif ( /itanium2/ ) { $cflags = "-tpp2"; } } } elsif ( $compversion =~ /pgi/ ) { for ( $cpu ) { if ( /i386|i486|i586/ ) { $cflags = "-tp px"; } elsif ( /pentium($|-mmx)/ ) { $cflags = "-tp p5"; } elsif ( /pentiumpro|p2|p3/ ) { $cflags = "-tp p6"; } elsif ( /p4/ ) { $cflags = "-tp p7"; } elsif ( /athlon/ ) { $cflags = "-tp p6"; } elsif ( /opteron/ ) { $cflags = "-tp k8-$bits"; } elsif ( /via-c3a/ ) { $cflags = "-tp p5"; } } } elsif ( $compversion =~ /path-2/ ) { for ( $cpu ) { if ( /i386|i486|i586/ ) { $cflags = "-march=anyx86"; } elsif ( /pentium($|-mmx)/ ) { $cflags = "-march=anyx86"; } elsif ( /pentiumpro|p2|p3/ ) { $cflags = "-march=anyx86"; } elsif ( /athlon/ ) { $cflags = "-march=anyx86"; } elsif ( /via-c3a/ ) { $cflags = "-march=anyx86"; } elsif ( /p4/ ) { $cflags = "-march=pentium4"; } elsif ( /opteron/ ) { $cflags = "-march=opteron -m$bits"; } } } else { error( "cpuflags: unsupported compiler ($compversion)\n" ); } } elsif ( $system eq "Solaris" ) { if ( $compversion =~ /gcc-2/ ) { if ( $cpu =~ /ultra[123]/ ) { $cflags = "-mcpu=ultrasparc"; } } elsif ( $compversion =~ /gcc-(3|4)/ ) { for ( $cpu ) { if ( /ultra[12]/ ) { $cflags = "-mcpu=ultrasparc -m$bits"; } elsif ( /ultra3/ ) { $cflags = "-mcpu=ultrasparc3 -m$bits"; } } } elsif ( $compversion =~ /suncc-5.[0123]|kcc/ ) { if ( $bits == 32 ) { for ( $cpu ) { if ( /ultra1/ ) { $cflags = "-xtarget=ultra -xarch=v8"; } elsif ( /ultra2/ ) { $cflags = "-xtarget=ultra2 -xarch=v8plusa"; } elsif ( /ultra3/ ) { $cflags = "-xtarget=ultra3 -xarch=v8plusb"; } } } elsif ( $bits == 64 ) { for ( $cpu ) { if ( /ultra1/ ) { $cflags = "-xtarget=ultra -xarch=v9"; } elsif ( /ultra2/ ) { $cflags = "-xtarget=ultra2 -xarch=v9a"; } elsif ( /ultra3/ ) { $cflags = "-xtarget=ultra3 -xarch=v9b"; } } } } elsif ( $compversion =~ /suncc-5.[45678]/ ) { if ( $bits == 32 ) { for ( $cpu ) { if ( /ultra1/ ) { $cflags = "-xtarget=ultra -xarch=v8"; } elsif ( /ultra2/ ) { $cflags = "-xtarget=ultra2 -xarch=v8plusa"; } elsif ( /ultra3/ ) { $cflags = "-xtarget=ultra3cu -xarch=v8plusb"; } } } elsif ( $bits == 64 ) { for ( $cpu ) { if ( /ultra1/ ) { $cflags = "-xtarget=ultra -xarch=v9"; } elsif ( /ultra2/ ) { $cflags = "-xtarget=ultra2 -xarch=v9a"; } elsif ( /ultra3/ ) { $cflags = "-xtarget=ultra3cu -xarch=v9b"; } } } } else { error( "cpuflags: unsupported compiler ($compversion)\n" ); } } elsif ( $system eq "AIX" ) { if ( $compversion =~ /gcc-[23]/ ) { if ( $bits == 32 ) { $cflags = "-mcpu=power2"; } else { $cflags = "-mcpu=powerpc64 -maix64"; } } elsif ( $compversion =~ /xlc/i ) { $cflags = "-q64" if ( $bits == 64 ); for ( $cpu ) { if ( /power4/ ) { $cflags .= " -qarch=pwr4 -qtune=pwr4"; } } } else { error( "cpuflags: unsupported compiler ($compversion)\n" ); } } elsif ( $system eq "IRIX" ) { if ( $compversion =~ /gcc-2/ ) { $cflags = "-march=mips4"; } elsif ( $compversion =~ /gcc-3/ ) { $cflags = "-march=mips4 -mabi=$bits"; } elsif ( $compversion =~ /mipscc/ ) { $cflags = "-mips4 -$bits"; } else { error( "cpuflags: unsupported compiler ($compversion)\n" ); } } elsif ( $system eq "Darwin" ) { if ( $compversion =~ /gcc/ ) { for ( $cpu ) { if ( /ppc750/ ) { $cflags = "-mcpu=750 -mpowerpc-gfxopt -fsigned-char"; } elsif ( /ppc7400/ ) { $cflags = "-mcpu=7400 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /ppc7450/ ) { $cflags = "-mcpu=7450 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /ppc970/ ) { $cflags = "-mcpu=970 -mpowerpc-gfxopt -maltivec -mabi=altivec -fsigned-char" } elsif ( /ppc/ ) { $cflags = " " } } } elsif ( $compversion =~ /xlc/ ) { for ( $cpu ) { if ( /ppc750/ ) { $cflags = "-qarch=auto -qcache=auto"; } elsif ( /ppc74[05]0/ ) { $cflags = "-qarch=ppcv -qtune=ppcv -qcache=auto -qaltivec" } elsif ( /ppc970/ ) { $cflags = "-qarch=g5 -qtune=g5 -qcache=auto -qaltivec" } elsif ( /ppc/ ) { $cflags = "-qarch=auto -qcache=auto" } } } } elsif ( $system eq "Tru64" ) { if ( $compversion =~ /gcc/ ) { } elsif ( $compversion =~ /compaqcc/ ) { for ( $cpu ) { if ( /ev56/ ) { $cflags = "-arch ev56"; } elsif ( /ev5/ ) { $cflags = "-arch ev5"; } elsif ( /ev67/ ) { $cflags = "-arch ev67"; } elsif ( /ev6/ ) { $cflags = "-arch ev6"; } } } } elsif ( $system eq "HP-UX" ) { if ( $compversion =~ /acc/ ) { for ( $cpu ) { if ( /PA8[25]/ ) { $cflags = "+tm K8000 +DA2.0"; } elsif ( /PA8[678]/ ) { $cflags = "+tm K8000 +DA2.0W"; } elsif ( /PA7/ ) { $cflags = "+tm K7200"; } } if ( $bits == 32 ) { $cflags .= " +DD32"; } elsif ( $bits == 64 ) { $cflags .= " +DD64"; } } } elsif ( $system eq "Win32" ) { if ( $compversion =~ /msvc/ ) { for ( $cpu ) { if ( /i386/ ) { $cflags = ""; } elsif ( /i486/ ) { $cflags = ""; } elsif ( /i586|pentium/ ) { $cflags = ""; } elsif ( /k6$/ ) { $cflags = ""; } elsif ( /k6-2/ ) { $cflags = ""; } elsif ( /k6-3/ ) { $cflags = ""; } elsif ( /pentium-mmx/ ) { $cflags = ""; } elsif ( /pentiumpro/ ) { $cflags = ""; } elsif ( /p2/ ) { $cflags = ""; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "/arch:SSE"; } elsif ( /p3-(sse|xeon)/ ) { $cflags = "/arch:SSE"; } elsif ( /centrino/ ) { $cflags = "/arch:SSE2"; } elsif ( /p4-p/ ) { $cflags = "/arch:SSE2"; } elsif ( /p4-n/ ) { $cflags = "/arch:SSE2"; } elsif ( /p4/ ) { $cflags = "/arch:SSE2"; } elsif ( /athlon-tbird/ ) { $cflags = ""; } elsif ( /athlon-xp/ ) { $cflags = "/arch:SSE"; } elsif ( /athlon/ ) { $cflags = ""; } elsif ( /opteron/ ) { $cflags = "/arch:SSE2 /favor:AMD64"; } elsif ( /via-c3a/ ) { $cflags = "/arch:SSE"; } } } } if ( $cflags eq "" ) { error( "CPU $cpu not supported by compiler $compversion\n" ); # setup some flags based on cpuinfo $cflags = ""; $cflags .= " -mmmx" if ( $proc_flags{"mmx"} ); $cflags .= " -msse" if ( $proc_flags{"sse"} ); $cflags .= " -msse2" if ( $proc_flags{"sse2"} ); $cflags .= " -msse3" if ( $proc_flags{"sse3"} ); $cflags .= " -m3dnow" if ( $proc_flags{"3dnow"} ); } } ############################################################### # # setup optimisation CFLAGS # sub set_oflags { if ( $system =~ /Linux|CYGWIN/ ) { for ( $compversion ) { if ( /gcc-[23]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; if ( $cpu =~ /i586|pentium|p[234]/ ) { $oflags .= " -malign-double"; } if ( $cpu =~ /k6|athlon|via-c3/ ) { $oflags .= " -malign-double"; } if ( $cpu =~ /p[34]|athlon|opteron/ ) { $oflags .= " -fprefetch-loop-arrays"; } } elsif ( /gcc-[4]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; if ( $cpu =~ /i586|pentium|p[234]/ ) { $oflags .= " -malign-double"; } if ( $cpu =~ /k6|athlon|via-c3/ ) { $oflags .= " -malign-double"; } if ( $cpu =~ /p[34]|athlon|opteron/ ) { $oflags .= " -fprefetch-loop-arrays"; } if ( $cpu =~ /p[34]|athlon|opteron/ ) { $oflags .= " -ftree-vectorize"; } } elsif ( /icc/ ) { $oflags = "-O3 -Ob2 -unroll -ip"; if ( $cpu =~ /itanium2/ ) { $oflags .= " -IFP_fma"; } } elsif ( /pgi/ ) { $oflags = "-O3 -fast -Minline"; if ( $cpu =~ /p[234]|athlon|opteron|via-c3/ ) { $oflags .= " -Mvect"; } } elsif ( /path-2/ ) { $oflags = "-O3 -OPT:Ofast -OPT:fast_math -fno-math-errno -finline-functions -funroll-loops"; } } } elsif ( $system eq "Solaris" ) { for ( $compversion ) { if ( /gcc-[234]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; } elsif ( /suncc-5.[45678]/ ) { $oflags = "-fast -xO5"; if ( $cpu =~ /ultra3/ ) { $oflags .= " -xprefetch -xprefetch_level=3"; } } elsif ( /suncc-5.[0123]/ ) { $oflags = "-fast -xO5"; if ( $cpu =~ /ultra3/ ) { $oflags .= " -xprefetch"; } } elsif ( /kcc/ ) { $oflags = "-fast +K3 -xO5 --abstract_float"; if ( $cpu =~ /ultra3/ ) { $oflags .= " -xprefetch"; } } } } elsif ( $system eq "AIX" ) { for ( $compversion ) { if ( /gcc-[23]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; } elsif ( /xlc/i ) { $oflags = "-O2 -qinline -qrtti"; } } } elsif ( $system eq "IRIX" ) { for ( $compversion ) { if ( /gcc-[23]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; } elsif ( /mipscc/ ) { $oflags = "-O3"; } } } elsif ( $system =~ /Darwin/ ) { for ( $compversion ) { if ( /gcc-[23]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; } elsif ( /gcc-[4]/ ) { $oflags = "-O3 -fomit-frame-pointer -ffast-math -funroll-loops"; if ( $cpu =~ /ppc7400/ ) { $oflags .= " -ftree-vectorize" } elsif ( $cpu =~ /ppc7450/ ) { $oflags .= " -ftree-vectorize" } elsif ( $cpu =~ /ppc970/ ) { $oflags .= " -ftree-vectorize" } } elsif ( /xlc/ ) { $oflags = "-O3 -qunroll -qinline"; } } } elsif ( $system eq "Tru64" ) { if ( $compversion =~ /gcc/ ) { } elsif ( $compversion =~ /compaqcc/ ) { $oflags = "-fast -O4 -inline speed -unroll 0"; } } elsif ( $system eq "HP-UX" ) { if ( $compversion =~ /acc/ ) { $oflags = "-fast +Odataprefetch"; } } elsif ( $system eq "Win32" ) { if ( $compversion =~ /msvc/ ) { $oflags = "/Ox /fp:fast"; } } if ( $oflags eq "" ) { error( "CPU $cpu not supported by compiler $compversion\n" ); } } ############################################################### ############################################################### ## ## determine processor ## ############################################################### ############################################################### ############################################################### # # lookup x86 processor based on vendor, family and model # sub lookup_x86 { my $vendor = $_[0]; my $family = $_[1]; my $model = $_[2]; my $cpu = ""; # # switch between different outputs # if ( $vendor eq "AuthenticAMD" ) { if ( $family eq "4" ) { # AMD 486 $cpu = "i486"; } elsif ( $family eq "5" ) { # K5 and K6 if ( $model eq "0" ) { $cpu = "i586"; } elsif ( $model eq "1" ) { $cpu = "i586"; } elsif ( $model eq "2" ) { $cpu = "i586"; } elsif ( $model eq "3" ) { $cpu = "i586"; } elsif ( $model eq "6" ) { $cpu = "k6"; } elsif ( $model eq "7" ) { $cpu = "k6"; } elsif ( $model eq "8" ) { $cpu = "k6-2"; } elsif ( $model eq "9" ) { $cpu = "k6-3"; } elsif ( $model eq "13" ) { $cpu = "k6-3"; } else { error( "cpuflags : unsupported processor type\n" ); $cpu = "k5"; } } elsif ( $family eq "6" ) { # Athlon if ( $model eq "1" ) { $cpu = "athlon"; } elsif ( $model eq "2" ) { $cpu = "athlon"; } elsif ( $model eq "3" ) { $cpu = "athlon"; } # Duron elsif ( $model eq "4" ) { $cpu = "athlon-tbird"; } elsif ( $model eq "6" ) { $cpu = "athlon-xp"; } elsif ( $model eq "7" ) { $cpu = "athlon-xp"; } # Duron-XP elsif ( $model eq "10" ) { $cpu = "athlon-xp"; } else { error( "cpuflags : unknown Athlon model\n" ); $cpu = "athlon-tbird"; } } elsif ( $family eq "15" ) { # AMD Opteron if ( $model eq "5" ) { $cpu = "opteron"; } else { error( "cpuflags : unknown Opteron model\n" ); $cpu = "opteron"; } } } elsif ( $vendor eq "GenuineIntel" ) { if ( $family eq "3" ) { $cpu = "i386"; } elsif ( $family eq "4" ) { $cpu = "i486"; } elsif ( $family eq "5" ) { # Pentium if ( $model eq "0" ) { $cpu = "pentium"; } elsif ( $model eq "1" ) { $cpu = "pentium"; } elsif ( $model eq "2" ) { $cpu = "pentium"; } elsif ( $model eq "3" ) { $cpu = "pentium"; } elsif ( $model eq "4" ) { $cpu = "pentium-mmx"; } elsif ( $model eq "7" ) { $cpu = "pentium"; } elsif ( $model eq "8" ) { $cpu = "pentium-mmx"; } else { error( "cpuflags : unknown Pentium model\n" ); $cpu = "pentium"; } } elsif ( $family eq "6" ) { # PentiumPro, P2, P3 if ( $model eq "0" ) { $cpu = "pentiumpro"; } elsif ( $model eq "1" ) { $cpu = "pentiumpro"; } elsif ( $model eq "3" ) { $cpu = "p2"; } elsif ( $model eq "5" ) { $cpu = "p2"; } elsif ( $model eq "6" ) { $cpu = "p2"; } elsif ( $model eq "7" ) { $cpu = "p3"; } elsif ( $model eq "8" ) { $cpu = "p3-sse"; } elsif ( $model eq "9" ) { $cpu = "centrino"; } elsif ( $model eq "10" ) { $cpu = "p3-xeon"; } elsif ( $model eq "11" ) { $cpu = "p3-sse"; } elsif ( $model eq "13" ) { $cpu = "centrino"; } else { error( "cpuflags : unknown Pentium3 model\n" ); $cpu = "pentiumpro"; } } elsif ( $family eq "15" ) { # Pentium 4 if ( $model eq "0" ) { $cpu = "p4"; } elsif ( $model eq "1" ) { $cpu = "p4-w"; } elsif ( $model eq "2" ) { $cpu = "p4-n"; } elsif ( $model eq "3" ) { $cpu = "p4-p"; } elsif ( $model eq "4" ) { $cpu = "p4-n"; } elsif ( $model eq "5" ) { $cpu = "p4-f"; } else { error( "cpuflags : unknown Pentium4 model\n" ); $cpu = "p4"; } } elsif ( $family eq "Itanium 2" ) { $cpu = "itanium2"; } } elsif ( $vendor eq "CentaurHauls" ) { if ( $family eq "6" ) { # VIA C3 if ( $model eq "9" ) { $cpu = "via-c3a"; } else { error( "cpuflags : unknown C3 model\n" ); $cpu = "via-c3"; } } } else { error( "cpuflags : unknown cpu-vendor\n" ); $cpu = "i386"; } return $cpu; } ############################################################### # # functions for Linux # sub parse_linux { my @cpuinfo = `cat /proc/cpuinfo 2>&1`; my $vendor = ""; my $cputype = ""; foreach $line (@cpuinfo) { my $entry, $data; $entry = $line; $entry =~ s/[ \t]*\:.*//g; $entry =~ s/\n//g; $data = $line; $data =~ s/.*\: *//g; $data =~ s/\n//g; print "entry = ($entry), data = ($data)\n" if ( $verbosity >= 2 ); if ( $entry =~ /vendor/ ) { $vendor = $data; } elsif ( $entry eq "cpu" ) { $cputype = $data; } elsif ( $entry =~ /family/ ) { $family = $data; } elsif ( $entry eq "model" ) { $model = $data; } elsif ( $entry eq "flags" ) { # # parse processor flags # for ( $data ) { if ( /mmx/ ) { $proc_flags{"mmx"} = 1; } if ( /sse/ ) { $proc_flags{"sse"} = 1; } if ( /sse2/ ) { $proc_flags{"sse2"} = 1; } if ( /sse3/ ) { $proc_flags{"sse3"} = 1; } if ( /3dnow/ ) { $proc_flags{"3dnow"} = 1; } } } } if ( $verbosity >= 1 ) { print "Linux\n"; print " Vendor = $vendor\n"; print " CPUtype = $cputype\n"; print " Family = $family\n"; print " Model = $model\n"; print " has MMX\n" if ( $proc_flags{"mmx"} ); print " has SSE\n" if ( $proc_flags{"sse"} ); print " has SSE2\n" if ( $proc_flags{"sse2"} ); print " has SSE3\n" if ( $proc_flags{"sse3"} ); print " has 3DNOW\n" if ( $proc_flags{"3dnow"} ); } # # switch between different outputs # if ( $vendor ne "" ) { $cpu = lookup_x86( $vendor, $family, $model ); } elsif ( $cputype ne "" ) { if ( $cputype eq "745/755" ) { $cpu = "ppc750"; } else { error( "cpuflags : unknown cpu\n" ); } } else { error( "cpuflags : unknown structure in /proc/cpuinfo\n" ); } } ############################################################### # # functions for Solaris # sub parse_solaris { my $isalist = `isalist`; my $optisa = `optisa $isalist`; $optisa =~ s/\n//g; print "CPU = $optisa\n" if ( $verbosity >= 1 ); if ( $optisa eq "sparcv9" ) { $cpu = "ultra1"; } elsif ( $optisa eq "sparcv9+vis" ) { $cpu = "ultra2"; } elsif ( $optisa eq "sparcv9+vis2" ) { $cpu = "ultra3"; } else { error( "cpuflags: unsupported processor ($optisa)" ); } } ############################################################### # # functions for AIX # sub parse_aix { my @cfg = `/usr/sbin/lscfg | awk 'BEGIN { FS = "[ \t]+" } { print $2 }'`; foreach $line (@cfg) { if ( $line =~ /.*proc.*/ ) { my @entry = split( /[ \t]+/, $line ); my $proc = $entry[1]; my $info = `/usr/sbin/lscfg -p -l $proc | grep -i name`; if ( $info =~ /.*POWER4.*/ ) { $cpu = "power4" } else { error( "cpuflags: unsupported processor ($info)\n" ); } return; } } } ############################################################### # # functions for IRIX # sub parse_irix { my @cfg = `hinv`; foreach $line (@cfg) { if ( $line =~ /.*CPU.*/ ) { my @entry = split( /[ \t]+/, $line ); my $proc = $entry[2]; if ( $proc =~ /.*R10000.*/ ) { $cpu = "r10000" } else { error( "cpuflags: unsupported processor ($proc)\n" ); } return; } } } ############################################################### # # functions for Darwin (aka MacOSX) # sub parse_darwin { # # determine CPU type # my $cputype = ""; my $cpusubtype = ""; my @cfg = `sysctl -a`; foreach $line (@cfg) { if ( $line =~ /cputype/i ) { $cputype = $line; $cputype =~ s/.*\: *//g; $cputype =~ s/\n//g; } elsif ( $line =~ /cpusubtype/i ) { $cpusubtype = $line; $cpusubtype =~ s/.*\: *//g; $cpusubtype =~ s/\n//g; } } print "CPU type/subtype = $cputype / $cpusubtype\n" if ( $verbosity >= 1 ); # # set processor name # if ( $cputype == 18 ) { if ( $cpusubtype == 0 ) { $cpu = "ppc"; } elsif ( $cpusubtype == 1 ) { $cpu = "ppc601"; } elsif ( $cpusubtype == 2 ) { $cpu = "ppc602"; } elsif ( $cpusubtype == 3 ) { $cpu = "ppc603"; } elsif ( $cpusubtype == 4 ) { $cpu = "ppc603"; } elsif ( $cpusubtype == 5 ) { $cpu = "ppc603"; } elsif ( $cpusubtype == 6 ) { $cpu = "ppc604"; } elsif ( $cpusubtype == 7 ) { $cpu = "ppc604"; } elsif ( $cpusubtype == 8 ) { $cpu = "ppc620"; } elsif ( $cpusubtype == 9 ) { $cpu = "ppc750"; } elsif ( $cpusubtype == 10 ) { $cpu = "ppc7400"; } elsif ( $cpusubtype == 11 ) { $cpu = "ppc7450"; } elsif ( $cpusubtype == 100 ) { $cpu = "ppc970"; } } else { error( "cpuflags: unsupported processor (cputype = $cputype)\n" ); $cpu = "ppc"; } } ############################################################### # # functions for Tru64 # sub parse_tru64 { my @cfg = `/usr/sbin/pinfo -v`; foreach $line (@cfg) { if ( $line =~ /.*alpha.*/ ) { my @entry = split( /[ \t]+/, $line ); my $proc = $entry[3]; print "processor = $proc\n" if ( $verbosity >= 2 ); if ( $proc =~ /EV5\.6/ ) { $cpu = "ev56" } elsif ( $proc =~ /EV6\.7/ ) { $cpu = "ev67" } else { error( "cpuflags: unsupported processor ($proc)\n" ); } return; } } } ############################################################### # # functions for HP-UX # sub parse_hpux { my $type = `getconf CPU_CHIP_TYPE`; print "CPU chip type = $type\n" if ( $verbosity >= 2 ); # remove lower 5 bits to reveal actual cpu type $type >>= 5; if ( $type == 0xb) { $cpu = "PA7200"; } elsif ( $type == 0xd) { $cpu = "PA7100LC"; } elsif ( $type == 0xe) { $cpu = "PA8000"; } elsif ( $type == 0xf) { $cpu = "PA7300LC"; } elsif ( $type == 0x10) { $cpu = "PA8200"; } elsif ( $type == 0x11) { $cpu = "PA8500"; } elsif ( $type == 0x12) { $cpu = "PA8600"; } elsif ( $type == 0x13) { $cpu = "PA8700"; } elsif ( $type == 0x14) { $cpu = "PA8800"; } elsif ( $type == 0x15) { $cpu = "PA8750"; } else { $cpu = "PA"; } } ############################################################### # # functions for Win32 # sub parse_win32 { require Win32::TieRegistry; $Win32::TieRegistry::Registry->Delimiter( "/" ); # evaluate regsitry to determine exact processor type my $proc_info; my $reg_key = "LMachine/HARDWARE/DESCRIPTION/System/CentralProcessor/0"; my $error = ""; $proc_info = $Win32::TieRegistry::Registry->Open( $reg_key, { Access => KEY_READ } ) or $error = "could not access registry because: $^E\n"; if ( $error ne "" ) { print $error; $cpu = "i386"; } # # now distinguish between different processors # my $identifier = $proc_info->GetValue( "Identifier" ); my $vendor = $proc_info->GetValue( "VendorIdentifier" ); my $family, $model; if ( $identifier =~ /Family (\d+)/i ) { $family = $1; } if ( $identifier =~ /Model (\d+)/i ) { $model = $1; } if ( $verbosity >= 1 ) { print "Win32\n"; print " Vendor = $vendor\n"; print " Family = $family\n"; print " Model = $model\n"; } $cpu = lookup_x86( $vendor, $family, $model ); } ############################################################### ############################################################### ## ## determine compiler version ## ############################################################### ############################################################### sub parse_comp_output { foreach $line (@_) { print "output: $line" if ( $verbosity >= 2 ); if ( $line =~ /^gcc.* (\d+)\.(\d+)/i ) { $compversion = "gcc-$1.$2"; return; } if ( $line =~ /intel.*compiler.*version.* (\d+)\.(\d+)/i ) { $compversion = "icc-$1.$2"; return; } if ( $line =~ /Version (\d+)\.(\d+).*l_cc/ ) { $compversion = "icc-$1.$2"; return; } if ( $line =~ /pg(cc|CC|f77|f90) (\d+)\.(\d+)/i ) { $compversion = "pgi-$2.$3"; return; } if ( $line =~ /PathScale.* Version (\d+)\.(\d+)/i ) { $compversion = "path-$1.$2"; return; } if ( $line =~ /forte developer .* c\+* (\d+)\.(\d+)/i ) { $compversion = "suncc-$1.$2"; return; } if ( $line =~ /sun workshop .* c\+* (\d+)\.(\d+)/i ) { $compversion = "suncc-$1.$2"; return; } if ( $line =~ /sun c\+* (\d+)\.(\d+)/i ) { $compversion = "suncc-$1.$2"; return; } if ( $line =~ /hp.*ansi.*a\.(\d+)/i ) { $compversion = "acc-$1"; return; } if ( $line =~ /mipspro compilers.* (\d+)\.(\d+)/i ) { $compversion = "mipscc-$1"; return; } if ( $line =~ /IBM XL .* Version (\d+)\.(\d+)/i ) { $compversion = "xlc-$1"; return; } if ( $line =~ /C for AIX version (\d+)\.(\d+)/i ) { $compversion = "xlc-$1"; return; } if ( $line =~ /Compaq C V(\d+)\.(\d+)/i ) { $compversion = "compaqcc-$1"; return; } if ( $line =~ /Microsoft .* C\/C\+\+ .* Version (\d+)\.(\d+)/i ) { $compversion = "msvc-$1"; return; } } } sub compiler_version { $compversion = ""; if ( $system =~ /Linux|CYGWIN/ ) { @options = ( "-v", "-V", "--version", "-qversion" ); } else { @options = ( "-V", "-v", "--version", "-qversion" ); } foreach $opt (@options) { @output = `$compiler $opt 2>&1`; parse_comp_output( @output ); if ( $compversion ne "" ) { $compsubver = $compversion; $compsubver =~ s/.*\.//g; return; } } error( "compiler '$compiler' not available or unsupported by cpuflags\n" ); exit( 1 ); } ############################################################### ############################################################### ## ## main program ## ############################################################### ############################################################### parse_cmdline(); # # determine operating system # if ( $^O eq "MSWin32" ) { $system = "Win32"; } else { $system = `uname -s`; $system =~ s/\n//g; } # adjust name if ( $system eq "SunOS" ) { $system = "Solaris"; } if ( $system eq "IRIX64" ) { $system = "IRIX"; } if ( $system eq "OSF1" ) { $system = "Tru64"; } # # determine compiler version # compiler_version() if ( $compversion eq "" ); if ( $compversion eq "" ) { error( "unsupported compiler\n" ); exit( 1 ); } print "compiler = $compversion\n" if ( $verbosity >= 1 ); # # determine processor # if ( $cpu eq "" ) { if ( $system =~ /Linux|CYGWIN/ ) { parse_linux(); } elsif ( $system eq "Solaris" ) { parse_solaris(); } elsif ( $system eq "AIX" ) { parse_aix(); } elsif ( $system eq "IRIX" ) { parse_irix(); } elsif ( $system eq "Darwin" ) { parse_darwin(); } elsif ( $system eq "Tru64" ) { parse_tru64(); } elsif ( $system eq "HP-UX" ) { parse_hpux(); } elsif ( $system eq "Win32" ) { parse_win32(); } else { error( "cpuflags: unknown system ($system)\n" ); exit( 1 ); } } # # setup cflags # if ( $show_cflags == 1 ) { set_cflags(); } if ( $show_oflags == 1 ) { set_oflags(); } # # output everything # if ( $show_cpu == 1 ) { print "$cpu\n"; } else { # standard flags $oflags = $std_oflags if ( $oflags eq "" ); # first print optimisation flags to omit warnings of sun-compiler print "$oflags " if ( $show_oflags == 1 ); print "$cflags " if ( $show_cflags == 1 ); print "\n" if ( $show_cflags == 1 or $show_oflags == 1 ); }