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
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
pt=$base.pt
bin=$base.bin
lst=$base.lst
files=`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
fi
exps=""
sb=""
for file in $files; do
case $file in
*.sb)
sb_base=${file%.sb}
sb_part=${sb_base#$base-}
sb_prefix=${sb_part%%,*}
sb_options=${sb_part#$sb_prefix}
sb_prio=${sb_prefix##*-}
sb_prefix2=${sb_prefix%-$sb_prio}
sb_format=${sb_prefix2##*-}
sb+=`echo $sb_options | sed -e "s/,/ --$sb_format:/g" -e "s/=/ /g"`
sb+=" --$sb_format:$sb_prio $file"
;;
*.exp)
exps+=" $file"
;;
*)
echo "$ptt: unexpected $pttc_cmd output '$file'"
status=1
continue
;;
esac
done
if [[ -z $exps ]]; then
echo "$ptt: $pttc_cmd $pttc_arg did not produce any .exp file" >&2
status=1
return
fi
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 $sb > $out
;;
ptdump)
local opts=`ptt-ptdump-opts "$ptt"`
run "$ptdump_cmd" $ptdump_arg $cpu $opts $sb $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 [[ -z $cpus ]]; then
cpus=`ptt-cpus "$ptt"`
fi
if [[ -z $cpus ]]; then
run-ptt-test "$ptt"
return
fi
for i in $cpus; do
run-ptt-test "$ptt" $i
done
}
for ptt in "$@"; do
run-ptt-tests "$ptt"
done
exit $status