Subject: pkg/29345: i386 cpu type detection in graphics/povray fails for AMD K6
To: None <pkg-manager@netbsd.org, gnats-admin@netbsd.org,>
From: None <dholland@eecs.harvard.edu>
List: pkgsrc-bugs
Date: 02/12/2005 22:47:00
>Number:         29345
>Category:       pkg
>Synopsis:       i386 cpu type detection in graphics/povray fails for AMD K6
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Feb 12 22:47:00 +0000 2005
>Originator:     David A. Holland <dholland@eecs.harvard.edu>
>Release:        NetBSD 2.99.12 [20050109]
>Organization:
   Harvard EECS
>Environment:
System: NetBSD merlin 2.99.12 NetBSD 2.99.12 (MERLIN) #56: Sat Jan 15 09:58:45 EST 2005  dholland@merlin:/usr/src/sys/arch/i386/compile/MERLIN i386
Architecture: i386
Machine: i386
>Description:

	povray does some pretty aggressive cpu detection to feed
	-mcpu=* to gcc, but it has some bugs and doesn't understand 
	NetBSD. 

	As a result, it always picks the default, -mcpu=i686. This
	seems to cause gcc to generate code that doesn't run on a K6;
	then the build fails with SIGILL down inside povray's included
	copy of libtiff.

>How-To-Repeat:

	Find a K6, and build povray.

>Fix:

	The following patch cleans up cpu detection and adds support
	for extracting the exact cpu type from /var/run/dmesg.boot.
	The patch is more involved than is strictly necessary for
	pkgsrc, but as I'm sending a copy upstream I wanted to fix it
	properly.

	I don't know the proper incantations to have pkgsrc rerun 
	autoconf after patching configure.ac, so I haven't included
	that bit.

--- configure.ac.orig	2004-08-02 19:16:14.000000000 -0400
+++ configure.ac	2005-02-12 16:53:10.000000000 -0500
@@ -886,10 +886,21 @@
           pov_cpuinfo=/proc/cpuinfo
         elif test -r /compat/linux/proc/cpuinfo ; then # FreeBSD using linprocfs
           pov_cpuinfo=/compat/linux/proc/cpuinfo
-        elif test "`dmesg 2> /dev/null`"; then  # FreeBSD 4.9 at least
-          pov_modelname=`dmesg | grep CPU | $head_1 | cut -d: -f2 | tr A-Z a-z`
-          pov_cpuflags=`dmesg | grep Features | $head_1 | cut -d'<' -f2 | sed 's/[,>]/ /g' | tr A-Z a-z`
-          pov_vendorid=`dmesg | grep Origin | $head_1 | cut -d'"' -f2`
+        elif test -r /emul/linux/proc ; then # NetBSD linprocfs
+          pov_cpuinfo=/emul/linux/proc
+        else
+          case "`uname -s 2>/dev/null || echo nothing`" in
+            NetBSD)
+              pov_modelname=`grep cpu0: /var/run/dmesg.boot | $head_1 | cut -d: -f2 | cut -d, -f1 | tr A-Z a-z`
+	      pov_cpuflags=`grep 'cpu0: features' /var/run/dmesg.boot | cut -d'<' -f2 | tr 'A-Z,>\n' 'a-z   '`
+	      pov_vendorid='unknown'  # not reported as such
+	    ;;
+	    FreeBSD)
+              pov_modelname=`grep CPU /var/run/dmesg.boot | $head_1 | cut -d: -f2 | tr A-Z a-z`
+              pov_cpuflags=`grep Features /var/run/dmesg.boot | $head_1 | cut -d'<' -f2 | tr 'A-Z,>' 'a-z  '`
+              pov_vendorid=`grep Origin /var/run/dmesg.boot | $head_1 | cut -d'"' -f2`
+            ;;
+          esac
         fi
       fi
 
@@ -930,51 +941,52 @@
 
       if test -z "$pov_arch"; then
         case "$host" in
+          i386-*) ;;  # *BSD always says i386
           i486-*)         pov_arch="i486";;
           i586-*)         pov_arch="pentium";;  # for GCC / ICC
-          i686-*|i386-*)  # FreeBSD seems to only report i386
+          i686-*) ;;
+          k6-*)           pov_arch="k6"; pov_arch_fallback="i586";;
+          k7-*)           pov_arch="k7"; pov_arch_fallback="i686";;
+          k8-*|x86_64-*)  pov_arch="k8"; pov_arch_fallback="i686";;
+          *)              pov_arch="unknown";;
+        esac
+      fi
+      if test -z "$pov_arch"; then
             pov_cpu=${pov_modelname:-`uname -p 2> /dev/null`}
             case "$pov_cpu" in
               # Intel
               *pentium*4*|*xeon*)  pov_arch="pentium4";;  # for GCC / ICC
               *pentium*mmx*)       pov_arch="pentium";;   # catch this first
-              *pentium*m*)
-                if test x"$CXX" = x"icc"; then
-                  pov_arch="pentium4"
-                else
-                  pov_arch="pentium-m"
-                fi
-                ;;
-              *pentium*iii*|*celeron*)  # assume all celerons belong here
-                if test x"$CXX" = x"icc"; then
-                  pov_arch="pentiumiii"
-                else
-                  pov_arch="pentium3"
-                fi
-                ;;
-              *pentium*ii*)
-                if test x"$CXX" = x"icc"; then
-                  pov_arch="pentiumii"
-                else
-                  pov_arch="pentium2"
-                fi
-                ;;
+              *pentium*m*)         pov_arch="pentium-m";;
+              *pentium*iii*)       pov_arch="pentium3";;
+              # assume all celerons belong here
+              *celeron*)           pov_arch="pentium3";;
+              *pentium*ii*)        pov_arch="pentium2";;
               *pentium*pro*)       pov_arch="pentiumpro";;  # for GCC / ICC
               *pentium*)           pov_arch="pentium";;     # for GCC / ICC
               # AMD
               *athlon*xp*)         pov_arch="athlon-xp";;
               *athlon*mp*)         pov_arch="athlon-mp";;
               *athlon*|*duron*)    pov_arch="athlon";;
-              # others
-              *)                   pov_arch="i686";;  # don't support true i386
+              *k6*)                pov_arch="k6";;
+              *k7*)                pov_arch="k7";;
+              *k8*)                pov_arch="k8";;
+              *x86_64*)            pov_arch="k8";;
+              # others -- don't support true i386
+              *)                   pov_arch="i686";;
+            esac
+            if test x"$CXX" = x"icc"; then
+              case "$pov_arch" in
+                pentium2)            pov_arch="pentiumii";;
+                pentium3)            pov_arch="pentiumiii";;
+                pentium-m)           pov_arch="pentium4";;
+              esac
+            fi
+
+            case "$pov_arch" in
+	      k6|pentium)            pov_arch_fallback="i586";;
+              k7|k8|athlon|pentium*) pov_arch_fallback="i686";;
             esac
-            pov_arch_fallback="i686"
-            ;;
-          k6-*)           pov_arch="k6"; pov_arch_fallback="i686";;
-          k7-*)           pov_arch="k7"; pov_arch_fallback="i686";;
-          k8-*|x86_64-*)  pov_arch="k8"; pov_arch_fallback="i686";;
-          *)              pov_arch="unknown";;
-        esac
       fi
       if test x"$pov_arch" != x"unknown"; then
         POV_PROG_CXX_FLAGS([-march=$pov_arch -mtune=$pov_arch],