regen-rv64.sh (4285B)
1 #!/usr/bin/env bash 2 # test/asm/regen-rv64.sh — regenerate the rv64_* smoke goldens from 3 # clang + llvm-objdump targeting riscv64-linux-gnu. Maintainer aid: NOT 4 # run by CI. Commit the refreshed goldens alongside the case changes. 5 # 6 # Usage: 7 # ./regen-rv64.sh regenerate every rv64_* case 8 # ./regen-rv64.sh <name> regenerate just one rv64_* case (substring) 9 # 10 # Detects clang + llvm-objdump (or riscv64-linux-gnu-objdump). Exits 0 11 # with a SKIP-style message if either is missing — the script is intended 12 # to support cross-toolchain regen on machines that don't have a full 13 # riscv64 cross install. 14 15 set -u 16 17 ROOT="$(cd "$(dirname "$0")/../.." && pwd)" 18 TEST_DIR="$ROOT/test/asm" 19 FILTER="${1:-}" 20 21 # Use the no-C ISA so encode goldens match the existing 4-byte-per-insn 22 # fixtures. Per-fixture .targets sidecars carry the canonical bytes the 23 # in-tree corpus has agreed to (asm-runner emits raw 32-bit encodings; 24 # turning on the C extension would shrink some forms to 16 bits). 25 CLANG_TARGET="--target=riscv64-linux-gnu -march=rv64imafd -mabi=lp64d" 26 OBJDUMP="$(command -v llvm-objdump 2>/dev/null || command -v riscv64-linux-gnu-objdump 2>/dev/null || true)" 27 CLANG="$(command -v clang 2>/dev/null || true)" 28 29 if [ -z "$OBJDUMP" ] || [ -z "$CLANG" ]; then 30 printf 'regen-rv64.sh: SKIP — need clang and llvm-objdump (or riscv64-linux-gnu-objdump) on PATH\n' >&2 31 exit 0 32 fi 33 34 tmp="$(mktemp -d)" 35 trap 'rm -rf "$tmp"' EXIT 36 37 regen_encode() { 38 local src="$1" name out_obj out_hex 39 name="$(basename "$src" .s)" 40 case "$name" in rv64_*) ;; *) return 0 ;; esac 41 [ -n "$FILTER" ] && [[ "$name" != *"$FILTER"* ]] && return 0 42 out_obj="$tmp/$name.o" 43 out_hex="$TEST_DIR/encode/$name.expected.hex" 44 $CLANG $CLANG_TARGET -c "$src" -o "$out_obj" 45 "$OBJDUMP" --full-contents -j .text "$out_obj" \ 46 | awk '/^Contents of section/ {next} /^$/ {next} 47 { for (i=2; i<=5; i++) if ($i ~ /^[0-9a-f]+$/) printf "%s", $i; printf "\n" }' \ 48 | tr -d '\n' \ 49 | { cat; printf '\n'; } >"$out_hex" 50 printf ' regen encode/%s\n' "$name" 51 } 52 53 regen_decode() { 54 local hexfile="$1" name out_txt raw scratch 55 name="$(basename "$hexfile" .hex)" 56 case "$name" in rv64_*) ;; *) return 0 ;; esac 57 [ -n "$FILTER" ] && [[ "$name" != *"$FILTER"* ]] && return 0 58 out_txt="$TEST_DIR/decode/$name.expected.txt" 59 raw="$tmp/$name.bin" 60 scratch="$tmp/$name.decode.txt" 61 xxd -r -p "$hexfile" "$raw" 62 if ! "$OBJDUMP" -b binary -m riscv -M no-aliases -D "$raw" >"$scratch" 2>"$tmp/$name.decode.err"; then 63 return 1 64 fi 65 awk '/^[ ]+[0-9a-f]+:/ { 66 sub(/:/, "", $1); 67 addr = $1; 68 mnem = $3; 69 ops = ""; 70 for (i=4; i<=NF; i++) ops = (ops=="" ? $i : ops " " $i); 71 printf "%s:\t%s\t%s\n", addr, mnem, ops; 72 }' "$scratch" >"$out_txt" 73 printf ' regen decode/%s\n' "$name" 74 } 75 76 regen_listing() { 77 local bin="$1" name out_lst scratch 78 name="$(basename "$bin" .in.bin)" 79 case "$name" in rv64_*) ;; *) return 0 ;; esac 80 [ -n "$FILTER" ] && [[ "$name" != *"$FILTER"* ]] && return 0 81 out_lst="$TEST_DIR/listing/$name.expected.lst" 82 scratch="$tmp/$name.listing.txt" 83 if ! "$OBJDUMP" -d -m riscv "$bin" >"$scratch" 2>"$tmp/$name.listing.err"; then 84 return 1 85 fi 86 awk '/^Disassembly of section/ || /^[0-9a-f]+ </ || /^[ ]+[0-9a-f]+:/ || /^$/' \ 87 "$scratch" >"$out_lst" 88 printf ' regen listing/%s\n' "$name" 89 } 90 91 printf 'Regenerating rv64 goldens...\n' 92 # encode/ is portable across llvm-objdump versions (uses real .o input). 93 for src in "$TEST_DIR"/encode/*.s; do [ -e "$src" ] && regen_encode "$src"; done 94 # decode/ and listing/ pass raw bytes through `-b binary -m riscv` which 95 # some llvm-objdump builds (notably the macOS Homebrew build) do not 96 # support. Soft-fail per case so encode regen still completes. 97 for src in "$TEST_DIR"/decode/*.hex; do 98 [ -e "$src" ] || continue 99 regen_decode "$src" || printf ' skip decode/%s (objdump rejected raw binary)\n' "$(basename "$src" .hex)" 100 done 101 for src in "$TEST_DIR"/listing/*.in.bin; do 102 [ -e "$src" ] || continue 103 regen_listing "$src" || printf ' skip listing/%s (objdump rejected raw binary)\n' "$(basename "$src" .in.bin)" 104 done 105 printf 'Done.\n'