check-cpu 5.29 KB
Newer Older
1 2 3 4 5 6
#!/bin/sh
#
# Check cpu of current machine and find the
# best compiler optimization flags for gcc
#

7 8 9 10
check_cpu () {
  if test -r /proc/cpuinfo ; then
    # on Linux (and others?) we can get detailed CPU information out of /proc
    cpuinfo="cat /proc/cpuinfo"
11

12 13 14 15 16
    # 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
17

18 19 20 21 22 23 24 25 26 27 28
    # 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
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
    # parse CPU flags
    for flag in `$cpuinfo | grep '^flags' | sed -e 's/^flags.*: //'`; do 
          eval cpu_flag_$flag=yes
    done
  else
    # Fallback when there is no /proc/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
50
  fi
51

52 53 54 55 56 57 58
  # 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";
59
      ;;
60 61 62 63 64 65 66 67 68 69 70

    # 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
71
      ;;
72 73
    *Pentium*4*Mobile*)
      cpu_arg="pentium4m";
74
    ;;
75
    *Pentium*4*)
76
      cpu_arg="pentium4";
77 78 79
      ;;
    *Pentium*III*Mobile*)
      cpu_arg="pentium3m";
80
    ;;
81 82
    *Pentium*III*)
      cpu_arg="pentium3";
83
    ;;
84 85
    *Pentium*M*pro*)
      cpu_arg="pentium-m";
86
    ;;
87 88 89 90 91 92
    *Athlon*64*)
      cpu_arg="athlon64";
      ;;
    *Athlon*)
      cpu_arg="athlon";
      ;;
93 94 95
    *Opteron*)
      cpu_arg="opteron";
      ;;
96 97 98 99
    # MacOSX / Intel  
    *i386*i486*)
      cpu_arg="pentium-m";
      ;;
100

101 102 103 104 105
    # Intel ia64
    *Itanium*)
      # Don't need to set any flags for itanium(at the moment)
      cpu_arg="";
      ;;
106

107 108 109 110 111 112 113 114
    #
    *ppc*)
      cpu_arg='powerpc'
      ;;
   
    *powerpc*)
      cpu_arg='powerpc'
      ;;
115

116 117 118 119 120 121 122 123 124
    # unknown
    *)
      cpu_arg="";
      ;;
  esac


  if test -z "$cpu_arg"; then
    echo "BUILD/check-cpu: Oops, could not find out what kind of cpu this machine is using." >&2
125
    check_cpu_cflags=""
126 127 128
    return
  fi

129 130 131 132 133 134 135
  # different compiler versions have different option names
  # for CPU specific command line options
  if test -z "$CC" ; then
    cc="gcc";
  else
    cc=$CC
  fi
136

137
  cc_ver=`$cc --version | sed 1q`
138
  cc_verno=`echo $cc_ver | sed -e 's/^.*gcc/gcc/g; s/[^0-9. ]//g;	 s/^ *//g; s/ .*//g'`
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156

  case "$cc_ver--$cc_verno" in
    *GCC*)
        # different gcc backends (and versions) have different CPU flags
        case `gcc -dumpmachine` in
          i?86-*)
                case "$cc_verno" in
                      3.4*|3.5*|4.*)
                            check_cpu_args='-mtune=$cpu_arg -march=$cpu_arg'
                            ;;
                      *)
                            check_cpu_args='-mcpu=$cpu_arg -march=$cpu_arg'
                            ;;
            esac
            ;;
          ppc-*)
                    check_cpu_args='-mcpu=$cpu_arg -mtune=$cpu_arg'
            ;;
157 158 159
          x86_64-*)
                    check_cpu_args='-mtune=$cpu_arg'
            ;;
160 161 162 163 164 165 166 167 168 169 170 171 172 173
          *)
            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
      ;;
174 175
  esac

176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
  # now we check whether the compiler really understands the cpu type
  touch __test.c

  while [ "$cpu_arg" ] ; do
    # FIXME: echo -n isn't portable - see contortions autoconf goes through
    echo -n 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        ;;

208 209
      # power / powerPC
      7450)       cpu_arg=7400        ;;
210 211 212 213 214 215 216

      *)          cpu_arg=""          ;;
    esac
  done

  rm __test.*
}
217

218
check_cpu