kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

regen-rv32.sh (4418B)


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