Files
cell/src/qbe/tools/test.sh
2026-02-17 10:23:47 -06:00

268 lines
3.8 KiB
Bash
Executable File

#!/bin/sh
dir=`dirname "$0"`
if [ -z "${bin:-}" ]; then
bin=$dir/../qbe
fi
if [ -z "${binref:-}" ]; then
binref=${bin}.ref
fi
tmp=/tmp/qbe.zzzz
drv=$tmp.c
asm=$tmp.s
asmref=$tmp.ref.s
exe=$tmp.exe
out=$tmp.out
qemu_not_needed() {
"$@"
}
cc=
find_cc_and_qemu() {
if [ -n "$cc" ]; then
return
fi
target="$1"
candidate_cc="$2"
if $candidate_cc -v >/dev/null 2>&1; then
cc=$candidate_cc
echo "cc: $cc"
if [ "$target" = "$(uname -m)" ]
then
qemu=qemu_not_needed
echo "qemu: not needed, testing native architecture"
else
qemu="$3"
if $qemu -version >/dev/null 2>&1
then
sysroot=$($candidate_cc -print-sysroot)
if [ -n "$sysroot" ]; then
qemu="$qemu -L $sysroot"
fi
echo "qemu: $qemu"
elif $qemu --version >/dev/null 2>&1
then
# wine
:
else
qemu=
echo "qemu: not found"
fi
fi
echo
fi
}
init() {
case "$TARGET" in
arm64)
for p in aarch64-linux-musl aarch64-linux-gnu
do
find_cc_and_qemu aarch64 "$p-gcc -no-pie -static" "qemu-aarch64"
done
if test -z "$cc" -o -z "$qemu"
then
echo "Cannot find arm64 compiler or qemu."
exit 77
fi
bin="$bin -t arm64"
;;
rv64)
for p in riscv64-linux-musl riscv64-linux-gnu
do
find_cc_and_qemu riscv64 "$p-gcc -no-pie -static" "qemu-riscv64"
done
if test -z "$cc" -o -z "$qemu"
then
echo "Cannot find riscv64 compiler or qemu."
exit 77
fi
bin="$bin -t rv64"
;;
x86_64)
for p in x86_64-linux-musl x86_64-linux-gnu
do
find_cc_and_qemu x86_64 "$p-gcc -no-pie -static" "qemu-x86_64"
done
if test -z "$cc" -o -z "$qemu"
then
echo "Cannot find x86_64 compiler or qemu."
exit 77
fi
bin="$bin -t amd64_sysv"
;;
amd64_win)
for p in x86_64-w64-mingw32
do
find_cc_and_qemu x86_64-w64 "$p-gcc -static" "wine"
done
if test -z "$cc"
then
echo "Cannot find windows compiler or wine."
exit 1
fi
export WINEDEBUG=-all
bin="$bin -t amd64_win"
;;
"")
case `uname` in
*Darwin*)
cc="cc"
;;
*OpenBSD*)
cc="cc -nopie -lpthread"
;;
*FreeBSD*)
cc="cc -lpthread"
;;
*)
cc="${CC:-cc}"
ccpost="-lpthread"
;;
esac
TARGET=`$bin -t?`
;;
*)
echo "Unknown target '$TARGET'."
exit 77
;;
esac
}
cleanup() {
rm -f $drv $asm $exe $out
}
extract() {
WHAT="$1"
FILE="$2"
awk "
/^# >>> $WHAT/ {
p = 1
next
}
/^# <<</ {
p = 0
}
p
" $FILE \
| sed -e 's/# //' \
| sed -e 's/#$//'
}
once() {
t="$1"
if ! test -f $t
then
echo "invalid test file $t" >&2
exit 1
fi
if
sed -e 1q $t |
grep "skip.* $TARGET\( .*\)\?$" \
>/dev/null
then
return 0
fi
printf "%-45s" "$(basename $t)..."
if ! $bin -o $asm $t
then
echo "[qbe fail]"
return 1
fi
if test -x $binref
then
$binref -o $asmref $t 2>/dev/null
fi
extract driver $t > $drv
extract output $t > $out
if test -s $drv
then
src="$drv $asm"
else
src="$asm"
fi
if ! $cc -g -o $exe $src $ccpost
then
echo "[cc fail]"
return 1
fi
if test -s $out
then
$qemu $exe a b c | tr -d '\r' | diff -u - $out
ret=$?
reason="output"
else
$qemu $exe a b c
ret=$?
reason="returned $ret"
fi
if test $ret -ne 0
then
echo "[$reason fail]"
return 1
fi
echo "[ok]"
if test -f $asmref && ! cmp -s $asm $asmref
then
loc0=`wc -l $asm | cut -d' ' -f1`
loc1=`wc -l $asmref | cut -d' ' -f1`
printf " asm diff: %+d\n" $(($loc0 - $loc1))
return 0
fi
}
#trap cleanup TERM QUIT
init
if test -z "$1"
then
echo "usage: tools/test.sh {all, SSAFILE}" 2>&1
exit 1
fi
case "$1" in
"all")
fail=0
count=0
for t in $dir/../test/[!_]*.ssa
do
once $t
fail=`expr $fail + $?`
count=`expr $count + 1`
done
if test $fail -ge 1
then
echo
echo "$fail of $count tests failed!"
else
echo
echo "All is fine!"
fi
exit $fail
;;
*)
once $1
exit $?
;;
esac