|
|
#!/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 "==========================================" |