You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
4.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#!/bin/bash
PROJECT_ROOT=$(cd "$(dirname "$0")/.." ; pwd)
COMPILER="$PROJECT_ROOT/build/bin/compiler"
TEST_CASE_DIR="$PROJECT_ROOT/test/test_case"
TEST_RESULT_DIR="$PROJECT_ROOT/test/test_result/mir"
SYLIB_C="$PROJECT_ROOT/sylib/sylib.c"
SYLIB_O="/tmp/sylib.o"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
if [ ! -x "$COMPILER" ]; then
echo "错误:编译器不存在或不可执行: $COMPILER"
exit 1
fi
# 编译 sylib 运行时库
echo "编译运行时库..."
if [ ! -f "$SYLIB_O" ]; then
riscv64-linux-gnu-gcc -c "$SYLIB_C" -o "$SYLIB_O" 2>/dev/null
if [ $? -ne 0 ]; then
echo "警告:无法编译 sylib.c部分测试可能链接失败"
fi
fi
echo ""
mkdir -p "$TEST_RESULT_DIR"
echo "=========================================="
echo "RISC-V 后端测试"
echo "=========================================="
echo ""
# 收集测试用例
mapfile -t test_files < <(find "$TEST_CASE_DIR" -name "*.sy" -not -path '*/*performance*/*' | sort)
total=${#test_files[@]}
pass_gen=0
fail_gen=0
pass_run=0
fail_run=0
timeout_cnt=0
echo "=== 阶段1汇编生成 ==="
echo ""
for test_file in "${test_files[@]}"; do
relative_path=$(realpath --relative-to="$TEST_CASE_DIR" "$test_file")
output_file="$TEST_RESULT_DIR/${relative_path%.sy}.s"
mkdir -p "$(dirname "$output_file")"
"$COMPILER" --emit-asm "$test_file" 2>/dev/null > "$output_file"
if [ $? -eq 0 ] && [ -s "$output_file" ]; then
echo -e " ${GREEN}${NC} $relative_path"
((pass_gen++))
else
echo -e " ${RED}${NC} $relative_path"
((fail_gen++))
fi
done
echo ""
echo "--- 汇编生成: 通过 $pass_gen / 失败 $fail_gen / 总计 $total ---"
echo ""
for test_file in "${test_files[@]}"; do
relative_path=$(realpath --relative-to="$TEST_CASE_DIR" "$test_file")
stem="${relative_path%.sy}"
asm_file="$TEST_RESULT_DIR/${stem}.s"
exe_file="$TEST_RESULT_DIR/${stem}"
expected_file="${test_file%.sy}.out"
if [ ! -s "$asm_file" ]; then
echo -e " ${YELLOW}${NC} $relative_path (跳过)"
continue
fi
# 链接
if [ -f "$SYLIB_O" ]; then
riscv64-linux-gnu-gcc -static "$asm_file" "$SYLIB_O" -o "$exe_file" -no-pie 2>/dev/null
else
riscv64-linux-gnu-gcc -static "$asm_file" -o "$exe_file" -no-pie 2>/dev/null
fi
if [ $? -ne 0 ]; then
echo -e " ${RED}${NC} $relative_path (链接失败)"
((fail_run++))
continue
fi
# 运行程序
input_file="${test_file%.sy}.in"
tmp_out=$(mktemp)
if [ -f "$input_file" ]; then
timeout 10 qemu-riscv64 "$exe_file" < "$input_file" > "$tmp_out" 2>&1
else
timeout 10 qemu-riscv64 "$exe_file" > "$tmp_out" 2>&1
fi
exit_code=$?
if [ $exit_code -eq 124 ]; then
echo -e " ${YELLOW}${NC} $relative_path (超时)"
((timeout_cnt++))
rm -f "$tmp_out"
continue
fi
program_output=$(cat "$tmp_out" | tr -d '\n' | sed 's/[[:space:]]*$//')
rm -f "$tmp_out"
if [ -f "$expected_file" ]; then
expected=$(cat "$expected_file" | tr -d '\n' | sed 's/[[:space:]]*$//')
if [[ "$expected" =~ ^[0-9]+$ ]] && [ "$expected" -ge 0 ] && [ "$expected" -le 255 ] && [ -z "$program_output" ]; then
# 期望退出码(且没有输出)
if [ $exit_code -eq "$expected" ] 2>/dev/null; then
echo -e " ${GREEN}${NC} $relative_path (退出码: $exit_code)"
((pass_run++))
else
echo -e " ${RED}${NC} $relative_path (退出码: 期望 $expected, 实际 $exit_code)"
((fail_run++))
fi
else
# 期望输出内容
if [ "$program_output" = "$expected" ]; then
echo -e " ${GREEN}${NC} $relative_path (输出匹配)"
((pass_run++))
else
echo -e " ${RED}${NC} $relative_path (输出不匹配: 期望 '$expected', 实际 '$program_output')"
((fail_run++))
fi
fi
else
# 没有期望文件
echo -e " ${GREEN}${NC} $relative_path (退出码: $exit_code, 输出: '$program_output')"
((pass_run++))
fi
done
echo ""
echo "--- 运行验证: 通过 $pass_run / 失败 $fail_run / 超时 $timeout_cnt ---"
echo ""
echo "=========================================="
echo "测试完成"
echo "汇编生成: 通过 $pass_gen / 失败 $fail_gen"
echo "运行验证: 通过 $pass_run / 失败 $fail_run / 超时 $timeout_cnt"
echo "=========================================="