#! /bin/sh
#
# GMP config.guess wrapper.


# Copyright 2000, 2001 Free Software Foundation, Inc.
#
# This file is part of the GNU MP Library.
#
# The GNU MP Library is free software; you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published
# by the Free Software Foundation; either version 2.1 of the License, or (at
# your option) any later version.
#
# The GNU MP Library is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
# License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
# MA 02111-1307, USA.


# Usage: config.guess
#
# Print the host system CPU-VENDOR-OS.  configfsf.guess is run and its
# guess then sharpened up to take advantage of the finer grained CPU
# types GMP knows.


# Expect to find configfsf.guess in the same directory as this config.guess
configfsf_guess="`echo \"$0\" | sed 's/config.guess$/configfsf.guess/'`"
if test "$configfsf_guess" = "$0"; then
  echo "Cannot derive configfsf.guess from $0" 1>&2
  exit 1
fi
if test -f "$configfsf_guess"; then
  :
else
  echo "$configfsf_guess not found" 1>&2
  exit 1
fi

# Always run configfsf.guess with $SHELL, like autoconf does for config.guess
SHELL=${CONFIG_SHELL-/bin/sh}

# Identify ourselves on --version, --help or errors
if test $# != 0; then
  echo "(GNU MP wrapped config.guess)"
  $SHELL $configfsf_guess "$@"
  exit 1
fi


guess_full=`$SHELL $configfsf_guess`
if test $? != 0; then
  exit 1
fi

guess_cpu=`echo "$guess_full" | sed 's/-.*$//'`
guess_rest=`echo "$guess_full" | sed 's/^[^-]*//'`
exact_cpu=


# -------------------------------------------------------------------------
# The following should look at the current guess and probe the system to
# establish a better guess in exact_cpu.  Leave exact_cpu empty if probes
# can't be done, or don't work.
#
# When a number of probes are done, test -z "$exact_cpu" can be used instead
# of putting each probe under an "else" of the preceeding.  That can stop
# the code getting horribly nested and marching off the right side of the
# screen.


dummy=dummy-$$
trap 'rm -f $dummy.c $dummy.o $dummy ${dummy}1.s ${dummy}2.c ; exit 1' 1 2 15

# Use $HOST_CC if defined. $CC may point to a cross-compiler
if test x"$CC_FOR_BUILD" = x; then
  if test x"$HOST_CC" != x; then
    CC_FOR_BUILD="$HOST_CC"
  else
    if test x"$CC" != x; then
      CC_FOR_BUILD="$CC"
    else
      echo 'dummy(){}' >$dummy.c
      for c in cc c89 gcc; do 
	  ($c $dummy.c -c) >/dev/null 2>&1
	  if test $? = 0; then
	      CC_FOR_BUILD="$c"; break
	  fi
      done
      rm -f $dummy.c $dummy.o
      if test x"$CC_FOR_BUILD" = x; then
	CC_FOR_BUILD=no_compiler_found
      fi
    fi
  fi
fi


case "$guess_full" in

alpha*-*-netbsd* | alpha*-*-freebsd* | alpha*-*-openbsd*)
  # configfsf.guess has a block of code not unlike this for OSF and linsux.
  # Perhaps it'll support *BSD too some time, in which case the code here
  # can be removed.

  cat <<EOF >$dummy.s
	.globl main
	.ent main
main:
	.frame \$30,0,\$26,0
	.prologue 0
	.long 0x47e03d80 # implver $0
	lda \$2,259
	.long 0x47e20c21 # amask $2,$1
	srl \$1,8,\$2
	sll \$2,2,\$2
	sll \$0,3,\$0
	addl \$1,\$0,\$0
	addl \$2,\$0,\$0
	ret \$31,(\$26),1
	.end main
EOF
  $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
  if test "$?" = 0 ; then
    ./$dummy
    case "$?" in
     7) exact_cpu=alpha      ;;
    15)	exact_cpu=alphaev5   ;;
    14) exact_cpu=alphaev56  ;;
    10)	exact_cpu=alphapca56 ;;
    16)	exact_cpu=alphaev6   ;;
    esac
  fi
  rm -f $dummy.s $dummy
  ;;

mips-*-irix[6789]*)
  # IRIX 6 and up always has a 64-bit mips cpu
  exact_cpu=mips64
  ;;

m68k-*-*)
  # NetBSD (and presumably other *BSD) "sysctl hw.model" gives for example
  #   hw.model = Apple Macintosh Quadra 610  (68040)
  exact_cpu=`(sysctl hw.model) 2>/dev/null | sed -n 's/^.*\(680[012346]0\).*$/m\1/p'`
  if test -z "$exact_cpu"; then
    # Linux kernel 2.2 gives for example "CPU: 68020" (tabs in between).
    exact_cpu=`sed -n 's/^CPU:.*\(680[012346]0\).*$/m\1/p' /proc/cpuinfo 2>/dev/null`
  fi
  if test -z "$exact_cpu"; then
    # Try: movel #0,%d0; rts
    # This is to check the compiler and our asm code works etc, before
    # assuming failures below indicate cpu characteristics.
    # .byte is used to avoid problems with assembler syntax variations.
    # For testing, provoke failures by adding "illegal" possibly as
    # ".byte 0x4A, 0xFC"
    cat >$dummy.s <<EOF
	.text
	.globl main
	.globl _main
main:
_main:
	.byte	0x70, 0x00
	.byte	0x4e, 0x75
EOF
    if ($CC_FOR_BUILD $dummy.s -o $dummy && ./$dummy) >/dev/null 2>&1; then

      # $SHELL -c is used to execute ./$dummy below, since (./$dummy)
      # 2>/dev/null still prints the SIGILL message on some shells.
      #
        # Try: movel #0,%d0
        #      rtd #0
        cat >$dummy.s <<EOF
	.text
	.globl main
	.globl _main
main:
_main:
	.byte	0x70, 0x00
	.byte	0x4e, 0x74, 0x00, 0x00
EOF
        if $CC_FOR_BUILD $dummy.s -o $dummy >/dev/null 2>&1; then
          $SHELL -c ./$dummy >/dev/null 2>&1
	  if test $? != 0; then
            exact_cpu=m68000    # because rtd didn't work
          fi
        fi
      #

      if test -z "$exact_cpu"; then
        # Try: trapf
        #      movel #0,%d0
        #      rts
        # Another possibility for identifying 68000 and 68010 is the
        # different value stored by "movem a0,(a0)+"
        cat >$dummy.s <<EOF
	.text
	.globl main
	.globl _main
main:
_main:
	.byte	0x51, 0xFC
	.byte	0x70, 0x00
	.byte	0x4e, 0x75
EOF
        if $CC_FOR_BUILD $dummy.s -o $dummy >/dev/null 2>&1; then
          $SHELL -c ./$dummy >/dev/null 2>&1
	  if test $? != 0; then
            exact_cpu=m68010    # because trapf didn't work
          fi
        fi
      fi

      if test -z "$exact_cpu"; then
        # Try: bfffo %d1{0:31},%d0
        #      movel #0,%d0
        #      rts
        cat >$dummy.s <<EOF
	.text
	.globl main
	.globl _main
main:
_main:
	.byte	0xED, 0xC1, 0x00, 0x1F
	.byte	0x70, 0x00
	.byte	0x4e, 0x75
EOF
        if $CC_FOR_BUILD $dummy.s -o $dummy >/dev/null 2>&1; then
          $SHELL -c ./$dummy >/dev/null 2>&1
	  if test $? != 0; then
            exact_cpu=m68360  # cpu32, because bfffo didn't work
          fi
        fi
      fi

      if test -z "$exact_cpu"; then
        # FIXME: Now we know 68020 or up, but how to detect 030, 040 and 060?
        exact_cpu=m68020
      fi
    fi
    rm -f $dummy.s $dummy $dummy.core core
  fi
  if test -z "$exact_cpu"; then
    case "$guess_full" in
      *-*-next* | *-*-openstep*)  # NeXTs are 68020 or better
        exact_cpu=m68020 ;;
    esac
  fi
  ;;

rs6000-*-aix4* | powerpc-*-aix4*)
  cat >$dummy.c <<EOF
#include <stdio.h>
#include <sys/systemcfg.h>
main ()
{
  if (_system_configuration.architecture == POWER_RS
      || _system_configuration.implementation == POWER_601)
    puts ("power");
  else
    {
      if (_system_configuration.width == 64)
        puts ("powerpc64");
      else
        puts ("powerpc");
    }
  exit (0);
}
EOF
  if ($CC_FOR_BUILD $dummy.c -o $dummy) >/dev/null 2>&1; then
    exact_cpu=`./$dummy`
  fi
  rm -f $dummy.c $dummy
  ;;

sparc-*-*)
  case "`uname -m`" in
  sun4[md]) exact_cpu=sparcv8 ;;
  sun4u)    exact_cpu=sparcv9 ;;
  esac
  ;;

i?86-*-*)
  cat <<EOF >${dummy}1.s
	.globl cpuid
	.globl _cpuid
cpuid:
_cpuid:
	pushl %esi
	pushl %ebx
	movl 16(%esp),%eax
	.byte 0x0f
	.byte 0xa2
	movl 12(%esp),%esi
	movl %ebx,(%esi)
	movl %edx,4(%esi)
	movl %ecx,8(%esi)
	popl %ebx
	popl %esi
	ret
EOF
  cat <<EOF >${dummy}2.c
main ()
{
  char vendor_string[13];
  char dummy_string[12];
  long fms;
  int family, model;
  char *modelstr;

  cpuid (vendor_string, 0);
  vendor_string[12] = 0;

  fms = cpuid (dummy_string, 1);

  family = (fms >> 8) & 15;
  model = (fms >> 4) & 15;

  modelstr = "i486";
  if (strcmp (vendor_string, "GenuineIntel") == 0)
    {
      switch (family)
	{
	case 5:
	  if (model <= 2)	modelstr = "pentium";
	  else if (model >= 4)	modelstr = "pentiummmx";
	  break;
	case 6:
	  if (model == 1)	modelstr = "pentiumpro";
	  else if (model <= 6)	modelstr = "pentium2";
	  else			modelstr = "pentium3";
	  break;
	case 15:
	  modelstr = "pentium4";
	  break;
	}
    }
  else if (strcmp (vendor_string, "AuthenticAMD") == 0)
    {
      switch (family)
	{
	case 5:
	  if (model <= 3)	modelstr = "k5";
	  else if (model <= 7)	modelstr = "k6";
	  else if (model <= 8)	modelstr = "k62";
	  else if (model <= 9)	modelstr = "k63";
	  break;
	case 6:
	  modelstr = "athlon";
	  break;
	}
    }
  else if (strcmp (vendor_string, "CyrixInstead") == 0)
    {
      /* Should recognize Cyrix' processors too.  */
    }

  printf ("%s\n", modelstr);
  return 0;
}
EOF

  $CC_FOR_BUILD ${dummy}1.s ${dummy}2.c -o $dummy >/dev/null 2>&1
  if test "$?" = 0 ; then
    exact_cpu=`./$dummy`
  fi

  # We need to remove some .o files here since lame C compilers
  # generate these even when not asked.
  rm -f ${dummy}1.s ${dummy}1.o ${dummy}2.c ${dummy}2.o $dummy
  ;;

esac



# -------------------------------------------------------------------------
# Use an exact cpu, if possible

if test -n "$exact_cpu"; then
  echo "$exact_cpu$guess_rest"
else
  echo "$guess_full"
fi
exit 0



# Local variables:
# fill-column: 76
# End:
