diff --git a/asm/assembler_fuzz_test.go b/asm/assembler_fuzz_test.go
index 8fe74e8..a159477 100644
--- a/asm/assembler_fuzz_test.go
+++ b/asm/assembler_fuzz_test.go
@@ -37,6 +37,22 @@ func corpusSeeds(f *testing.F) {
}
}
+// archCorpusSeeds seeds a target with every assembly file of its architecture
+// seed directory, testdata/seeds/
. The files hold the target-specific
+// corpus: the instruction families GOROOT's own assembler corpus exercises for
+// the architecture, minimalised, plus the boundary shapes the encoder's range
+// gates live on. They are committed assembly, so `gasm fmt` and `gasm lint`
+// gate them the way they gate every other .s file. A plain `go test` run
+// replays each one as a regression case.
+func archCorpusSeeds(f *testing.F, dir string) {
+ files, _ := filepath.Glob(filepath.Join("testdata", "seeds", dir, "*.s"))
+ for _, path := range files {
+ if b, err := os.ReadFile(path); err == nil {
+ f.Add(string(b))
+ }
+ }
+}
+
// fuzzAssemble is the whole fuzz body, shared by every target and one line
// apart between them: parse with macro and include expansion, assemble
// through the target's file-level entry, and hold the invariants. The
@@ -179,3 +195,86 @@ func FuzzAssembleARM64(f *testing.F) {
fuzzAssemble(t, "fuzz_arm64.s", src, AssembleFileARM64)
})
}
+
+// FuzzAssembleRISCV64 hammers the same pipeline for the fixed riscv64 target.
+// The seed corpus lives in testdata/seeds/riscv64: the instruction families
+// GOROOT's riscv64 assembler corpus exercises (the immediate-range ladder of
+// the I-type arithmetic, the load/store and branch offsets, the atomics, the
+// FP conversions and the fused multiply-adds), the RVV configuration and
+// arithmetic classes with their mask forms, the RVC-compressible shapes, the
+// CSR instructions and the Zbb/Zba/Zbs bit-manipulation set, plus one file per
+// rejection shape so each diagnostic path replays on its own.
+func FuzzAssembleRISCV64(f *testing.F) {
+ corpusSeeds(f)
+ archCorpusSeeds(f, "riscv64")
+ // Minimal seeds for the shared file-level surface, spelled the riscv64
+ // way: the guard classes, the macro and include expansion, and the data
+ // section with its symbol-valued fields.
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tRET\n")
+ f.Add("TEXT ·f(SB), $16-8\n\tMOV x+0(FP), X10\n\tMOV X10, ret+8(FP)\n\tRET\n")
+ f.Add("TEXT ·f(SB), $256-0\n\tCALL ·helper(SB)\n\tRET\nTEXT ·helper(SB), NOSPLIT, $0\n\tRET\n")
+ f.Add("#define L(n) ADDI $n, X10, X10\nTEXT ·f(SB), NOSPLIT, $0\n\tL(7)\n\tRET\n")
+ f.Add("#include \"textflag.h\"\nTEXT ·f(SB), NOSPLIT, $0\n\tRET\n")
+ f.Add("#include \"fuzzdefs.h\"\nTEXT ·f(SB), $16-8\n\tMOV KONST, X10\n\tMOV ARG(x), X11\n\tRET\n")
+ f.Add("DATA d<>+0(SB)/8, $0xf4f8fcff\nDATA d<>+4(SB)/4, $1\nGLOBL d<>(SB), RODATA, $8\n" +
+ "TEXT ·f(SB), NOSPLIT, $0\n\tMOV d<>(SB), X10\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tPCALIGN $16\n\tADD X11, X10, X10\n\tPCALIGN $2048\n\tRET\n")
+ f.Add("TEXT ·f(SB), $0\n\tPCDATA $0, $1\n\tFUNCDATA $0, ·meta(SB)\n\tRET\n")
+ // Shapes that must be rejected: each pins a diagnostic path the accepted
+ // seeds never reach.
+ f.Add("TEXT ·f(SB), $0\n\tBOGUSINSTR X10, X11\n\tRET\n")
+ f.Add("GLOBL d(SB), $-8\n")
+ f.Add("GLOBL d(SB), $0x4000001\n")
+ f.Add("DATA d+0(SB)/9, $1\nGLOBL d(SB), $8\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tADD X11, X32\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tADDI $2048, X5, X6\n\tADD X11, X40, X6\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tCSRRW $0x1000, X5, X6\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tSLLI $64, X5, X6\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVLE8V (X10), V32\n\tRET\n")
+ f.Add("#define A A\nA\n")
+
+ f.Fuzz(func(t *testing.T, src string) {
+ fuzzAssemble(t, "fuzz_riscv64.s", src, AssembleFileRISCV)
+ })
+}
+
+// FuzzAssembleLOONG64 hammers the same pipeline for the fixed loong64 target.
+// The seed corpus lives in testdata/seeds/loong64: the LSX and LASX register
+// banks with their immediate forms and range gates (the si5 compares, the
+// biased shifts, the VSHUF4I/VPERMI/VEXTRINS immediates), the ll/sc offset
+// ladder with its three encoding spans, the pointer loads and stores, the
+// atomics with their dbar forms, the branches, the bit-field instructions and
+// the register-class moves, plus one file per rejection shape.
+func FuzzAssembleLOONG64(f *testing.F) {
+ corpusSeeds(f)
+ archCorpusSeeds(f, "loong64")
+ // Minimal seeds for the shared file-level surface, spelled the loong64
+ // way.
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tRET\n")
+ f.Add("TEXT ·f(SB), $16-8\n\tMOVV x+0(FP), R4\n\tMOVV R4, ret+8(FP)\n\tRET\n")
+ f.Add("TEXT ·f(SB), $256-0\n\tCALL ·helper(SB)\n\tRET\nTEXT ·helper(SB), NOSPLIT, $0\n\tRET\n")
+ f.Add("#define L(n) ADDV $n, R4, R4\nTEXT ·f(SB), NOSPLIT, $0\n\tL(7)\n\tRET\n")
+ f.Add("#include \"textflag.h\"\nTEXT ·f(SB), NOSPLIT, $0\n\tRET\n")
+ f.Add("#include \"fuzzdefs.h\"\nTEXT ·f(SB), $16-8\n\tMOVV KONST, R4\n\tMOVV ARG(x), R5\n\tRET\n")
+ f.Add("DATA d<>+0(SB)/8, $0xf4f8fcff\nDATA d<>+4(SB)/4, $1\nGLOBL d<>(SB), RODATA, $8\n" +
+ "TEXT ·f(SB), NOSPLIT, $0\n\tMOVV d<>(SB), R4\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tPCALIGN $16\n\tADDV R5, R4, R4\n\tPCALIGN $2048\n\tRET\n")
+ f.Add("TEXT ·f(SB), $0\n\tPCDATA $0, $1\n\tFUNCDATA $0, ·meta(SB)\n\tRET\n")
+ // Shapes that must be rejected: each pins a diagnostic path the accepted
+ // seeds never reach.
+ f.Add("TEXT ·f(SB), $0\n\tBOGUSINSTR R4, R5\n\tRET\n")
+ f.Add("GLOBL d(SB), $-8\n")
+ f.Add("GLOBL d(SB), $0x4000001\n")
+ f.Add("DATA d+0(SB)/9, $1\nGLOBL d(SB), $8\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tADD R5, R32\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tBEQZ V0, L1\nL1:\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVADDV V1, V2, X3\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVSEQV $32, V2, V3\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tVSHUF4IV $16, V2, V1\n\tRET\n")
+ f.Add("TEXT ·f(SB), NOSPLIT, $0\n\tBSTRPICKV $64, R4, $5, R6\n\tRET\n")
+ f.Add("#define A A\nA\n")
+
+ f.Fuzz(func(t *testing.T, src string) {
+ fuzzAssemble(t, "fuzz_loong64.s", src, AssembleFileLOONG64)
+ })
+}
diff --git a/asm/testdata/seeds/loong64/llsc-offsets.s b/asm/testdata/seeds/loong64/llsc-offsets.s
new file mode 100644
index 0000000..30e2f2a
--- /dev/null
+++ b/asm/testdata/seeds/loong64/llsc-offsets.s
@@ -0,0 +1,84 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleLOONG64: the ll/sc and pointer load/store
+// offset ladder, the three spans the encoder classifies by (a signed 16-bit
+// offset alone, a 32-bit one split through addu16i.d into R30, a wider one
+// materialised in full), the acquire/release pair, sc.q and the atomics with
+// their dbar forms.
+
+#include "textflag.h"
+
+TEXT ·llscNear(SB), NOSPLIT, $0
+ LL (R12), R13
+ LL 0(R12), R13
+ LL 4(R12), R13
+ LLW 8(R12), R13
+ LLW -4(R12), R13
+ LLV 8(R14), R15
+ LLV -8(R14), R15
+ SC R16, (R17)
+ SC R16, 0(R17)
+ SCW R16, 4(R17)
+ SCV R18,-8(R19)
+ RET
+
+TEXT ·llscSpans(SB), NOSPLIT, $0
+ LL 1020(R12), R13
+ LL 1024(R12), R13
+ LL -1024(R12), R13
+ LLW 32760(R12), R13
+ LLW 32764(R12), R13
+ LLW 32768(R12), R13
+ LLW -32768(R12), R13
+ LLV 65532(R14), R15
+ LLV 65536(R14), R15
+ LLV 131068(R14), R15
+ LLW 1048572(R12), R13
+ LLV 2147483644(R14), R15
+ LLV -2147483648(R14), R15
+ SC R16, 1020(R17)
+ SCW R16, 32764(R17)
+ SCV R18, 65532(R19)
+ SCV R18, 65536(R19)
+ RET
+
+TEXT ·ptrForms(SB), NOSPLIT, $0
+ MOVWP R16, (R17)
+ MOVWP R16, 8(R17)
+ MOVVP R18, (R19)
+ MOVVP R18,-8(R19)
+ RET
+
+TEXT ·acqRel(SB), NOSPLIT, $0
+ LLACQW (R5), R4
+ LLACQV (R5), R4
+ SCRELW R4, (R6)
+ SCRELV R4, (R6)
+ SCQ R4, R5, (R6)
+ RET
+
+TEXT ·atomics(SB), NOSPLIT, $0
+ AMSWAPB R14, (R13), R12
+ AMSWAPH R14, (R13), R12
+ AMSWAPW R14, (R13), R12
+ AMSWAPV R14, (R13), R12
+ AMCASB R14, (R13), R12
+ AMCASDBV R14, (R13), R12
+ AMADDW R14, (R13), R12
+ AMADDV R14, (R13), R12
+ AMANDW R6, (R5), R4
+ AMORW R0, (R5), R4
+ AMXORV R14, (R13), R12
+ AMMAXW R14, (R13), R12
+ AMMINV R14, (R13), R12
+ AMMAXWU R14, (R13), R12
+ AMMINVU R14, (R13), R12
+ AMADDDBW R14, (R13), R12
+ AMADDDBV R14, (R13), R12
+ AMANDDBW R6, (R5), R4
+ AMORDBV R14, (R13), R12
+ AMXORDBW R14, (R13), R12
+ AMMAXDBWU R14, (R13), R12
+ AMMINDBVU R14, (R13), R12
+ RET
diff --git a/asm/testdata/seeds/loong64/lsx-lasx.s b/asm/testdata/seeds/loong64/lsx-lasx.s
new file mode 100644
index 0000000..6a01da4
--- /dev/null
+++ b/asm/testdata/seeds/loong64/lsx-lasx.s
@@ -0,0 +1,212 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleLOONG64: the LSX (V) and LASX (X) register
+// banks, the family GOROOT's loong64 assembler corpus exercises
+// (cmd/asm/internal/asm/testdata/loong64enc*.s). Every immediate window sits
+// on an encoder gate: the si5 compares, the biased shifts, the ui8 logic
+// immediates and the element moves.
+
+#include "textflag.h"
+
+TEXT ·vecArith(SB), NOSPLIT, $0
+ VADDV V1, V2, V3
+ VADDW V1, V2, V3
+ VADDD V1, V2, V3
+ VADDQ V1, V2, V3
+ VSUBV V1, V2, V3
+ VSSUBV V1, V2, V3
+ VSADDVU V1, V2, V3
+ VMULV V1, V2, V3
+ VMUHVU V1, V2, V3
+ VDIVB V1, V2, V3
+ VMODH V1, V2, V3
+ VANDV V1, V2, V3
+ VORV V1, V2, V3
+ VXORV V1, V2, V3
+ VNORV V1, V2, V3
+ VANDNV V1, V2, V3
+ VSEQB V1, V2, V3
+ VSLTW V1, V2, V3
+ VSLTBU V1, V2, V3
+ VSLLB V1, V2, V3
+ VSRAH V1, V2, V3
+ VROTRV V1, V2, V3
+ VILVLW V1, V2, V3
+ VILVHV V1, V2, V3
+ VBITCLRW V1, V2, V3
+ VBITSETB V1, V2, V3
+ VBITREVW V1, V2, V3
+ VADDWEVHB V1, V2, V3
+ VSUBWODVW V1, V2, V3
+ VMULWEVQV V1, V2, V3
+ VMADDWODQVU V1, V2, V3
+ VSHUFV V1, V2, V3
+ RET
+
+TEXT ·vecArithX(SB), NOSPLIT, $0
+ XVADDV X1, X2, X3
+ XVADDW X1, X2, X3
+ XVADDD X1, X2, X3
+ XVADDQ X1, X2, X3
+ XVSUBV X1, X2, X3
+ XVSSUBVU X1, X2, X3
+ XVMULV X1, X2, X3
+ XVMUHVU X1, X2, X3
+ XVDIVB X1, X2, X3
+ XVANDV X1, X2, X3
+ XVNORV X1, X2, X3
+ XVSEQB X1, X2, X3
+ XVSLTW X1, X2, X3
+ XVSLLB X1, X2, X3
+ XVSRAB X1, X2, X3
+ XVROTRW X1, X2, X3
+ XVILVLB X1, X2, X3
+ XVBITCLRV X1, X2, X3
+ XVADDWEVHB X1, X2, X3
+ XVMULWODWHU X1, X2, X3
+ XVMADDWEVQVUV X1, X2, X3
+ XVSHUFV X1, X2, X3
+ RET
+
+TEXT ·vecImm(SB), NOSPLIT, $0
+ VANDB $0, V2, V3
+ VANDB $255, V2, V3
+ VORB $128, V2, V3
+ VXORB $255, V2, V3
+ VNORB $1, V2, V3
+ VSEQB $-16, V2, V3
+ VSEQB $15, V2, V3
+ VSEQH $0, V2, V3
+ VSEQW $-1, V2, V3
+ VSEQV $15, V2, V3
+ VSEQV $-15, V2, V3
+ VSLTB $-16, V2, V3
+ VSLTBU $0, V2, V3
+ VSLTBU $31, V2, V3
+ VADDBU $0, V2, V3
+ VADDVU $31, V2, V3
+ VSUBBU $31, V2, V3
+ VSLLB $0, V2, V3
+ VSLLB $7, V2, V3
+ VSLLH $15, V2, V3
+ VSLLW $31, V2, V3
+ VSLLV $63, V2, V3
+ VSRLB $7, V2, V3
+ VSRAB $7, V2, V3
+ VSRAH $15, V2, V3
+ VSRAW $31, V2, V3
+ VSRAV $63, V2, V3
+ VROTRB $7, V2, V3
+ VROTRH $15, V2, V3
+ VROTRW $31, V2, V3
+ VROTRV $63, V2, V3
+ VBITCLRB $7, V2, V3
+ VBITSETH $15, V2, V3
+ VBITREVW $31, V2, V3
+ VBITREVV $63, V2, V3
+ XVANDB $0, X2, X3
+ XVANDB $255, X2, X3
+ XVSEQB $-16, X2, X3
+ XVSEQB $15, X2, X3
+ XVSEQV $15, X2, X3
+ XVADDVU $31, X2, X3
+ XVSLLB $0, X2, X3
+ XVSLLB $7, X2, X3
+ XVSLLV $63, X2, X3
+ XVSRAB $7, X2, X3
+ XVROTRV $63, X2, X3
+ XVBITCLRB $7, X2, X3
+ XVBITSETV $63, X2, X3
+ RET
+
+TEXT ·vecUnary(SB), NOSPLIT, $0
+ VPCNTB V1, V2
+ VPCNTH V1, V2
+ VPCNTW V1, V2
+ VPCNTV V1, V2
+ VNEGB V1, V2
+ VNEGW V1, V2
+ VNEGV V1, V2
+ VFCLASSF V1, V2
+ VFCLASSD V1, V2
+ VFSQRTF V1, V2
+ VFSQRTD V1, V2
+ VFRECIPD V1, V2
+ VFRSQRTF V1, V2
+ VFRINTF V1, V2
+ VFRINTRMD V1, V2
+ VFRINTRNEF V1, V2
+ VFRINTRZD V1, V2
+ VFRINTRPF V1, V2
+ XVPCNTB X1, X2
+ XVPCNTV X1, X2
+ XVNEGH X1, X2
+ XVFSQRTD X1, X2
+ XVFRECIPF X1, X2
+ XVFRINTRZD X1, X2
+ RET
+
+TEXT ·vecCond(SB), NOSPLIT, $0
+ VSETNEV V1, FCC0
+ VSETEQV V1, FCC1
+ VSETANYEQB V1, FCC2
+ VSETANYEQH V2, FCC3
+ VSETANYEQW V1, FCC4
+ VSETANYEQV V2, FCC5
+ VSETALLNEB V1, FCC6
+ VSETALLNEH V2, FCC7
+ VSETALLNEW V1, FCC0
+ VSETALLNEV V0, FCC1
+ XVSETNEV X1, FCC0
+ XVSETEQV X2, FCC1
+ XVSETANYEQV X1, FCC2
+ XVSETALLNEB X2, FCC3
+ RET
+
+TEXT ·vecShuffle4(SB), NOSPLIT, $0
+ VSHUFB V0, V1, V2, V3
+ XVSHUFB X0, X1, X2, X3
+ RET
+
+// The VMOVQ/XVMOVQ move family: the load, the indexed load, the store, the
+// replicated load, the whole-register move, the GPR broadcast, the element
+// extract, the element insert and the element broadcast.
+TEXT ·vecMove(SB), NOSPLIT, $0
+ VMOVQ 8(R4), V2
+ VMOVQ (R4)(R5), V2
+ VMOVQ V2, 8(R4)
+ VMOVQ V2, (R4)(R5)
+ VMOVQ 2(R4), V1.H8
+ VMOVQ -6(R4), V1.H8
+ VMOVQ -12(R4), V2.W4
+ VMOVQ V1, V2
+ VMOVQ R4, V1.B16
+ VMOVQ R4, V1.H8
+ VMOVQ R4, V1.W4
+ VMOVQ R4, V1.V2
+ VMOVQ V1.B[3], R5
+ VMOVQ V1.H[7], R5
+ VMOVQ V1.W[3], R5
+ VMOVQ V1.V[1], R5
+ VMOVQ R5, V1.B[3]
+ VMOVQ R5, V1.H[7]
+ VMOVQ R5, V1.W[3]
+ VMOVQ R5, V1.V[1]
+ VMOVQ V1.B[3], V9.B16
+ VMOVQ V2.H[2], V8.H8
+ VMOVQ V3.W[1], V7.W4
+ VMOVQ V4.V[0], V6.V2
+ XVMOVQ X1, X2
+ XVMOVQ X0, X31.B32
+ XVMOVQ X1, X30.H16
+ XVMOVQ X2, X29.W8
+ XVMOVQ X3, X28.V4
+ XVMOVQ X3, X27.Q2
+ XVMOVQ X0, X31.W[7]
+ XVMOVQ X1, X29.W[0]
+ XVMOVQ X3, X28.V[3]
+ XVMOVQ X4, X27.V[0]
+ XVMOVQ X31.W[7], X0
+ XVMOVQ X28.V[3], X8
+ RET
diff --git a/asm/testdata/seeds/loong64/misc-branches.s b/asm/testdata/seeds/loong64/misc-branches.s
new file mode 100644
index 0000000..4500f0f
--- /dev/null
+++ b/asm/testdata/seeds/loong64/misc-branches.s
@@ -0,0 +1,121 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleLOONG64: the branches over their offset range,
+// the jumps, the bit-field pair at the msb/lsb boundaries, the ALSL shift
+// window, RDTIME, the system instructions, the constant materialisation
+// chain and the register-class moves.
+
+#include "textflag.h"
+
+TEXT ·branches(SB), NOSPLIT, $0
+ BEQ R4, R5, b1
+ BNE R4, R5, b2
+ BLT R4, R5, b1
+ BGE R4, R5, b2
+ BLTU R4, R5, b1
+ BGEU R4, R5, b2
+ BEQZ R6, b1
+ BNEZ R7, b2
+ BLTZ R8, b1
+ BGEZ R9, b2
+ BLEZ R10, b1
+ BGTZ R11, b2
+ BFPT b1
+ BFPF b2
+
+b1:
+ MOVV R1, R2
+
+b2:
+ MOVV R2, R1
+ BEQ R4, R5, b1
+ RET
+
+TEXT ·jumps(SB), NOSPLIT, $0
+ JMP j1
+ JAL (R30)
+ JIRL R0, R4, 8
+ JIRL R1, R5, 0
+ CALL runtime·morestack_noctxt(SB)
+
+j1:
+ JMP -3(PC)
+ RET
+
+TEXT ·bitfield(SB), NOSPLIT, $0
+ BSTRINSW $3, R4, $0, R5
+ BSTRINSV $7, R4, $0, R5
+ BSTRINSV $31, R6, $0, R7
+ BSTRINSV $63, R6, $32, R7
+ BSTRPICKW $3, R4, $0, R5
+ BSTRPICKV $6, R7, $0, R8
+ BSTRPICKV $63, R6, $32, R7
+ ALSLW $1, R4, R5, R6
+ ALSLW $4, R7, R8, R9
+ ALSLWU $3, R4, R5, R6
+ ALSLV $2, R8, R9, R10
+ ALSLV $3, R8, R9, R10
+ RET
+
+TEXT ·system(SB), NOSPLIT, $0
+ SYSCALL
+ DBAR
+ DBAR $0
+ BREAK $0
+ BREAK $32767
+ PRELD 0(R4), $0
+ PRELD 2047(R4), $31
+ RDTIMELW R7, R8
+ RDTIMEHW R7, R8
+ RDTIMED R20, R21
+ RET
+
+TEXT ·consts(SB), NOSPLIT, $0
+ LU12IW R4, $0x12345
+ LU12IW R5, $-524288
+ LU12IW R6, $1048575
+ LU32ID R7, $-524288
+ LU52ID $-4096, R8, R9
+ LU52ID $4095, R8, R9
+ PCALAU12I R10, $0x12345
+ PCADDU12I R11, $-524288
+ ADDV16 $65536, R11, R12
+ ADDV16 $-65536, R11, R12
+ MOVV $0x123456789ABCDEF0, R13
+ MOVV $-1, R14
+ RET
+
+TEXT ·regClasses(SB), NOSPLIT, $0
+ MOVV R4, F5
+ MOVV F6, R7
+ MOVW R8, F9
+ MOVW F10, R11
+ MOVV R12, FCC0
+ MOVV FCC1, R13
+ MOVV R14, FCSR0
+ MOVV FCSR3, R15
+ FSEL FCC0, F3, F4, F3
+ FSEL FCC1, F1, F2
+ RET
+
+TEXT ·memOffsets(SB), NOSPLIT, $0
+ MOVB 2047(R4), R5
+ MOVB -2048(R4), R5
+ MOVH 2047(R4), R5
+ MOVW 2047(R4), R5
+ MOVV 2047(R4), R5
+ MOVW 2048(R4), R5
+ MOVW -2048(R4), R5
+ MOVW 4095(R4), R5
+ MOVW -4096(R4), R5
+ MOVW 65536(R4), R5
+ MOVW $4(R4), R5
+ MOVV $4(R4), R5
+ MOVBU -1(R4), R5
+ MOVHU 2(R4), R5
+ MOVWU -3(R4), R5
+ MOVF 8(R4), F5
+ MOVD -8(R4), F5
+ MOVV (R4)(R5), R6
+ RET
diff --git a/asm/testdata/seeds/loong64/vshuf4iv.s b/asm/testdata/seeds/loong64/vshuf4iv.s
new file mode 100644
index 0000000..9f3fdda
--- /dev/null
+++ b/asm/testdata/seeds/loong64/vshuf4iv.s
@@ -0,0 +1,61 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleLOONG64: the shuffle/permute immediate family.
+// VSHUF4I.B/H/W take a ui8 packing two position nibbles; VSHUF4I.V is
+// range-gated to 0..15 although its field is ui8, the same gate the
+// toolchain keeps. VPERMI.W and the VEXTRINS pack an element index and an
+// insert/extract order in one ui8.
+
+#include "textflag.h"
+
+TEXT ·shuf4(SB), NOSPLIT, $0
+ VSHUF4IB $0, V2, V1
+ VSHUF4IB $16, V2, V1
+ VSHUF4IB $255, V2, V1
+ VSHUF4IH $0, V2, V1
+ VSHUF4IH $128, V2, V1
+ VSHUF4IH $255, V2, V1
+ VSHUF4IW $0, V2, V1
+ VSHUF4IW $96, V2, V1
+ VSHUF4IW $255, V2, V1
+ VSHUF4IV $0, V2, V1
+ VSHUF4IV $8, V2, V1
+ VSHUF4IV $15, V2, V1
+ RET
+
+TEXT ·shuf4X(SB), NOSPLIT, $0
+ XVSHUF4IB $0, X2, X1
+ XVSHUF4IB $255, X2, X1
+ XVSHUF4IH $255, X2, X1
+ XVSHUF4IW $255, X2, X1
+ XVSHUF4IV $0, X2, X1
+ XVSHUF4IV $15, X2, X1
+ RET
+
+TEXT ·permi(SB), NOSPLIT, $0
+ VPERMIW $0, V2, V1
+ VPERMIW $255, V2, V1
+ XVPERMIW $0, X2, X1
+ XVPERMIW $255, X2, X1
+ XVPERMIV $0, X2, X1
+ XVPERMIV $255, X2, X1
+ XVPERMIQ $0, X2, X1
+ XVPERMIQ $255, X2, X1
+ RET
+
+TEXT ·extrins(SB), NOSPLIT, $0
+ VEXTRINSB $0, V2, V1
+ VEXTRINSB $255, V2, V1
+ VEXTRINSH $0, V2, V1
+ VEXTRINSH $255, V2, V1
+ VEXTRINSW $0, V2, V1
+ VEXTRINSW $255, V2, V1
+ VEXTRINSV $0, V2, V1
+ VEXTRINSV $255, V2, V1
+ XVEXTRINSB $0, X2, X1
+ XVEXTRINSB $255, X2, X1
+ XVEXTRINSH $255, X2, X1
+ XVEXTRINSW $255, X2, X1
+ XVEXTRINSV $255, X2, X1
+ RET
diff --git a/asm/testdata/seeds/riscv64/csr.s b/asm/testdata/seeds/riscv64/csr.s
new file mode 100644
index 0000000..e75d65a
--- /dev/null
+++ b/asm/testdata/seeds/riscv64/csr.s
@@ -0,0 +1,35 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleRISCV64: the CSR instructions over the whole
+// 12-bit address range and the 5-bit immediate window of the CSRRWI family.
+
+#include "textflag.h"
+
+TEXT ·csrRegs(SB), NOSPLIT, $0
+ CSRRW $0x300, X5, X6
+ CSRRS $0x304, X7, X8
+ CSRRC $0x305, X9, X10
+ CSRRW $0, X5, X6
+ CSRRS $0xFFF, X7, X8
+ CSRRC $0x7FF, X9, X10
+ CSRRW $0x341, X0, X6
+ CSRRS $0x342, X0, X6
+ RET
+
+TEXT ·csrImm(SB), NOSPLIT, $0
+ CSRRWI $0x300, $0, X6
+ CSRRSI $0x304, $31, X8
+ CSRRCI $0x305, $1, X10
+ CSRRWI $0xFFF, $15, X6
+ CSRRSI $0, $31, X8
+ CSRRCI $0x7FF, $16, X10
+ RET
+
+TEXT ·csrNamed(SB), NOSPLIT, $0
+ CSRRS $0xC00, X0, X14
+ CSRRS $0xC01, X0, X15
+ CSRRS $0xC02, X0, X16
+ CSRRW $0x105, X5, X6
+ CSRRSI $0x106, $1, X7
+ RET
diff --git a/asm/testdata/seeds/riscv64/imm-ranges.s b/asm/testdata/seeds/riscv64/imm-ranges.s
new file mode 100644
index 0000000..cffa8ad
--- /dev/null
+++ b/asm/testdata/seeds/riscv64/imm-ranges.s
@@ -0,0 +1,106 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleRISCV64: the immediate-range ladder of the
+// I-type arithmetic and the U-type pair, the family GOROOT's riscv64
+// assembler corpus walks (cmd/asm/internal/asm/testdata/riscv64.s). Every
+// boundary sits on an encoder gate: the 12-bit signed window, the
+// one-instruction and two-instruction decompositions, the shamt widths and
+// the wide MOV immediate that goes through the literal pool.
+
+#include "textflag.h"
+
+TEXT ·immIType(SB), NOSPLIT, $0
+ ADDI $2047, X5, X6
+ ADDI $-2048, X5, X6
+ ADDI $2048, X5, X6
+ ADDI $-2049, X5, X6
+ ADDI $4094, X5, X6
+ ADDI $-4096, X5, X6
+ ADDI $4095, X5, X6
+ ADDI $-4097, X5, X6
+ ADDI $0, X5, X6
+ SLTI $2047, X5, X7
+ SLTI $-2048, X5, X7
+ SLTIU $2047, X5, X7
+ SLTIU $-2048, X5, X7
+ ANDI $-2048, X5, X6
+ ANDI $2047, X5, X6
+ ORI $-1, X5, X6
+ XORI $2047, X5, X6
+ XORI $-2048, X5, X6
+ RET
+
+TEXT ·immAlias(SB), NOSPLIT, $0
+ ADD $2047, X5, X6
+ ADD $2048, X5, X6
+ SUB $1, X5, X6
+ SUB $2049, X5, X6
+ AND $-1, X5, X6
+ OR $2047, X5, X6
+ XOR $-2048, X5, X6
+ SLT $55, X5, X7
+ SLTU $55, X5, X7
+ ADDW $2047, X5, X6
+ RET
+
+TEXT ·immUType(SB), NOSPLIT, $0
+ LUI $0x7FFFF, X6
+ LUI $-0x80000, X6
+ LUI $1, X6
+ AUIPC $0x7FFFF, X7
+ AUIPC $-0x80000, X7
+ RET
+
+TEXT ·immShift(SB), NOSPLIT, $0
+ SLLI $0, X5, X6
+ SLLI $31, X5, X6
+ SLLI $63, X5, X6
+ SRLI $31, X5, X6
+ SRLI $63, X5, X6
+ SRAI $1, X5, X6
+ SRAI $63, X5, X6
+ SLLIW $31, X5, X6
+ SRLIW $31, X5, X6
+ SRAIW $31, X5, X6
+ SLLIUW $31, X5, X6
+ RET
+
+TEXT ·immWide(SB), NOSPLIT, $0
+ MOV $0, X10
+ MOV $2047, X10
+ MOV $2048, X10
+ MOV $-2048, X10
+ MOV $4095, X10
+ MOV $-4097, X10
+ MOV $0x12345678, X10
+ MOV $0x123456789, X10
+ MOV $0x123456789ABCDEF0, X10
+ MOV $-1, X11
+ MOV $-0x8000000000000000, X11
+ MOV $0x7FFFFFFFFFFFFFFF, X12
+ RET
+
+TEXT ·memOffsets(SB), NOSPLIT, $0
+ LD 0(X10), X11
+ LD 2047(X10), X11
+ LD -2048(X10), X11
+ LD 2048(X10), X11
+ LD 4095(X10), X11
+ LD -4096(X10), X11
+ LW 0(X10), X12
+ LBU -1(X10), X12
+ LHU 2(X10), X12
+ LWU -3(X10), X12
+ SD X11, 0(X10)
+ SD X11, 2047(X10)
+ SD X11,-2048(X10)
+ SD X11, 4095(X10)
+ SW X12,-4096(X10)
+ SH X12, 6(X10)
+ SB X12, 7(X10)
+ FLW 8(X10), F8
+ FLD -8(X10), F8
+ FSW F8, 16(X10)
+ FSD F8,-16(X10)
+ RET
diff --git a/asm/testdata/seeds/riscv64/rvc.s b/asm/testdata/seeds/riscv64/rvc.s
new file mode 100644
index 0000000..d612171
--- /dev/null
+++ b/asm/testdata/seeds/riscv64/rvc.s
@@ -0,0 +1,95 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleRISCV64: the RVC-compressible shapes. Every
+// instruction here has a compressed 16-bit encoding the compression pass may
+// pick: the two-operand ALU forms over x8-x15, the stack-pointer loads and
+// stores at the scaled offset boundaries, C.ADDI16SP and C.ADDI4SPN ranges,
+// the compressed branches and the uncompressible spellings beside them.
+
+#include "textflag.h"
+
+TEXT ·primeALU(SB), NOSPLIT, $0
+ ADD X9, X8, X8
+ ADD X15, X8, X8
+ ADDI $1, X8, X8
+ ADDI $31, X15, X15
+ ADDI $-32, X8, X8
+ AND X9, X8, X8
+ ANDI $3, X8, X8
+ OR X10, X9, X9
+ XOR X11, X10, X10
+ SUB X13, X12, X12
+ SLLI $2, X8, X8
+ SRLI $5, X9, X9
+ SRAI $7, X10, X10
+ MOV X9, X8
+ MOV X1, X8
+ MOV X8, X1
+ RET
+
+TEXT ·stackOffsets(SB), NOSPLIT, $0
+ LW 0(X2), X8
+ LW 4(X2), X8
+ LW 124(X2), X9
+ LW 2044(X2), X10
+ LD 0(X2), X8
+ LD 8(X2), X8
+ LD 504(X2), X9
+ SW X8, 0(X2)
+ SW X8, 124(X2)
+ SW X8, 2044(X2)
+ SD X8, 0(X2)
+ SD X8, 504(X2)
+ FLW 0(X2), F8
+ FLD 504(X2), F8
+ FSW F8, 0(X2)
+ FSD F8, 504(X2)
+ RET
+
+TEXT ·frameAdj(SB), NOSPLIT, $0
+ ADDI $16, X2, X2
+ ADDI $-16, X2, X2
+ ADDI $496, X2, X2
+ ADDI $-512, X2, X2
+ ADDI $1024, X2, X2
+ ADDI $2048, X2, X2
+ ADDI $1, X2, X2
+ RET
+
+TEXT ·primeMem(SB), NOSPLIT, $0
+ LW 0(X8), X9
+ LW 4(X8), X10
+ LW 124(X8), X11
+ LD 0(X8), X9
+ LD 8(X8), X10
+ LD 120(X8), X11
+ SW X9, 0(X8)
+ SW X9, 124(X8)
+ SD X9, 0(X8)
+ SD X9, 120(X8)
+ RET
+
+TEXT ·cBranches(SB), NOSPLIT, $0
+ BEQ X8, X0, cb1
+ BNE X9, X0, cb2
+ BLT X10, X0, cb1
+ BGE X11, X0, cb2
+ BLTU X12, X0, cb1
+ BGEU X13, X0, cb2
+
+cb1:
+ MOV X8, X9
+
+cb2:
+ MOV X9, X8
+ RET
+
+TEXT ·uncompressible(SB), NOSPLIT, $0
+ ADD X17, X16, X16
+ ADDI $2048, X8, X8
+ LW 2048(X2), X10
+ LD 512(X2), X10
+ SW X8, 2048(X2)
+ ADDI $2049, X2, X2
+ RET
diff --git a/asm/testdata/seeds/riscv64/rvv.s b/asm/testdata/seeds/riscv64/rvv.s
new file mode 100644
index 0000000..f78d530
--- /dev/null
+++ b/asm/testdata/seeds/riscv64/rvv.s
@@ -0,0 +1,233 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleRISCV64: the RVV surface. The configuration
+// setters, the load/store families with their segment and fault-only-first
+// variants, the arithmetic operand classes (VV/VX/VI, the masks, the
+// merge and carry forms, the reductions and the whole-register moves).
+
+#include "textflag.h"
+
+TEXT ·config(SB), NOSPLIT, $0
+ VSETVLI X5, E8, M8, TA, MA, X6
+ VSETVLI X5, E8, M1, TU, MU, X6
+ VSETVLI $15, E32, M1, TA, MA, X12
+ VSETVLI $31, E64, M2, TU, MU, X12
+ VSETIVLI $0, E16, M4, TA, MA, X0
+ VSETIVLI $4, E32, M1, TA, MA, X0
+ VSETIVLI $31, E8, M8, TU, MU, X15
+ RET
+
+TEXT ·loads(SB), NOSPLIT, $0
+ VLE8V (X10), V8
+ VLE16V (X10), V8
+ VLE32V (X10), V8
+ VLE64V (X11), V16
+ VSE8V V8, (X10)
+ VSE16V V8, (X10)
+ VSE32V V15, (X11)
+ VSE64V V24, (X10)
+ VLSE8V (X14), X9, V0
+ VLSE32V (X14), X5, V4
+ VSSE64V V4, X7, (X14)
+ VLUXEI8V (X10), V20, V4
+ VLOXEI32V (X10), V20, V4
+ VSUXEI64V V4, V20, (X10)
+ VSOXEI16V V4, V20, (X10)
+ VLE8FFV (X10), V8
+ RET
+
+TEXT ·segments(SB), NOSPLIT, $0
+ VLSEG2E8V (X14), V0
+ VLSEG4E32V (X14), V0
+ VLSEG8E64V (X14), V4
+ VSSEG2E32V V0, (X14)
+ VSSEG8E8V V4, (X14)
+ VLSSEG4E32V (X14), X0, V0
+ VLSSEG8E32V (X10), X0, V4
+ VLUXSEG2EI32V (X10), V20, V4
+ VLOXSEG4EI64V (X10), V20, V4
+ VSUXSEG2EI8V V4, V20, (X10)
+ VLSEG4E8FFV (X14), V0
+ RET
+
+TEXT ·wholeReg(SB), NOSPLIT, $0
+ VL1RV (X10), V8
+ VL2RV (X10), V16
+ VL4RV (X10), V0
+ VL8RV (X10), V0
+ VS1RV V8, (X10)
+ VS2RV V16, (X10)
+ VS4RV V0, (X10)
+ VS8RV V0, (X10)
+ VL1RE8V (X10), V8
+ VL2RE16V (X10), V16
+ VL4RE32V (X10), V0
+ VL8RE64V (X10), V0
+ VL2RE64V (X10), V16
+ VLMV (X10), V0
+ VSMV V0, (X10)
+ RET
+
+TEXT ·arith(SB), NOSPLIT, $0
+ VADDVV V1, V2, V3
+ VADDVV V1, V2, V0, V3
+ VADDVX X10, V2, V0, V3
+ VADDVI $15, V2, V0, V3
+ VADDVI $-16, V2, V0, V3
+ VADDVI $0, V2, V3
+ VSUBVV V1, V2, V0, V3
+ VSUBVX X10, V2, V3
+ VRSUBVX X10, V2, V0, V3
+ VRSUBVI $15, V2, V0, V3
+ VANDVI $-1, V2, V3
+ VORVI $15, V2, V3
+ VORVI $-16, V2, V3
+ VXORVI $0, V2, V3
+ VNEGV V2, V0, V3
+ VNOTV V2, V3
+ VIDV V12
+ VFMVVF F10, V14
+ VMVVI $15, V14
+ VMVVI $-16, V14
+ VMVVV V1, V4
+ VMVVX X10, V4
+ VMVXS V4, X10
+ VFMVSF F10, X11
+ RET
+
+TEXT ·shiftsSliding(SB), NOSPLIT, $0
+ VSLLVI $0, V28, V30
+ VSLLVI $31, V28, V30
+ VSRLVI $25, V29, V29
+ VSRAVI $31, V4, V5
+ VNSRLWI $31, V6, V7
+ VNSRAWI $0, V6, V7
+ VSLLVV V1, V2, V3
+ VSRLVX X10, V2, V3
+ VSRAVV V1, V2, V3
+ VRORVI $7, V4, V5
+ VRORVI $31, V4, V5
+ VRORVV V1, V2, V3
+ VROLVX X10, V2, V3
+ VSLIDEUPVI $31, V4, V5
+ VSLIDEUPVX X10, V4, V5
+ VSLIDEDOWNVI $0, V4, V5
+ VSLIDEDOWNVX X10, V4, V5
+ VFSLIDE1UPVF F10, V4, V5
+ VFSLIDE1DOWNVF F10, V4, V5
+ VRGATHERVI $31, V2, V3
+ VRGATHERVV V1, V2, V3
+ VRGATHERVX X10, V2, V3
+ RET
+
+TEXT ·compareMask(SB), NOSPLIT, $0
+ VMSEQVV V1, V2, V0
+ VMSEQVX X10, V2, V0
+ VMSEQVI $0, V2, V0
+ VMSNEVI $-16, V2, V0
+ VMSLTVI $15, V2, V0
+ VMSLTUVI $15, V2, V0
+ VMSLEVI $-1, V2, V0
+ VMSGEVI $15, V2, V0
+ VMSGEUVI $0, V2, V0
+ VMSGTVV V1, V2, V0
+ VMSLEVV V1, V2, V0
+ VMFEQVF F10, V2, V0
+ VMFLTVF F10, V2, V0
+ VMFGEVF F10, V2, V0
+ VMANDMM V1, V2, V3
+ VMNANDMM V1, V2, V3
+ VMANDNMM V1, V2, V3
+ VMORMM V1, V2, V3
+ VMXORMM V1, V2, V3
+ VMXNORMM V1, V2, V3
+ VMNORMM V1, V2, V3
+ VMORNMM V1, V2, V3
+ VMCLRM V1
+ VMSETM V1
+ VMNOTM V1, V2
+ VCPOPM V0, X6
+ VFIRSTM V0, X7
+ VIOTAM V0, X5
+ VMSBFM V0, V1
+ VMSIFM V0, V1
+ VMSOFM V0, V1
+ RET
+
+TEXT ·carryMerge(SB), NOSPLIT, $0
+ VADCVVM V1, V2, V0, V3
+ VADCVXM X10, V2, V0, V3
+ VADCVIM $15, V2, V0, V3
+ VMADCVV V1, V2, V3
+ VMADCVX X10, V2, V3
+ VMADCVI $-16, V2, V3
+ VSBCVVM V1, V2, V0, V3
+ VSBCVXM X10, V2, V0, V3
+ VSBCVVM V1, V2, V0, V3
+ VSBCVXM X10, V2, V0, V3
+ VMADCVV V1, V2, V3
+ VMADCVX X10, V2, V3
+ VMADCVI $0, V2, V3
+ VMADCVVM V1, V2, V0, V3
+ VMERGEVVM V1, V2, V0, V3
+ VMERGEVXM X10, V2, V0, V3
+ VMERGEVIM $15, V2, V0, V3
+ VFMERGEVFM F10, V2, V0, V3
+ RET
+
+TEXT ·reduceWiden(SB), NOSPLIT, $0
+ VREDSUMVS V1, V2, V3
+ VREDMAXUVS V1, V2, V3
+ VREDMINVS V1, V2, V3
+ VREDANDVS V1, V2, V3
+ VREDORVS V1, V2, V3
+ VREDXORVS V1, V2, V3
+ VWREDSUMUVS V1, V2, V3
+ VWREDSUMVS V1, V2, V3
+ VFWREDOSUMVS V1, V2, V3
+ VFWREDUSUMVS V1, V2, V3
+ VWADDUVV V1, V2, V3
+ VWADDWV V1, V2, V3
+ VWSUBUVV V1, V2, V3
+ VWSUBWV V1, V2, V3
+ VWADDUWX X10, V2, V3
+ VWADDWX X10, V2, V3
+ VMULVV V1, V2, V3
+ VMULHUVV V1, V2, V3
+ VMULHSUVV V1, V2, V3
+ VDIVUVV V1, V2, V3
+ VREMVV V1, V2, V3
+ VSMULVV V1, V2, V3
+ VCLMULVV V1, V2, V3
+ VCLMULHVX X10, V2, V3
+ RET
+
+TEXT ·fpVec(SB), NOSPLIT, $0
+ VFADDVV V1, V2, V3
+ VFADDVF F10, V2, V3
+ VFSUBVF F10, V2, V3
+ VFMULVV V1, V2, V3
+ VFDIVVF F10, V2, V3
+ VFRSUBVF F10, V2, V3
+ VFMINVV V1, V2, V3
+ VFMAXVF F10, V2, V3
+ VFMACCVV V1, V2, V3
+ VFMACCVF F10, V2, V3
+ VFMSACVV V1, V2, V3
+ VFNMSACVF F10, V2, V3
+ VFMADDVV V1, V2, V3
+ VFNMADDVF F10, V2, V3
+ VFWMACCVV V1, V2, V3
+ VFWMSACVF F10, V2, V3
+ VFSQRTV V4, V5
+ VFCLASSV V4, V5
+ VFREC7V V4, V5
+ VFRSQRT7V V4, V5
+ VFCVTXFV V4, V5
+ VFCVTRTZXFV V4, V5
+ VFNCVTFFW V4, V5
+ VFWCVTFFV V4, V5
+ VSEXTVF2 V4, V5
+ VZEXTVF8 V4, V5
+ RET
diff --git a/asm/testdata/seeds/riscv64/system-fp.s b/asm/testdata/seeds/riscv64/system-fp.s
new file mode 100644
index 0000000..6628351
--- /dev/null
+++ b/asm/testdata/seeds/riscv64/system-fp.s
@@ -0,0 +1,177 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleRISCV64: branches over their offset range, the
+// jumps and calls, the system instructions, the atomics with the LR/SC pair,
+// the FP arithmetic, compare, conversion and fused multiply-add families in
+// every width including quad.
+
+#include "textflag.h"
+
+TEXT ·branches(SB), NOSPLIT, $0
+ BEQ X5, X6, b1
+ BNE X5, X6, b2
+ BLT X5, X6, b1
+ BGE X5, X6, b2
+ BLTU X5, X6, b1
+ BGEU X5, X6, b2
+ BGT X6, X5, b1
+ BLE X6, X5, b2
+ BGTU X6, X5, b1
+ BLEU X6, X5, b2
+
+b1:
+ ADDI $1, X5, X5
+
+b2:
+ ADDI $-1, X6, X6
+ BEQ X5, X6, b1
+ RET
+
+TEXT ·farBranch(SB), NOSPLIT, $0
+ BEQ X5, X6, far
+ SLTI $2047, X5, X6
+ BEQ X5, X6, far
+
+far:
+ SLTIU $2047, X5, X6
+ BGE X5, X6, far
+ RET
+
+TEXT ·jumps(SB), NOSPLIT, $0
+ JAL X1, j1
+
+j1:
+ JALR X0, (X1)
+ JALR X1, 0(X5)
+ JMP j2
+
+j2:
+ JMP (X5)
+ CALL (X5)
+ JMP -3(PC)
+ CALL runtime·morestack_noctxt(SB)
+ RET
+
+TEXT ·system(SB), NOSPLIT, $0
+ FENCE
+ FENCE.TSO
+ PAUSE
+ ECALL
+ EBREAK
+ RET
+
+TEXT ·atomics(SB), NOSPLIT, $0
+ AMOSWAPW X5, (X6), X7
+ AMOSWAPD X5, (X6), X7
+ AMOADDW X5, (X6), X7
+ AMOADDD X5, (X6), X7
+ AMOANDW X5, (X6), X7
+ AMOORW X5, (X6), X7
+ AMOXORW X5, (X6), X7
+ AMOMINW X5, (X6), X7
+ AMOMAXW X5, (X6), X7
+ AMOMINUW X5, (X6), X7
+ AMOMAXUW X5, (X6), X7
+ AMOMIND X5, (X6), X7
+ AMOMAXD X5, (X6), X7
+ AMOMINUD X5, (X6), X7
+ AMOMAXUD X5, (X6), X7
+ LRW (X6), X7
+ LRD (X6), X7
+ SCW X5, (X6), X7
+ SCD X5, (X6), X7
+ RET
+
+TEXT ·fpArith(SB), NOSPLIT, $0
+ FADDS F1, F2, F3
+ FSUBS F1, F2, F3
+ FMULS F1, F2, F3
+ FDIVS F1, F2, F3
+ FADDD F1, F2, F3
+ FSUBD F1, F2, F3
+ FMULD F1, F2, F3
+ FDIVD F1, F2, F3
+ FADDQ F1, F2, F3
+ FSUBQ F1, F2, F3
+ FMULQ F1, F2, F3
+ FDIVQ F1, F2, F3
+ FSQRTS F1, F2
+ FSQRTD F1, F2
+ FSQRTQ F1, F2
+ FMINS F1, F2, F3
+ FMAXS F1, F2, F3
+ FMIND F1, F2, F3
+ FMAXD F1, F2, F3
+ FMINQ F1, F2, F3
+ FMAXQ F1, F2, F3
+ RET
+
+TEXT ·fpFma(SB), NOSPLIT, $0
+ FMADDS F1, F2, F3, F4
+ FMSUBS F1, F2, F3, F4
+ FNMSUBS F1, F2, F3, F4
+ FNMADDS F1, F2, F3, F4
+ FMADDD F1, F2, F3, F4
+ FMSUBD F1, F2, F3, F4
+ FNMSUBD F1, F2, F3, F4
+ FNMADDD F1, F2, F3, F4
+ FMADDQ F1, F2, F3, F4
+ FMSUBQ F1, F2, F3, F4
+ FNMSUBQ F1, F2, F3, F4
+ FNMADDQ F1, F2, F3, F4
+ RET
+
+TEXT ·fpCvt(SB), NOSPLIT, $0
+ FCVTWS F1, X5
+ FCVTWUS F1, X5
+ FCVTLS F1, X5
+ FCVTLUS F1, X5
+ FCVTWD F1, X5
+ FCVTWUD F1, X5
+ FCVTLD F1, X5
+ FCVTLUD F1, X5
+ FCVTSW X5, F1
+ FCVTSWU X5, F1
+ FCVTSL X5, F1
+ FCVTSLU X5, F1
+ FCVTDW X5, F1
+ FCVTDWU X5, F1
+ FCVTDL X5, F1
+ FCVTDLU X5, F1
+ FCVTSD F1, F2
+ FCVTDS F1, F2
+ FCVTSQ F1, F2
+ FCVTDQ F1, F2
+ FCVTQS F1, F2
+ FCVTQD F1, F2
+ FCVTWQ F1, X5
+ FCVTLQ F1, X5
+ FCVTQW X5, F1
+ FCVTQL X5, F1
+ FCLASSS F1, X5
+ FCLASSD F1, X5
+ FCLASSQ F1, X5
+ FMVXD F1, X5
+ FMVDX X5, F1
+ FMVXW F1, X5
+ FMVWX X5, F1
+ RET
+
+TEXT ·fpSign(SB), NOSPLIT, $0
+ FSGNJS F1, F0, F2
+ FSGNJNS F1, F0, F2
+ FSGNJXS F1, F0, F2
+ FSGNJD F1, F0, F2
+ FSGNJND F1, F0, F2
+ FSGNJXD F1, F0, F2
+ FLTS F1, F2, X5
+ FLES F1, F2, X5
+ FEQS F1, F2, X5
+ FLTD F1, F2, X5
+ FLED F1, F2, X5
+ FEQD F1, F2, X5
+ FLTQ F1, F2, X5
+ FLEQ F1, F2, X5
+ FEQQ F1, F2, X5
+ RET
diff --git a/asm/testdata/seeds/riscv64/zbb.s b/asm/testdata/seeds/riscv64/zbb.s
new file mode 100644
index 0000000..89e3139
--- /dev/null
+++ b/asm/testdata/seeds/riscv64/zbb.s
@@ -0,0 +1,65 @@
+// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)
+// SPDX-License-Identifier: BSD-3-Clause
+
+// Seed corpus for FuzzAssembleRISCV64: the Zbb/Zba/Zbs/Zicond bit-manipulation
+// and address-generation set, with every unary form's W variant and the
+// shamt-range immediate forms.
+
+#include "textflag.h"
+
+TEXT ·unary(SB), NOSPLIT, $0
+ CLZ X5, X6
+ CLZW X5, X6
+ CTZ X5, X6
+ CTZW X5, X6
+ CPOP X5, X6
+ CPOPW X5, X6
+ SEXTB X5, X6
+ SEXTH X5, X6
+ ZEXTH X5, X6
+ ORCB X5, X6
+ REV8 X5, X6
+ RET
+
+TEXT ·rolRor(SB), NOSPLIT, $0
+ ROL X7, X5, X6
+ ROR X7, X5, X6
+ RORI $0, X5, X6
+ RORI $63, X5, X6
+ ANDN X7, X5, X6
+ ORN X7, X5, X6
+ XNOR X7, X5, X6
+ MAX X7, X5, X6
+ MAXU X7, X5, X6
+ MIN X7, X5, X6
+ MINU X7, X5, X6
+ CLMUL X7, X5, X6
+ CLMULH X7, X5, X6
+ CLMULR X7, X5, X6
+ RET
+
+TEXT ·addrGen(SB), NOSPLIT, $0
+ SH1ADD X7, X5, X6
+ SH2ADD X7, X5, X6
+ SH3ADD X7, X5, X6
+ SH1ADDUW X7, X5, X6
+ SH2ADDUW X7, X5, X6
+ SH3ADDUW X7, X5, X6
+ ADDUW X7, X5, X6
+ RET
+
+TEXT ·bitImm(SB), NOSPLIT, $0
+ BCLR $31, X5, X6
+ BEXT $63, X5, X6
+ BINV $0, X5, X6
+ BSET $31, X5, X6
+ BCLRI $63, X5, X6
+ BEXTI $31, X5, X6
+ BINVI $63, X5, X6
+ BSETI $63, X5, X6
+ RET
+
+TEXT ·condZero(SB), NOSPLIT, $0
+ CZEROEQZ X7, X5, X6
+ CZERONEZ X7, X5, X6
+ RET