# $NetBSD: subr_NetBSD,v 1.13 2016/01/28 19:11:30 abs Exp $

AWK=awk
SED=sed

display_hw_details()
    {
    cat <<END
OS		: '$(uname)'
OS version	: '$(uname -r)'
hw.model	: '$hw_model'
hw.machine	: '$hw_machine'
hw.machine_arch : '$hw_machine_arch'
CPU		: '$cpu'
END
    extract_x86_cpu_vars
    echo "$cpu_details"
    }

extract_hw_details()
    {
    hw_model=$(sysctl -n hw.model | $SED 's/^  *//')
    hw_machine=$(sysctl -n hw.machine)
    hw_machine_arch=$(sysctl -n hw.machine_arch)
    if [ "$hw_machine_arch" = i386 -o "$hw_machine_arch" = x86_64 ] ; then
	if [ -x /usr/sbin/cpuctl ] ; then
	    cpu_details="$(cpuctl identify 0 | grep ^cpu0:)"
	else
	    cpu_details="$(grep ^cpu0: /var/run/dmesg.boot)"
	fi
	eval "$(extract_x86_cpu_vars)"
    fi

    # We're almost certainly crosscompiling
    if [ -n "$MACHINE" -a "$hw_machine" != "$MACHINE" ]; then
	echo
	exit
    fi
    }

extract_x86_cpu_vars()
    {
    # Set: cpu_feature_FOO=1 for each 'FOO' feature reported
    #      cpu_name="NAME" taken from the first cpu0: line
    #      cpu_brand="BRAND" the CPU branding string
    echo "$cpu_details" | $AWK '
    { gsub("[()]","") }
    { if (/cpu0:/ && !n) { sub("cpu0: ",""); n=1; print "cpu_name=\""$0"\"" } }
    /cpu0: ".*"/ { sub("[^\"]*", ""); print "cpu_brand="$0 }
    /cpu0: features\d?/ {
	sub(".*<","");
	sub(">.*","");
	gsub("[^,A-Z0-9]","_");
	split($0, features, /,/)
	for (f in features)
	    print "cpu_feature_"features[f]"=1";
	}
    /cpu0: family/ {
	for (i = 2; i < NF; i = i + 2) {
	    f=$(i+1);
	    print "cpu_"$i"="f
	    }
	}
    '
    }

determine_arch()
    {
    ARCH=
    # When adding $hw_model tests use maximum context (such as trailing space)
    case $hw_machine_arch in

    alpha)
	# cpu0 at mainbus0: ID 0 (primary), 21164A-0 (unknown ...
	case "$(egrep '^cpu0 ' /var/run/dmesg.boot)" in
	    *[\(\ ]2106[46][-A\ \)]*)	ARCH="-mcpu=21064"	;;
	    *[\(\ ]21164[-\ \)]*)	ARCH="-mcpu=21164"	;;
	    *[\(\ ]21164A[-\ \)]*)	ARCH="-mcpu=21164a"	;;
	    *[\(\ ]21264[-\ \)]*)	ARCH="-mcpu=21264"	;;
	    *[\(\ ]21264[AB][-\ \)]*)	ARCH="-mcpu=21264a"	;;
	    *\ PCA56-2)			ARCH="-mcpu=21164pc"	;;
	esac
	;;

    arm | arm32) case $hw_model in
	ARM610*)		ARCH="-mcpu=arm610"		;; # risc pc
	ARM710*)		ARCH="-mcpu=arm710"		;; # risc pc
	i80321\ *)		ARCH="-mcpu=xscale"		;; # iyonix
	SA-110*)	
	    case $hw_machine in			 # arm32 split post 1.5
		cats|shark|hpcarm|netwinder)
		    ARCH="-mcpu=strongarm110" ;;
		acorn32)
		    ARCH="-march=armv3m -mtune=strongarm" ;;
		*)
		    # memorybus in strongarm risc pc machines cannot support
		    # certain strongarm instructions, but in 1.5 and earlier
		    # all strongarm machines are 'arm32', so uname and sysctl
		    # no use
		    if egrep -q 'ofbus0|footbridge0' /var/run/dmesg.boot \
							    2>/dev/null ; then
			ARCH="-mcpu=strongarm110"		   # shark/cats
		    else
			ARCH="-march=armv3m -mtune=strongarm"	   # risc pc
		    fi
	    esac ;;
	esac ;;

    hppa)
	case "$(egrep '^cpu0 ' /var/run/dmesg.boot)" in
	   *\ PA7100\ *)       ARCH="-march=1.1 -mschedule=7100" ;; # untested
	   *\ PA7150\ *)       ARCH="-march=1.1 -mschedule=7100" ;; # untested
	   *\ PA7100LC\ *)     ARCH="-march=1.1 -mschedule=7100LC" ;; # untested
	   *\ PA7200\ *)       ARCH="-march=1.1 -mschedule=7200" ;; # untested
	   *\ PA7300LC\ *)     ARCH="-march=1.1 -mschedule=7300" ;; # B180L
	   *\ PA8*)	       ARCH="-march=2.0 -mschedule=8000" ;; # untested
	esac
	;;

    i386 | x86_64)
	include subr_x86	# this provides map_x86_brand_string()
	ARCH=$(map_x86_brand_string)
	if [ -z "$ARCH" ] ; then
	case "$cpu_name" in
	'AMD Athlon 64 X2 (686-class)'*)	   ARCH='-march=athlon64' ;;
	'AMD Athlon 64 or Athlon 64 FX or Opteron '*) ARCH='-march=opteron' ;;
	'AMD Athlon 64 or Sempron (686-class)'*)   ARCH='-march=athlon64' ;;
	'AMD Athlon Model 4 (Thunderbird) '*)	   ARCH='-march=athlon-tbird' ;;
	'AMD Dual-Core Opteron or Athlon 64 X2 '*) ARCH='-march=opteron' ;;
	'AMD Family 10h (686-class)'*)   	   ARCH='-march=amdfam10' ;;
	'AMD K6-2 (586-class)'*) 		   ARCH="-march=k6-2" ;;

	# Intel PIII & earlier - later Intel handled by map_x86_brand_string
	'Intel (686-class)'*)			   ARCH='-march=pentiumpro' ;;
	'Intel Pentium II (686-class)'*)	   ARCH='-march=pentium2' ;;
	'Intel Pentium III (686-class)'*)	   ARCH='-march=pentium3' ;;
	'Intel Pentium III (Katmai) (686-class)'*) ARCH='-march=pentium3' ;;
	'Intel Pentium III Xeon (686-class)'*)	   ARCH='-march=pentium3' ;;

	# Fallback classes
	*'(586-class)'*)			   ARCH='-march=pentium' ;;
	*'(486-class)'*)			   ARCH='-march=i486' ;;
	esac
	fi
	;;

    m68k) case $hw_model in				   # Examples
	*\(68020*|*\ MC68020\ *) ARCH='-m68020' ;; # Untested
	*\(68030*|*\ MC68030\ *) ARCH='-m68030' ;; # Mac LC III
	*\(68040*|*\ MC68040\ *) ARCH='-m68040' ;; # Untested
	*\(68060*|*\ MC68060\ *) ARCH='-m68060' ;; # Upgraded amiga 3000
    esac
    ;;

    mipseb|mipsel)
	# cpu0 at mainbus0: QED R4600 Orion CPU (0x2020) Rev. 2.0 with ...
	case $hw_model in
	    Infineon\ ADM5120)		ARCH='-march=4kc' ;;
	    *)
	    case "$(egrep '^cpu0 ' /var/run/dmesg.boot)" in
		*\ MIPS\ R2000\ *)	ARCH="-march=r2000" ;;
		*\ MIPS\ R3000\ *)	ARCH="-march=r3000" ;;
		*\ MIPS\ R3000A\ *)	ARCH="-march=r3000" ;;
		*\ Toshiba\ TX3912\ *)	ARCH="-march=r3900" ;;
		*\ Toshiba\ TX392[27]\ *) ARCH="-march=r3900" ;;
		*\ MIPS\ R4000\ *)	ARCH="-mtune=r4000 -mips2" ;; # mips3
		*\ MIPS\ R4400\ *)	ARCH="-mtune=r4400 -mips2" ;; # mips3
		*\ NEC\ VR4100\ *)	ARCH="-mtune=r4100 -mips2" ;; # mips3
		*\ NEC\ VR4300\ *)	ARCH="-mtune=r4300 -mips2" ;; # mips3
		*\ QED\ R4600\ *)	ARCH="-mtune=r4600 -mips2" ;; # mips3
		*\ MIPS\ R5000\ *)	ARCH="-mtune=r5000 -mips2" ;; # mips4
		*\ QED\ RM5200\ *)	ARCH="-mtune=r5000 -mips2" ;; # mips4
		*\ MIPS\ R6000\ *)	ARCH="-mtune=r6000 -mips2" ;;
		*\ MIPS\ R8000\ *)	ARCH="-mtune=r8000 -mips2" ;; # mips4
		*\ MIPS\ R10000\ *)	ARCH="-march=mips4 -mabi=32" ;; # mips4
	    esac ;;
	esac
	;;

    powerpc) case $hw_model in				   # Examples
	601\ *)			ARCH='-mcpu=601'	;; # Untested
	602\ *)			ARCH='-mcpu=602'	;; # Untested
	603\ *)			ARCH='-mcpu=603'	;; # Untested
	603e\ *|603ev\ *)	ARCH='-mcpu=603e'	;; # Umax C500 / PM4400
	604\ *)			ARCH='-mcpu=604'	;; # Mac 8500
	604e\ *)		ARCH='-mcpu=604e'	;; # upgr B&W G3
	604ev\ *)		ARCH='-mcpu=604e'	;; # usually 604e
	620\ *)			ARCH='-mcpu=620'	;; # Untested
	7400\ *)		ARCH='-mcpu=7400'	;; # AGP G4/400 Mac
	740\ *)			ARCH='-mcpu=740'	;; # Untested
	7410\ *)		ARCH='-mcpu=7400'	;; # powerbook g4
	7447A\ *)		ARCH='-mcpu=7450'	;; #
	7450\ *)		ARCH='-mcpu=7450'	;; # tibook 550
	750\ *)		       ARCH='-mcpu=750'	      ;; # orig. iBook

    esac ;;

    sparc | sparc64) case " $hw_model" in			   # Examples
	*[\ \(]MB86900/1A*)	ARCH='-mcpu=cypress'		;; # ss1+
	*[\ \(]L64811*)		ARCH='-mcpu=cypress'		;; # sun4/sun4c
	*[\ \(]CY7C601*)	ARCH='-mcpu=cypress'		;; # ss2
	*[\ \(]W8601/8701*)	ARCH='-mcpu=cypress'		;; # elc
	*[\ \(]MB86904*)	ARCH='-mcpu=supersparc' ;; # ss5 usparc
	*[\ \(]MB86907*)	ARCH='-mcpu=supersparc' ;; # ss5 usparc
	*[\ \(]TMS390S10*)	ARCH='-mcpu=supersparc' ;; # classic  "
	*[\ \(]TMS390Z50*)	ARCH='-mcpu=supersparc' ;; # ss10/ss20
	*[\ \(]RT620/625*)	ARCH='-mcpu=hypersparc' ;; # ss20 ross
	*[\ \(]MB86930*)	ARCH='-mcpu=sparclite'		;; # from gcc
	*[\ \(]MB86934*)	ARCH='-mcpu=sparclite'		;; # from gcc
	# under 1.5.1 -mcpu=ultrasparc chokes egcs-2.91.66 compiling perl
	*[\ \(]SUNW,UltraSPARC*) ARCH='-mcpu=v9'		;; # Ultra
    esac ;;

    vax) # No VAX specific gcc optimisations available
	NOARCH=1
	;;

    esac
    echo $ARCH
    }

determine_features()
    {
    FEATURES=

    case $hw_machine_arch in
	i386 | x86_64)
	    if [ -n "$cpu_feature_SSE3" ] ; then
		FEATURES="-mfpmath=sse -msse3"
	    elif [ -n "$cpu_feature_SSE2" ] ; then
		FEATURES="-mfpmath=sse -msse2"
	    elif [ -n "$cpu_feature_SSE" ] ; then
		FEATURES="-mfpmath=sse -msse"
	    fi
	    ;;
	m68k)
	    case "$(egrep '^fpu0 ' /var/run/dmesg.boot)" in
		*\(emulator\)*)		FEATURES="-msoft-float" ;;
		*\(no\ math\ support\)*) FEATURES="-msoft-float" ;;
	    esac
	    ;;
    esac
    echo $FEATURES
    }
