diff --git a/BUILD/check-cpu b/BUILD/check-cpu
index 0283c669fb2530ebd86f76cbb72a7c272f490888..3ceb9c269fee05100fd9e9ad6474a06ea7671759 100755
--- a/BUILD/check-cpu
+++ b/BUILD/check-cpu
@@ -6,113 +6,197 @@
 #
 
 if test -r /proc/cpuinfo ; then
+  # on Linux (and others?) we can get detailed CPU information out of /proc
   cpuinfo="cat /proc/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.*: //'`; do 
+	eval cpu_flag_$flag=yes
+  done
 else
   # Fallback when there is no /proc/cpuinfo
   case "`uname -s`" in
-    FreeBSD)
+    FreeBSD|OpenBSD)
       cpu_family=`uname -m`;
-      model_name=`sysctl -b hw.model`
+      model_name=`sysctl -n hw.model`
+      ;;
+    Darwin)
+      cpu_family=`uname -p`
+      model_name=`machine`
       ;;
     *)
       cpu_family=`uname -m`;
-      model_name="unknown";
+      model_name=`uname -p`;
       ;;
   esac
 fi
 
-cpu_flag=""
-cpu_flag_old=""
+# 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_flag="ev6";
+    cpu_arg="ev6";
     ;;
+
+  # Intel ia32
   *Xeon*)
-    cpu_flag="nocona";
+    # 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*)
-    cpu_flag="pentium4m";
+  *Pentium*4*Mobile*)
+    cpu_arg="pentium4m";
   ;;
-  *Pentium*4*CPU*)
-    cpu_flag="pentium4";
+  *Pentium*4*)
+    cpu_arg="pentium4";
     ;;
-  *Pentium*III*Mobile*CPU*)
-    cpu_flag="pentium3m";
+  *Pentium*III*Mobile*)
+    cpu_arg="pentium3m";
   ;;
-  *Pentium*III*CPU*)
-    cpu_flag="pentium3";
+  *Pentium*III*)
+    cpu_arg="pentium3";
   ;;
   *Pentium*M*pro*)
-    cpu_flag="pentium-m";
-    cpu_flag_old="pentium";
+    cpu_arg="pentium-m";
   ;;
   *Athlon*64*)
-    cpu_flag="athlon64";
-    cpu_flag_old="athlon";
+    cpu_arg="athlon64";
     ;;
   *Athlon*)
-    cpu_flag="athlon";
+    cpu_arg="athlon";
     ;;
+
+  # Intel ia64
   *Itanium*)
     # Don't need to set any flags for itanium(at the moment)
-    cpu_flag="";
+    cpu_arg="";
     ;;
-  *ppc)
-    cpu_flag="powerpc";
-    no_march=1;
+
+  # 
+  *powerpc*)
+    cpu_arg=`echo $model_name | sed -e"s/ppc//g"`
     ;;
+
+  # unknown
   *)
-    cpu_flag="";
+    cpu_arg="";
     ;;
 esac
 
-if test -z "$cpu_flag"; then
+
+if test -z "$cpu_arg"; then
   echo "BUILD/check-cpu: Oops, could not findout what kind of cpu this machine is using."
-  check_cpu_flags=""
+  check_cpu_cflags=""
   return
 fi
 
-echo "cpu_flag: $cpu_flag"
-
+# 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/[^0-9. ]//g;	 s/^ *//g; s/ .*//g'`
 
 case "$cc_ver--$cc_verno" in
-  *GCC*--3.4*|*GCC*--3.5*|*GCC*--4.*)
-    check_cpu_cflags="-mtune=$cpu_flag -march=$cpu_flag"
-    ;;
   *GCC*)
-    # Fix for older compiler versions
-    if test -n "$cpu_flag_old"; then
-      cpu_flag="$cpu_flag_old"
-    fi
-    check_cpu_cflags="-mcpu=$cpu_flag -march=$cpu_flag"
-    if test -n "$no_march"; then
-      check_cpu_cflags="-mcpu=$cpu_flag"
-    fi
+      # 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'
+          ;;
+        *)
+          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
-echo $check_cpu_cflags
+
+# now we check whether the compiler really understands the cpu type
+touch __test.c
+
+while [ "$cpu_arg" ] ; do
+  echo -n testing $cpu_arg "... "
+	
+  # compile check
+  check_cpu_cflags=`eval echo $check_cpu_args`
+  if $cc -c $check_cpu_cflags __test.c 2>/dev/null; then
+	  echo ok
+      break;
+  fi
+
+  echo failed
+  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.*
+