#!/usr/bin/perl # # prints cpu or cpu-flags for different compilers # supported platforms : Linux, Solaris, AIX # supported compilers : Linux - gcc2, gcc3, icc # Solaris - gcc2, gcc3, gcc3-64, # suncc, suncc-64, kcc, kcc-64 # AIX - gcc, xlC, xlC-64 # $system = ""; $cpu = $ENV{"CPU"}; $show_cpu = "0"; $show_cflags = "1"; $show_opt = "0"; $compiler = ""; $version = "0.5.7"; $verbosity = 0; $std_oflags = "-O"; $std_comp = "gcc3"; ############################################################### # # setup compiler-flags # sub setup_cpuflags { if ( $system eq "Linux" ) { if ( $compiler eq "gcc2" ) { $cpuflags{"i386"} = "-march=i386"; $cpuflags{"i486"} = "-march=i486"; $cpuflags{"i586"} = "-march=i586"; $cpuflags{"pentium"} = "-march=i586"; $cpuflags{"pentium-mmx"} = "-march=i586"; $cpuflags{"pentiumpro"} = "-march=i686"; $cpuflags{"p2"} = "-march=i686"; $cpuflags{"p3"} = "-march=i686"; $cpuflags{"p3-sse"} = "-march=i686"; $cpuflags{"p3-centrino"} = "-march=i686"; $cpuflags{"p3-xeon"} = "-march=i686"; $cpuflags{"athlon"} = "-march=i686"; $cpuflags{"duron"} = "-march=i686"; $cpuflags{"athlon-tbird"} = "-march=i686"; $cpuflags{"athlon-xp"} = "-march=i686"; $cpuflags{"duron-xp"} = "-march=i686"; $cpuflags{"p4"} = "-march=i686"; $cpuflags{"p4-xeon"} = "-march=i686"; $cpuflags{"ppc750"} = "-mcpu=750 -mpowerpc-gfxopt -mhard-float -mmultiple -mstring"; $cpuflags{"ppc7450"} = "-mcpu=7450 -mpowerpc-gfxopt"; $cpuflags{"via-c3a"} = "-march=i586"; } elsif ( $compiler eq "gcc3" ) { $cpuflags{"i386"} = "-march=i386"; $cpuflags{"i486"} = "-march=i486"; $cpuflags{"i586"} = "-march=i586"; $cpuflags{"pentium"} = "-march=i586"; $cpuflags{"pentium-mmx"} = "-march=i586 -mmmx"; $cpuflags{"pentiumpro"} = "-march=i686"; $cpuflags{"p2"} = "-march=i686 -mmmx"; $cpuflags{"p3"} = "-march=pentium3 -mmmx"; $cpuflags{"p3-sse"} = "-march=pentium3 -mmmx -msse -mfpmath=sse"; $cpuflags{"p3-centrino"} = "-march=pentium3 -mmmx -msse2 -mfpmath=sse2"; $cpuflags{"p3-xeon"} = "-march=pentium3 -mmmx -msse -mfpmath=sse"; $cpuflags{"athlon"} = "-march=athlon -mmmx -m3dnow"; $cpuflags{"duron"} = "-march=athlon -mmmx -m3dnow"; $cpuflags{"athlon-tbird"} = "-march=athlon-tbird -mmmx -m3dnow"; $cpuflags{"athlon-xp"} = "-march=athlon-xp -mmmx -msse -m3dnow -mfpmath=sse"; $cpuflags{"duron-xp"} = "-march=athlon-xp -mmmx -msse -m3dnow -mfpmath=sse"; $cpuflags{"p4"} = "-march=pentium4 -mmx -msse -msse2 -mfpmath=sse"; $cpuflags{"p4-xeon"} = "-march=pentium4 -mmx -msse -msse2 -mfpmath=sse"; $cpuflags{"ppc750"} = "-mcpu=750 -mhard-float -mmultiple -mstring"; $cpuflags{"ppc7450"} = "-mcpu=7450 -mpowerpc-gfxopt -maltivec -mabi=altivec"; $cpuflags{"via-c3a"} = "-march=i586 -mmmx -msse -mfpmath=sse"; } elsif ( $compiler eq "icc" ) { $cpuflags{"i386"} = ""; $cpuflags{"i486"} = ""; $cpuflags{"i586"} = ""; $cpuflags{"pentium"} = "-tpp5"; $cpuflags{"pentium-mmx"} = "-tpp5 -xM"; $cpuflags{"pentiumpro"} = "-tpp6"; $cpuflags{"p2"} = "-tpp6 -xM"; $cpuflags{"p3"} = "-tpp6 -xM"; $cpuflags{"p3-sse"} = "-tpp6 -xMK"; $cpuflags{"p3-centrino"} = "-tpp7 -xMKW"; $cpuflags{"p3-xeon"} = "-tpp6 -xMK"; $cpuflags{"athlon"} = "-tpp6 -xM"; $cpuflags{"duron"} = "-tpp6 -xM"; $cpuflags{"athlon-tbird"} = "-tpp6 -xM"; $cpuflags{"athlon-xp"} = "-tpp6 -xMK"; $cpuflags{"duron-xp"} = "-tpp6 -xMK"; $cpuflags{"p4"} = "-tpp7 -xMKW"; $cpuflags{"p4-xeon"} = "-tpp7 -xMKW"; $cpuflags{"via-c3a"} = "-tpp5 -xMK"; } else { print "cpuflags: unsupported compiler ($compiler)\n"; exit(1); } } elsif ( $system eq "Solaris" ) { if ( $compiler eq "gcc2" or $compiler eq "gcc3" ) { $cpuflags{"ultra1"} = "-mcpu=ultrasparc"; $cpuflags{"ultra2"} = "-mcpu=ultrasparc"; $cpuflags{"ultra3"} = "-mcpu=ultrasparc"; } elsif ( $compiler eq "gcc3-64" ) { $cpuflags{"ultra1"} = "-mcpu=ultrasparc -m64"; $cpuflags{"ultra2"} = "-mcpu=ultrasparc -m64"; $cpuflags{"ultra3"} = "-mcpu=ultrasparc -m64"; } elsif ( $compiler eq "suncc" or $compiler eq "kcc" ) { $cpuflags{"ultra1"} = "-xtarget=ultra -xarch=v8"; $cpuflags{"ultra2"} = "-xtarget=ultra2 -xarch=v8plusa"; $cpuflags{"ultra3"} = "-xtarget=ultra3 -xarch=v8plusb"; } elsif ( $compiler eq "fd7" ) { $cpuflags{"ultra1"} = "-xtarget=ultra -xarch=v8"; $cpuflags{"ultra2"} = "-xtarget=ultra2 -xarch=v8plusa"; $cpuflags{"ultra3"} = "-xtarget=ultra3cu -xarch=v8plusb"; } elsif ( $compiler eq "fd7-64" ) { $cpuflags{"ultra1"} = "-xtarget=ultra -xarch=v9"; $cpuflags{"ultra2"} = "-xtarget=ultra2 -xarch=v9a"; $cpuflags{"ultra3"} = "-xtarget=ultra3cu -xarch=v9b"; } elsif ( $compiler eq "suncc-64" or $compiler eq "kcc-64" ) { $cpuflags{"ultra1"} = "-xtarget=ultra -xarch=v9"; $cpuflags{"ultra2"} = "-xtarget=ultra2 -xarch=v9a"; $cpuflags{"ultra3"} = "-xtarget=ultra3 -xarch=v9b"; } else { print "cpuflags: unsupported compiler ($compiler)\n"; exit(1); } } elsif ( $system eq "AIX" ) { if ( $compiler eq "gcc2" or $compiler eq "gcc3" ) { $cpuflags{"power4"} = "-mcpu=power2"; } elsif ( $compiler eq "xlC" ) { $cpuflags{"power4"} = "-qarch=pwr4 -qtune=pwr4"; } elsif ( $compiler eq "xlC-64" ) { $cpuflags{"power4"} = "-q64 -qarch=pwr4 -qtune=pwr4"; } else { print "cpuflags: unsupported compiler ($compiler)\n"; exit(1); } } } sub setup_optflags { if ( $system eq "Linux" ) { if ( $compiler eq "gcc2" or $compiler eq "gcc3" ) { $stdflags = "-O3 -fomit-frame-pointer -finline-functions"; $stdflags = "$stdflags -ffast-math -funroll-loops -fexpensive-optimizations"; $optflags{"i386"} = "$stdflags"; $optflags{"i486"} = "$stdflags"; $optflags{"i586"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"pentium"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"pentium-mmx"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"pentiumpro"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p2"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p3"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p3-sse"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p3-centrino"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p3-xeon"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"athlon"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"duron"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"athlon-tbird"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"athlon-xp"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"duron-xp"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p4"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"p4-xeon"} = "$stdflags -fschedule-insns2 -malign-double"; $optflags{"ppc750"} = "$stdflags"; $optflags{"via-c3a"} = "$stdflags -fschedule-insns2 -malign-double"; } elsif ( $compiler eq "icc" ) { $stdflags = "-O3"; $optflags{"i386"} = "$stdflags"; $optflags{"i486"} = "$stdflags"; $optflags{"i586"} = "$stdflags"; $optflags{"pentium"} = "$stdflags"; $optflags{"pentium-mmx"} = "$stdflags"; $optflags{"pentiumpro"} = "$stdflags"; $optflags{"p2"} = "$stdflags -unroll"; $optflags{"p3"} = "$stdflags -unroll"; $optflags{"p3-sse"} = "$stdflags -unroll"; $optflags{"p3-centrino"} = "$stdflags -unroll"; $optflags{"p3-xeon"} = "$stdflags -unroll"; $optflags{"athlon"} = "$stdflags -unroll"; $optflags{"duron"} = "$stdflags -unroll"; $optflags{"athlon-tbird"} = "$stdflags -unroll"; $optflags{"athlon-xp"} = "$stdflags -unroll"; $optflags{"duron-xp"} = "$stdflags -unroll"; $optflags{"p4"} = "$stdflags -unroll"; $optflags{"p4-xeon"} = "$stdflags -unroll"; $optflags{"via-c3a"} = "$stdflags -unroll"; } else { print "cpuflags: unsupported compiler ($compiler)\n"; exit(1); } } elsif ( $system eq "Solaris" ) { if ( $compiler eq "gcc2" or $compiler eq "gcc3" ) { $stdflags = "-O3 -fomit-frame-pointer -finline-functions"; $stdflags = "$stdflags -ffast-math -funroll-loops -fexpensive-optimizations"; $optflags{"ultra1"} = "$stdflags"; $optflags{"ultra2"} = "$stdflags"; $optflags{"ultra3"} = "$stdflags"; } elsif ( $compiler eq "gcc3-64" ) { $stdflags = "-O3 -fomit-frame-pointer -finline-functions"; $stdflags = "$stdflags -ffast-math -funroll-loops -fexpensive-optimizations"; $optflags{"ultra1"} = "$stdflags"; $optflags{"ultra2"} = "$stdflags"; $optflags{"ultra3"} = "$stdflags"; } elsif ( $compiler eq "suncc" or $compiler eq "suncc-64" ) { $stdflags = "-fast -xO5"; $optflags{"ultra1"} = "$stdflags"; $optflags{"ultra2"} = "$stdflags"; $optflags{"ultra3"} = "$stdflags -xprefetch"; } elsif ( $compiler eq "fd7" or $compiler eq "fd7-64" ) { $stdflags = "-fast -xO5"; $optflags{"ultra1"} = "$stdflags"; $optflags{"ultra2"} = "$stdflags"; $optflags{"ultra3"} = "$stdflags -xprefetch -xprefetch_level=3"; } elsif ( $compiler eq "kcc" or $compiler eq "kcc-64" ) { $stdflags = "-fast +K3 -xO5 --abstract_float"; $optflags{"ultra1"} = "$stdflags"; $optflags{"ultra2"} = "$stdflags"; $optflags{"ultra3"} = "$stdflags -xprefetch"; } else { print "cpuflags: unsupported compiler ($compiler)\n"; exit(1); } } elsif ( $system eq "AIX" ) { if ( $compiler eq "gcc2" or $compiler eq "gcc3" ) { $optflags{"power4"} = "-O3 -fomit-frame-pointer -finline-functions -ffast-math -funroll-loops"; } elsif ( $compiler eq "xlC" or $compiler eq "xlC-64" ) { $optflags{"power4"} = "-O2 -qinline -qrtti"; } else { print "cpuflags: unsupported compiler ($compiler)\n"; exit(1); } } } ############################################################### # # functions for Linux # sub parse_linux { @cpuinfo = `cat /proc/cpuinfo`; $vendor = ""; $cputype = ""; foreach $line (@cpuinfo) { $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 eq "vendor_id" ) { $vendor = $data; } elsif ( $entry eq "cpu" ) { $cputype = $data; } elsif ( $entry eq "cpu family" ) { $family = $data; } elsif ( $entry eq "model" ) { $model = $data; } } # # switch between different outputs # if ( $verbosity >= 1 ) { print "Vendor = $vendor\n"; print "CPUtype = $cputype\n"; print "Family = $family\n"; print "Model = $model\n"; } if ( $vendor ne "" ) { if ( $vendor eq "AuthenticAMD" ) { if ( $family eq "4" ) { # AMD 486 print "cpuflags : to be done\n"; $cpu = "i486"; } elsif ( $family eq "5" ) { # K5 and K6 print "cpuflags : to be done\n"; $cpu = "i586"; } elsif ( $family eq "6" ) { # Athlon if ( $model eq "1" ) { $cpu = "athlon"; } elsif ( $model eq "2" ) { $cpu = "athlon"; } elsif ( $model eq "3" ) { $cpu = "duron"; } elsif ( $model eq "4" ) { $cpu = "athlon-tbird"; } elsif ( $model eq "6" ) { $cpu = "athlon-xp"; } elsif ( $model eq "7" ) { $cpu = "duron-xp"; } else { print "cpuflags : unkown Athlon model\n"; $cpu = "athlon-tbird"; } } } elsif ( $vendor eq "GenuineIntel" ) { if ( $family eq "3" ) { # i386 $cpu = "i386"; } elsif ( $family eq "4" ) { # i486 $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 { print "cpuflags : unkown 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 = "p3-centrino"; } elsif ( $model eq "10" ) { $cpu = "p3-xeon"; } elsif ( $model eq "11" ) { $cpu = "p3-sse"; } else { print "cpuflags : unkown Pentium3 model\n"; $cpu = "pentiumpro"; } } elsif ( $family eq "15" ) { # Pentium 4 if ( $model eq "2" ) { $cpu = "p4-xeon"; } else { print "cpuflags : unkown Pentium4 model\n"; $cpu = "p4"; } } } elsif ( $vendor eq "CentaurHauls" ) { if ( $family eq "6" ) { # VIA C3 if ( $model eq "9" ) { $cpu = "via-c3a"; } else { print "cpuflags : unknown C3 model"; $cpu = "via-c3"; } } } else { print "cpuflags : unkown cpu-vendor\n"; $cpu = "i386"; } } elsif ( $cputype ne "" ) { if ( $cputype eq "745/755" ) { $cpu = "ppc750"; } else { print "cpuflags : unknown cpu\n"; } } else { print "cpuflags : unkown structure in /proc/cpuinfo\n"; exit 1; } } ############################################################### # # functions for Solaris # sub parse_solaris { $isalist = `isalist`; $optisa = `optisa $isalist`; $optisa =~ s/\n//g; if ( $optisa eq "sparcv9" ) { $cpu = "ultra1"; } elsif ( $optisa eq "sparcv9+vis" ) { $cpu = "ultra2"; } elsif ( $optisa eq "sparcv9+vis2" ) { $cpu = "ultra3"; } else { print "cpuflags: unsupported processor ($optisa)"; } } ############################################################### # # functions for AIX # sub parse_aix { @cfg = `/usr/sbin/lscfg | awk 'BEGIN { FS = "[ \t]+" } { print $2 }'`; foreach $line (@cfg) { if ( $line =~ /.*proc.*/ ) { @entry = split( /[ \t]+/, $line ); $proc = $entry[1]; $info = `/usr/sbin/lscfg -p -l $proc | grep -i name`; if ( $info =~ /.*POWER4.*/ ) { $cpu = "power4" } else { print "cpuflags: unsupported processor ($info)"; } return; } } } ########################################################################### # # show usage # sub show_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 (default gcc2)\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 " -h, --help : print this message\n"; print " -v, --verbose : verbosity level (default 0)\n"; print " -V, --version : print version number\n"; print "\n"; print " Supported systems and compilers:\n"; print " Linux : gcc2, gcc3, icc\n"; print " Solaris : gcc2, gcc3, gcc3-64, suncc, suncc-64,\n"; print " kcc, kcc-64, fd7, fd7-64\n"; print " AIX : gcc, xlC, xlC-64\n"; print "\n"; print " Supported CPUs:\n"; print " Linux : i386, i486, pentium, pentium-mmx, pentium-pro\n"; print " p2, p3, p3-sse, p3-centrino, p3-xeon, p4, p4-xeon,\n"; print " athlon, duron, athlon-tbird, athlon-xp, duron-xp,\n"; print " via-c3a, ppc750, ppc7450\n"; print " Solaris : ultra1, ultra2, ultra3, ultra3cu\n"; print " AIX : power4\n"; print "\n"; } ########################################################################### # # parse command-line # sub parse_cmdline { for ( $i = 0; $i <= $#ARGV; $i++ ) { $arg = $ARGV[$i]; switch: { if ( $arg =~ /^--cpu/ ) { $i++; if ( $i <= $#ARGV and not $ARGV[$i] =~ /^-/ ) { $cpu = $ARGV[$i]; last switch; } else { print "error: expected name after --cpu\n"; exit( 1 ); } } elsif ( $arg =~ /^--showcpu/ ) { $show_cpu = 1; last switch; } elsif ( $arg =~ /^--cflags/ ) { $show_cflags = 1; last switch; } elsif ( $arg =~ /^--nocflags/ ) { $show_cflags = 0; last switch; } elsif ( $arg =~ /^--opt/ ) { $show_oflags = 1; last switch; } elsif ( $arg =~ /^--noopt/ ) { $show_oflags = 0; last switch; } elsif ( $arg =~ /^--comp/ ) { $i++; if ( $i <= $#ARGV and not $ARGV[$i] =~ /^-/ ) { $compiler = $ARGV[$i]; last switch; } else { print "error: expected name after --comp\n"; exit( 1 ); } } elsif ( $arg =~ /^-h/ or $arg =~ /^--help/ ) { show_usage(); exit( 0 ); } elsif ( $arg =~ /^-V/ or $arg =~ /^--version/ ) { print "cpuflags v$version\n"; exit( 0 ); } elsif ( $arg =~ /^-v/ or $arg =~ /^--verbose/ ) { $i++; if ( $i <= $#ARGV and not $ARGV[$i] =~ /^-/ ) { $verbosity = $ARGV[$i]; last switch; } else { print "error: expected name after --verbose\n"; exit( 1 ); } } } } } ############################################################ ############################################################ ## ## main program ## ############################################################ ############################################################ parse_cmdline(); # default settings $compiler = $std_comp if ( $compiler eq "" ); $cpu = "" if ( $cpu eq "auto" ); # # determine operating system # $system = `uname -s`; $system =~ s/\n//g; # adjust for prettier name if ( $system eq "SunOS" ) { $system = "Solaris"; } if ( $cpu eq "" ) { if ( $system eq "Linux" ) { parse_linux(); } elsif ( $system eq "Solaris" ) { parse_solaris(); } elsif ( $system eq "AIX" ) { parse_aix(); } else { print "cpuflags: unkown system ($system)\n"; } } if ( $show_cflags == 1 ) { setup_cpuflags(); $cflags = $cpuflags{$cpu}; } if ( $show_oflags == 1 ) { setup_optflags(); $oflags = $optflags{$cpu}; } if ( $show_cpu == 1 ) { print "$cpu\n"; } else { # some 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 ); }