// Copyright (c) 2026 Petr BalvĂ­n (https://petrbalvin.org) // SPDX-License-Identifier: BSD-3-Clause package verify import ( "os" "os/exec" "testing" ) // goobjVectorMainSrc is the Go side of the vector regression. The kernel // computes a signed byte checksum through the RVV load/store and arithmetic // families; main derives the same value in Go and panics on any divergence // before printing the deterministic line the baseline and the gasm-linked // binaries must agree on. const goobjVectorMainSrc = `package main func checksum(buf []byte, seed int64) int64 func main() { buf := []byte("gasm link parity vector kernel!") total := int64(0) for _, b := range buf { total += int64(int8(b)) } want := total*0x0101010101010101 ^ 0x5eed if got := checksum(buf, 0x5eed); got != want { panic("checksum") } println("ok", checksum(buf, 0x5eed)) } ` // TestGOOBJLinkRVVKernel proves the riscv64 vector families merged into the // encoder corpus are proven end to end: the kernel assembles by gasm into a // GOOBJ object, substitutes byte-wise into a real go build archive, relinks // with cmd/link and the linked binary computes the same checksum as the // toolchain-built one under qemu-user. The reduction reads the live vl, so // the checksum holds for any hardware VLEN. func TestGOOBJLinkRVVKernel(t *testing.T) { if testing.Short() { t.Skip("builds the gasm binary and links Go programs") } if os.Getenv("GASM_LINK_PARITY") == "" { t.Skip("deliberate verification: set GASM_LINK_PARITY=1 (just link-parity)") } goBin, err := exec.LookPath("go") if err != nil { t.Skip("no Go toolchain available") } gasmBin := buildLinkParityGasm(t, goBin) t.Run("riscv64", func(t *testing.T) { goobjLinkKernel(t, goBin, gasmBin, "riscv64", "linkvec_riscv64.s", goobjVectorMainSrc) }) }