12380c36eSRobert Mustacchi#!/usr/bin/ksh
22380c36eSRobert Mustacchi#
32380c36eSRobert Mustacchi# This file and its contents are supplied under the terms of the
42380c36eSRobert Mustacchi# Common Development and Distribution License ("CDDL"), version 1.0.
52380c36eSRobert Mustacchi# You may only use this file in accordance with the terms of version
62380c36eSRobert Mustacchi# 1.0 of the CDDL.
72380c36eSRobert Mustacchi#
82380c36eSRobert Mustacchi# A full copy of the text of the CDDL should have accompanied this
92380c36eSRobert Mustacchi# source.  A copy of the CDDL is also available via the Internet at
102380c36eSRobert Mustacchi# http://www.illumos.org/license/CDDL.
112380c36eSRobert Mustacchi#
122380c36eSRobert Mustacchi
132380c36eSRobert Mustacchi#
14*1f154020SRobert Mustacchi# Copyright 2018 Joyent, Inc.
152380c36eSRobert Mustacchi#
162380c36eSRobert Mustacchi
172380c36eSRobert Mustacchi#
182380c36eSRobert Mustacchi# libdis test driver
192380c36eSRobert Mustacchi#
202380c36eSRobert Mustacchi# Tests are arranged by architecture. By default we'll run all of the
212380c36eSRobert Mustacchi# dis tests on our current architecture only. If the -p option is passed
222380c36eSRobert Mustacchi# to point to other correctly built gas instances, then we'll run those
232380c36eSRobert Mustacchi# tests, verifying that the cross-dis works.
242380c36eSRobert Mustacchi#
252380c36eSRobert Mustacchi# Each test should begin with one of the following three keywords:
262380c36eSRobert Mustacchi#
272380c36eSRobert Mustacchi#	tst	- Run both the 32-bit and 64-bit versions
282380c36eSRobert Mustacchi#	32	- Only run this with the gas 32-bit flag
292380c36eSRobert Mustacchi#	64	- Only run this with the gas 64-bit flag
302380c36eSRobert Mustacchi#
312380c36eSRobert Mustacchi# For example, tst.smap.s, would be built both 32-bit and 64-bit and compared to
322380c36eSRobert Mustacchi# its output file.
332380c36eSRobert Mustacchi#
342380c36eSRobert Mustacchi# Each input file should consist of a series of instructions in a function named
352380c36eSRobert Mustacchi# 'libdis_test'. The test suite will compile this file into an object file,
362380c36eSRobert Mustacchi# disassemble it, and compare it to the output file.
372380c36eSRobert Mustacchi#
382380c36eSRobert Mustacchi# For each input file, there should be a corresponding output file with the .out
392380c36eSRobert Mustacchi# suffix instead of the .s suffix. So, if you had tst.smap.s, you should have
402380c36eSRobert Mustacchi# tst.smap.out.
412380c36eSRobert Mustacchi#
422380c36eSRobert Mustacchi
432380c36eSRobert Mustacchiunalias -a
442380c36eSRobert Mustacchidt_arg0=$(basename $0)
452380c36eSRobert Mustacchidt_dis="/usr/bin/dis -qF libdis_test"
462380c36eSRobert Mustacchidt_diff="/usr/bin/cmp -s"
472380c36eSRobert Mustacchidt_defas="gas"
482380c36eSRobert Mustacchidt_defarch=
492380c36eSRobert Mustacchidt_nodefault=
502380c36eSRobert Mustacchidt_tests=
512380c36eSRobert Mustacchidt_tnum=0
522380c36eSRobert Mustacchidt_tfail=0
532380c36eSRobert Mustacchidt_tsuc=0
542380c36eSRobert Mustacchidt_origwd=
552380c36eSRobert Mustacchidt_root=
562380c36eSRobert Mustacchidt_faildir=0
572380c36eSRobert Mustacchitypeset -A dt_platforms
582380c36eSRobert Mustacchi
592380c36eSRobert Mustacchifatal()
602380c36eSRobert Mustacchi{
612380c36eSRobert Mustacchi	typeset msg="$*"
622380c36eSRobert Mustacchi	[[ -z "$msg" ]] && msg="failed"
632380c36eSRobert Mustacchi	echo "$dt_arg0: $msg" >&2
642380c36eSRobert Mustacchi	exit 1
652380c36eSRobert Mustacchi}
662380c36eSRobert Mustacchi
672380c36eSRobert Mustacchiusage()
682380c36eSRobert Mustacchi{
692380c36eSRobert Mustacchi	typeset msg="$*"
702380c36eSRobert Mustacchi	[[ -z "$msg" ]] || echo "$msg" 2>&1
712380c36eSRobert Mustacchi	cat <<USAGE >&2
722380c36eSRobert MustacchiUsage: $dt_arg0  [-n] [ -p platform=pathtoas ]... [ test ]...
732380c36eSRobert Mustacchi
742380c36eSRobert Mustacchi	Runs all dis for the current platform or only specified tests if listed.
752380c36eSRobert Mustacchi
762380c36eSRobert Mustacchi	-n			Don't run default platform tests
772380c36eSRobert Mustacchi	-p platform=pathtoas	Run tests for platform using assembler. Should
782380c36eSRobert Mustacchi				either be an absolute path or a command on the
792380c36eSRobert Mustacchi				path.
802380c36eSRobert MustacchiUSAGE
81*1f154020SRobert Mustacchi	exit 2
822380c36eSRobert Mustacchi}
832380c36eSRobert Mustacchi
842380c36eSRobert Mustacchi#
852380c36eSRobert Mustacchi# By default, tests only run for the current platform. In other words,
862380c36eSRobert Mustacchi# running on an x86 system only assumes that the tests in the i386
872380c36eSRobert Mustacchi# directory should be run. If the -p option is specified, then other
882380c36eSRobert Mustacchi# platforms will be run.
892380c36eSRobert Mustacchi#
902380c36eSRobert Mustacchi# Right now, we only support running this on x86 natively; however, you
912380c36eSRobert Mustacchi# can run tests for other platforms with the -p option.
922380c36eSRobert Mustacchi#
932380c36eSRobert Mustacchidetermine_arch()
942380c36eSRobert Mustacchi{
952380c36eSRobert Mustacchi	typeset arch
962380c36eSRobert Mustacchi
972380c36eSRobert Mustacchi	arch=$(uname -p)
982380c36eSRobert Mustacchi	[[ $? -eq 0 ]] || fatal "failed to determine host architecture"
992380c36eSRobert Mustacchi	[[ "$arch" != "i386" ]] && fatal "dis tests are only supported on x86"
1002380c36eSRobert Mustacchi	[[ -n "$dt_nodefault" ]] && return
1012380c36eSRobert Mustacchi	dt_defarch="i386"
1022380c36eSRobert Mustacchi	dt_platforms[$dt_defarch]=$dt_defas
1032380c36eSRobert Mustacchi}
1042380c36eSRobert Mustacchi
1052380c36eSRobert Mustacchi#
1062380c36eSRobert Mustacchi# Iterate over the set of platforms and verify that we both know about them and
1072380c36eSRobert Mustacchi# we can find the assembler for them.
1082380c36eSRobert Mustacchi#
1092380c36eSRobert Mustacchicheck_platforms()
1102380c36eSRobert Mustacchi{
1112380c36eSRobert Mustacchi	typeset key
1122380c36eSRobert Mustacchi
1132380c36eSRobert Mustacchi	for key in ${!dt_platforms[@]}; do
1142380c36eSRobert Mustacchi		typeset bin
1152380c36eSRobert Mustacchi		[[ -d $dt_root/$key ]] || fatal "encountered unknown platform: $key"
1162380c36eSRobert Mustacchi
1172380c36eSRobert Mustacchi		#
1182380c36eSRobert Mustacchi		# This may be a path or something else.
1192380c36eSRobert Mustacchi		#
1202380c36eSRobert Mustacchi		bin=${dt_platforms[$key]}
1212380c36eSRobert Mustacchi		[[ -x $bin ]] && continue
1222380c36eSRobert Mustacchi		which $bin >/dev/null 2>&1 && continue
1232380c36eSRobert Mustacchi		fatal "failed to find command as absolute path or file: $bin"
1242380c36eSRobert Mustacchi	done
1252380c36eSRobert Mustacchi}
1262380c36eSRobert Mustacchi
1272380c36eSRobert Mustacchihandle_failure()
1282380c36eSRobert Mustacchi{
1292380c36eSRobert Mustacchi	typeset dir reason source out
1302380c36eSRobert Mustacchi	dir=$1
1312380c36eSRobert Mustacchi	reason=$2
1322380c36eSRobert Mustacchi	source=$3
1332380c36eSRobert Mustacchi	out=$4
1342380c36eSRobert Mustacchi	faildir=
1352380c36eSRobert Mustacchi
1362380c36eSRobert Mustacchi	while [[ -d failure.$dt_faildir ]]; do
1372380c36eSRobert Mustacchi		((dt_faildir++))
1382380c36eSRobert Mustacchi	done
1392380c36eSRobert Mustacchi
1402380c36eSRobert Mustacchi	faildir="failure.$dt_faildir"
1412380c36eSRobert Mustacchi	mv $dir $faildir
1422380c36eSRobert Mustacchi	cp $source $faildir/
1432380c36eSRobert Mustacchi	cp $out $faildir/
1442380c36eSRobert Mustacchi	printf "%s " "failed "
1452380c36eSRobert Mustacchi	[[ -n $reason ]] && printf "%s " $reason
1462380c36eSRobert Mustacchi	printf "%s\n" "$faildir"
1472380c36eSRobert Mustacchi	((dt_tfail++))
1482380c36eSRobert Mustacchi}
1492380c36eSRobert Mustacchi
1502380c36eSRobert Mustacchi#
1512380c36eSRobert Mustacchi# Check
1522380c36eSRobert Mustacchi#
1532380c36eSRobert Mustacchitest_one()
1542380c36eSRobert Mustacchi{
1552380c36eSRobert Mustacchi	typeset gflags source cmp disfile outfile extra aserr diserr
1562380c36eSRobert Mustacchi	dir="dis.$$"
1572380c36eSRobert Mustacchi	gflags=$1
1582380c36eSRobert Mustacchi	source=$2
1592380c36eSRobert Mustacchi	cmp=$3
1602380c36eSRobert Mustacchi	extra=$4
1612380c36eSRobert Mustacchi
1622380c36eSRobert Mustacchi	outfile=$dir/dis.o
1632380c36eSRobert Mustacchi	aserr=$dir/as.stderr
1642380c36eSRobert Mustacchi	disfile=$dir/libdis.out
1652380c36eSRobert Mustacchi	diserr=$dir/dis.stderr
1662380c36eSRobert Mustacchi
1672380c36eSRobert Mustacchi	((dt_tnum++))
1682380c36eSRobert Mustacchi	mkdir -p $dir || fatal "failed to make directory $dir"
1692380c36eSRobert Mustacchi
1702380c36eSRobert Mustacchi	printf "testing %s " $source
1712380c36eSRobert Mustacchi	[[ -n $extra ]] && printf "%s " $extra
1722380c36eSRobert Mustacchi	printf "... "
1732380c36eSRobert Mustacchi	if ! $gas $gflags -o $outfile $source 2>$aserr >/dev/null; then
1742380c36eSRobert Mustacchi		handle_failure $dir "(assembling)" $source $cmp
1752380c36eSRobert Mustacchi		return
1762380c36eSRobert Mustacchi	fi
1772380c36eSRobert Mustacchi
1782380c36eSRobert Mustacchi	if ! $dt_dis $outfile >$disfile 2>$diserr; then
1792380c36eSRobert Mustacchi		handle_failure $dir "(disassembling)" $source $cmp
1802380c36eSRobert Mustacchi		return
1812380c36eSRobert Mustacchi	fi
1822380c36eSRobert Mustacchi
1832380c36eSRobert Mustacchi	if ! $dt_diff $disfile $cmp; then
1842380c36eSRobert Mustacchi		handle_failure $dir "(comparing)" $source $cmp
1852380c36eSRobert Mustacchi		return
1862380c36eSRobert Mustacchi	fi
1872380c36eSRobert Mustacchi
1882380c36eSRobert Mustacchi	((dt_tsuc++))
1892380c36eSRobert Mustacchi	print "passed"
1902380c36eSRobert Mustacchi	rm -rf $dir || fatal "failed to remove directory $dir"
1912380c36eSRobert Mustacchi}
1922380c36eSRobert Mustacchi
1932380c36eSRobert Mustacchi#
1942380c36eSRobert Mustacchi# Run a single test. This may result in two actual tests (one 32-bit and one
1952380c36eSRobert Mustacchi# 64-bit) being run.
1962380c36eSRobert Mustacchi#
1972380c36eSRobert Mustacchirun_single_file()
1982380c36eSRobert Mustacchi{
1992380c36eSRobert Mustacchi	typeset sfile base cmpfile prefix arch gas p flags
200*1f154020SRobert Mustacchi	typeset asflags32 asflags64
2012380c36eSRobert Mustacchi	sfile=$1
2022380c36eSRobert Mustacchi
2032380c36eSRobert Mustacchi	base=${sfile##*/}
2042380c36eSRobert Mustacchi	cmpfile=${sfile%.*}.out
2052380c36eSRobert Mustacchi	prefix=${base%%.*}
2062380c36eSRobert Mustacchi	arch=${sfile%/*}
2072380c36eSRobert Mustacchi	arch=${arch##*/}
2082380c36eSRobert Mustacchi	[[ -f $cmpfile ]] || fatal "missing output file $cmpfile"
2092380c36eSRobert Mustacchi	gas=${dt_platforms[$arch]}
2102380c36eSRobert Mustacchi	[[ -n $gas ]] || fatal "encountered test $sfile, but missing assembler"
2112380c36eSRobert Mustacchi
212*1f154020SRobert Mustacchi	case "$arch" in
213*1f154020SRobert Mustacchi	"risc-v")
214*1f154020SRobert Mustacchi		asflags32="-march=rv32g"
215*1f154020SRobert Mustacchi		asflags64="-march=rv64g"
216*1f154020SRobert Mustacchi		;;
217*1f154020SRobert Mustacchi	"risc-v-c")
218*1f154020SRobert Mustacchi		asflags32="-march=rv32gc"
219*1f154020SRobert Mustacchi		asflags64="-march=rv64gc"
220*1f154020SRobert Mustacchi		;;
221*1f154020SRobert Mustacchi	*)
222*1f154020SRobert Mustacchi		asflags32="-32"
223*1f154020SRobert Mustacchi		asflags64="-64"
224*1f154020SRobert Mustacchi		;;
225*1f154020SRobert Mustacchi	esac
226*1f154020SRobert Mustacchi
2272380c36eSRobert Mustacchi	case "$prefix" in
2282380c36eSRobert Mustacchi	32)
229*1f154020SRobert Mustacchi		test_one $asflags32 $sfile $cmpfile
2302380c36eSRobert Mustacchi		;;
2312380c36eSRobert Mustacchi	64)
232*1f154020SRobert Mustacchi		test_one $asflags64 $sfile $cmpfile
2332380c36eSRobert Mustacchi		;;
2342380c36eSRobert Mustacchi	tst)
235*1f154020SRobert Mustacchi		test_one $asflags32 $sfile $cmpfile "(32-bit)"
236*1f154020SRobert Mustacchi		test_one $asflags64 $sfile $cmpfile "(64-bit)"
2372380c36eSRobert Mustacchi		;;
2382380c36eSRobert Mustacchi	esac
2392380c36eSRobert Mustacchi}
2402380c36eSRobert Mustacchi
2412380c36eSRobert Mustacchi#
2422380c36eSRobert Mustacchi# Iterate over all the test directories and run the specified tests
2432380c36eSRobert Mustacchi#
2442380c36eSRobert Mustacchirun_tests()
2452380c36eSRobert Mustacchi{
2462380c36eSRobert Mustacchi	typeset t
2472380c36eSRobert Mustacchi	if [[ $# -ne 0 ]]; then
2482380c36eSRobert Mustacchi		for t in $@; do
2492380c36eSRobert Mustacchi			run_single_file $t
2502380c36eSRobert Mustacchi		done
2512380c36eSRobert Mustacchi	else
2522380c36eSRobert Mustacchi		typeset k tests tests32 tests64
2532380c36eSRobert Mustacchi		for k in ${!dt_platforms[@]}; do
2542380c36eSRobert Mustacchi			tests=$(find $dt_root/$k -type f -name 'tst.*.s')
2552380c36eSRobert Mustacchi			tests32=$(find $dt_root/$k -type f -name '32.*.s')
2562380c36eSRobert Mustacchi			tests64=$(find $dt_root/$k -type f -name '64.*.s')
2572380c36eSRobert Mustacchi			for t in $tests $tests32 $tests64; do
2582380c36eSRobert Mustacchi				run_single_file $t
2592380c36eSRobert Mustacchi			done
2602380c36eSRobert Mustacchi		done
2612380c36eSRobert Mustacchi	fi
2622380c36eSRobert Mustacchi}
2632380c36eSRobert Mustacchi
2642380c36eSRobert Mustacchigoodbye()
2652380c36eSRobert Mustacchi{
2662380c36eSRobert Mustacchi	cat <<EOF
2672380c36eSRobert Mustacchi
2682380c36eSRobert Mustacchi--------------
2692380c36eSRobert Mustacchilibdis Results
2702380c36eSRobert Mustacchi--------------
2712380c36eSRobert Mustacchi
2722380c36eSRobert MustacchiTests passed: $dt_tsuc
2732380c36eSRobert MustacchiTests failed: $dt_tfail
2742380c36eSRobert MustacchiTests ran:    $dt_tnum
2752380c36eSRobert MustacchiEOF
2762380c36eSRobert Mustacchi}
2772380c36eSRobert Mustacchi
2782380c36eSRobert Mustacchi
2792380c36eSRobert Mustacchidt_origwd=$PWD
2802380c36eSRobert Mustacchicd $(dirname $0) || fatal "failed to cd to test root"
2812380c36eSRobert Mustacchidt_root=$PWD
2822380c36eSRobert Mustacchicd $dt_origwd || fatal "failed to return to original dir"
2832380c36eSRobert Mustacchi
2842380c36eSRobert Mustacchiwhile getopts ":np:" c $@; do
2852380c36eSRobert Mustacchi	case "$c" in
2862380c36eSRobert Mustacchi	n)
2872380c36eSRobert Mustacchi		dt_nodefault="y"
2882380c36eSRobert Mustacchi		;;
2892380c36eSRobert Mustacchi	p)
290*1f154020SRobert Mustacchi		OLDIFS=$IFS
2912380c36eSRobert Mustacchi		IFS="="
2922380c36eSRobert Mustacchi		set -A split $OPTARG
293*1f154020SRobert Mustacchi		IFS=$OLDIFS
2942380c36eSRobert Mustacchi		[[ ${#split[@]} -eq 2 ]] || usage "malformed -p option: $OPTARG"
2952380c36eSRobert Mustacchi		dt_platforms[${split[0]}]=${split[1]}
2962380c36eSRobert Mustacchi		;;
2972380c36eSRobert Mustacchi	:)
2982380c36eSRobert Mustacchi		usage "option requires an argument -- $OPTARG"
2992380c36eSRobert Mustacchi		;;
3002380c36eSRobert Mustacchi	*)
3012380c36eSRobert Mustacchi		usage "invalid option -- $OPTARG"
3022380c36eSRobert Mustacchi		;;
3032380c36eSRobert Mustacchi	esac
3042380c36eSRobert Mustacchidone
3052380c36eSRobert Mustacchi
3062380c36eSRobert Mustacchi[[ -n $dt_nodefault && ${#dt_platforms[@]} -eq 0 ]] && fatal \
3072380c36eSRobert Mustacchi    "no platforms specified to run tests for"
3082380c36eSRobert Mustacchi
3092380c36eSRobert Mustacchishift $((OPTIND-1))
3102380c36eSRobert Mustacchi
3112380c36eSRobert Mustacchidetermine_arch
3122380c36eSRobert Mustacchicheck_platforms
3132380c36eSRobert Mustacchirun_tests
3142380c36eSRobert Mustacchigoodbye
3152380c36eSRobert Mustacchi
3162380c36eSRobert Mustacchi[[ $dt_tfail -eq 0 ]]
317