#! /bin/bash
#
# Copyright (c) 2013-2021, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#  * Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#  * Neither the name of Intel Corporation nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# This script executes ptt tests and compares the output of tools, like
# ptxed or ptdump, with the expected output from the ptt testfile.

info() {
	[[ $verbose != 0 ]] && echo -e "$@" >&2
}

run() {
	info "$@"
	"$@"
}

asm2addr() {
	local line
	line=`grep -i ^org "$1"`
	[[ $? != 0 ]] && return $?
	echo $line | sed "s/org *//"
}

usage() {
	cat <<EOF
usage: $0 [<options>] <pttfile>...

options:
  -h            this text
  -v            print commands as they are executed
  -c cpu[,cpu]  comma-separated list of cpu's for the tests (see pttc -h, for valid values)
  -f            exit with 1 if any of the tests failed
  -l            only list .diff files
  -g            specify the pttc command (default: pttc)
  -G            specify additional arguments to pttc
  -d            specify the ptdump command (default: ptdump)
  -D            specify additional arguments to ptdump
  -x            specify the ptxed command (default: ptxed)
  -X            specify additional arguments to ptxed

  <pttfile>     annotated yasm file ending in .ptt
EOF
}

pttc_cmd=pttc
pttc_arg=""
ptdump_cmd=ptdump
ptdump_arg=""
ptxed_cmd=ptxed
ptxed_arg=""
exit_fails=0
list=0
verbose=0
while getopts "hvc:flg:G:d:D:x:X:" option; do
	case $option in
	h)
		usage
		exit 0
		;;
	v)
		verbose=1
		;;
	c)
		cpus=`echo $OPTARG | sed "s/,/ /g"`
		;;
	f)
		exit_fails=1
		;;
	l)
		list=1
		;;
	g)
		pttc_cmd=$OPTARG
		;;
	G)
		pttc_arg=$OPTARG
		;;
	d)
		ptdump_cmd=$OPTARG
		;;
	D)
		ptdump_arg=$OPTARG
		;;
	x)
		ptxed_cmd=$OPTARG
		;;
	X)
		ptxed_arg=$OPTARG
		;;
	\?)
		exit 1
		;;
	esac
done

shift $(($OPTIND-1))

if [[ $# == 0 ]]; then
	usage
	exit 1
fi

# the exit status
status=0

ptt-ptdump-opts() {
	sed -n 's/[ \t]*;[ \t]*opt:ptdump[ \t][ \t]*\(.*\)[ \t]*/\1/p' "$1"
}

ptt-ptxed-opts() {
	sed -n 's/[ \t]*;[ \t]*opt:ptxed[ \t][ \t]*\(.*\)[ \t]*/\1/p' "$1"
}

run-ptt-test() {
	info "\n# run-ptt-test $@"

	ptt="$1"
	cpu="$2"
	base=`basename "${ptt%%.ptt}"`

	if [[ -n "$cpu" ]]; then
		cpu="--cpu $cpu"
	fi

	# the following are the files that are generated by pttc
	pt=$base.pt
	bin=$base.bin
	lst=$base.lst


	# execute pttc - remove the extra \r in Windows line endings
	exps=`run "$pttc_cmd" $pttc_arg $cpu "$ptt" | sed 's/\r\n/\n/g'`
	ret=$?
	if [[ $ret != 0 ]]; then
		echo "$ptt: $pttc_cmd $pttc_arg failed with $ret" >&2
		status=1
		return
	elif [[ -z $exps ]]; then
		echo "$ptt: $pttc_cmd $pttc_arg did not produce any .exp file" >&2
		status=1
		return
	fi

	# loop over all .exp files determine the tool, generate .out
	# files and compare .exp and .out file with diff.
	# all differences will be
	for exp in $exps; do
		exp_base=${exp%%.exp}
		out=$exp_base.out
		diff=$exp_base.diff
		tool=${exp_base##$base-}
		tool=${tool%%-cpu_*}
		case $tool in
		ptxed)
			addr=`asm2addr "$ptt"`
			if [[ $? != 0 ]]; then
				echo "$ptt: org directive not found in test file" >&2
				status=1
				continue
			fi
			local opts=`ptt-ptxed-opts "$ptt"`
			opts+=" --no-inst --check"
			run "$ptxed_cmd" $ptxed_arg --raw $bin:$addr $cpu $opts --pt $pt > $out
			;;
		ptdump)
			local opts=`ptt-ptdump-opts "$ptt"`
			run "$ptdump_cmd" $ptdump_arg $cpu $opts $pt > $out
			;;
		*)
			echo "$ptt: unknown tool '$tool'"
			status=1
			continue
			;;
		esac
		if run diff -ub $exp $out > $diff; then
			run rm $diff
		else
			if [[ $exit_fails != 0 ]]; then
				status=1
			fi

			if [[ $list != 0 ]]; then
				echo $diff
			else
				cat $diff
			fi
		fi
	done
}

ptt-cpus() {
	sed -n 's/[ \t]*;[ \t]*cpu[ \t][ \t]*\(.*\)[ \t]*/\1/p' "$1"
}

run-ptt-tests() {
	local ptt="$1"
	local cpus=$cpus

	# if no cpus are given on the command-line,
	# use the cpu directives from the pttfile.
	if [[ -z $cpus ]]; then
		cpus=`ptt-cpus "$ptt"`
	fi

	# if there are no cpu directives in the pttfile,
	# run the test without any cpu settings.
	if [[ -z $cpus ]]; then
		run-ptt-test "$ptt"
		return
	fi

	# otherwise run for each cpu the test.
	for i in $cpus; do
		run-ptt-test "$ptt" $i
	done
}

for ptt in "$@"; do
	run-ptt-tests "$ptt"
done

exit $status
