| #! /bin/bash |
| # |
| # Copyright (c) 2013-2019, 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 |
| 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 |
| |
| # 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 $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 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 |