#!/bin/sh

# which_sparc
#
# This script generates a program that tests for a SPARC processor class
# Program returns:
#  0 unknown SPARC processor
#  8 SPARC V8 `compliant' processor	(umul instruction is legal)
#  9 SPARC V9 `compliant' processor	(popc instruction is legal)
#
# The script prints:
#  "unknown SPARC architecture"
#  SPARC_V8
#  SPARC_V9
#
# I hope this works for other machines and OS. Tested machines are:
# Sun Ultra 10 (Solaris 7), SPARC Station 5 (Solaris 2.5.1)
#
# Gwenole Beauchesne
# gb@dial.oleane.com

CC=gcc
PROG=./conftest
SOURCE=./conftest.c

if [ ! -x $PROG ]; then
cat > $SOURCE << EOF
#include <stdio.h>
#include <signal.h>

typedef unsigned int uint32;
typedef uint32 (*sparc_code_func)(void);

#define SPARC_UNKNOWN	0
#define SPARC_V8		8
#define SPARC_V9		9

#define MAX_CODE_SIZE	16
struct sparc_code_struct {
	int							version;
	uint32						code[MAX_CODE_SIZE];
	struct sparc_code_struct *	next;
};
typedef struct sparc_code_struct sparc_code_struct;

static sparc_code_struct *current_test_code;

static sparc_code_struct unknown_sparc_code =
{
	SPARC_UNKNOWN,
	{
		0x81C3E008,		/*	retl					*/
		0x01000000		/*	nop						*/
	}
};

static sparc_code_struct sparc_v9_code =
{
	SPARC_V9,
	{
		0x81C3E008,		/*	retl					*/
		0x81702007		/*	popc	7, %g0			*/
	}
};

static sparc_code_struct sparc_v8_code =
{
	SPARC_V8,
	{
		0x90102002,		/*	mov		2, %o0			*/
		0x81C3E008,		/*	retl					*/
		0x90520008		/*	umul	%o0, %o0, %o0	*/
	}
};

static void test_sparc_code(int unused_int)
{
	sparc_code_struct *tested_code = current_test_code;
	
	if (current_test_code == NULL)
		exit(SPARC_UNKNOWN);
	
	signal(SIGILL, test_sparc_code);
	current_test_code = current_test_code->next;
	(void) ((sparc_code_func)(tested_code->code))();
	exit(tested_code->version);
}

int main(void)
{
	sparc_v9_code.next = &sparc_v8_code;
	sparc_v8_code.next = &unknown_sparc_code;
	unknown_sparc_code.next = NULL;
	
	signal(SIGILL, test_sparc_code);
	current_test_code = &sparc_v9_code;
	raise(SIGILL);
	
	return 0;
}
EOF

$CC -o $PROG $SOURCE
if [ $? -ne 0 ]; then
	echo "Error: could not compile the test program"
	exit 1
fi

fi

$PROG
case $? in
	0) echo "unknown SPARC architecture";;
	8) echo "SPARC_V8";;
	9) echo "SPARC_V9";;
esac

rm -f $PROG
rm -f $SOURCE

exit 0
