Skip to content

Home

go-asmgen documentation

Ergonomic generation of Go-compatible Plan 9 assembly for every 64-bit Go target — amd64, arm64, riscv64, loong64, ppc64le (VSX), and s390x (vector facility, big-endian).

avo does this for amd64 by encoding instruction bytes itself, which is exactly what makes extending it to new ISAs expensive. go-asmgen instead emits Plan 9 assembly text and lets the Go toolchain assembler (cmd/asm) encode it — so each architecture is only a thin move/register surface over a shared ABI0 layout model, not a byte-level encoder. avo remains the richer choice for amd64-specific work; go-asmgen offers one uniform builder across every target. The exception is an instruction cmd/asm cannot assemble yet. Those are the ppc64le VSX float64 arithmetic (XVADDDP…) and the loong64 vector fused multiply-add (VFMADDD…). go-asmgen emits each one as a WORD whose comment gives the spelling proposed for cmd/asm, and keeps its encoding, references and proposed spelling in a registry (internal/gap). From that registry come the Go patches in goasm-patches/, and a weekly check that notices when Go catches up. Since v0.15.0 the arm64 vector float64 arithmetic (VFADD2D…) and the loong64 broadcast load are encoded by cmd/asm.

PackageWhat it is
amd64builder emitting Plan 9 amd64 instructions (MOVQ, MOVSS/MOVSD)
arm64builder emitting Plan 9 arm64 instructions (MOVD, FMOVS/FMOVD)
riscv64builder emitting Plan 9 riscv64 instructions (MOV, MOVF/MOVD)
loong64builder emitting Plan 9 loong64 instructions (MOVV, MOVF/MOVD)
ppc64lebuilder emitting Plan 9 ppc64le instructions (MOVD, FMOVS/FMOVD)
s390xbuilder emitting Plan 9 s390x instructions (MOVD, FMOVS/FMOVD; big-endian)
abithe architecture-independent ABI0 layout model all builders share
emita deliberately dumb, ISA-agnostic writer of well-formed Plan 9 .s text

Start with the Quick start, read the ABI0 & design notes for why it is built this way, see Aggregates for struct/slice/string parameters, then riscv64, loong64, ppc64le and s390x for how cheaply a new ISA drops in.

The seventh target: wasm-SIMD

The same layering pattern runs one more target — wasm-SIMD (v128) — as the wasm/ peer package inside this module. Go’s compiler does not emit v128 from Go source, and Plan 9 assembly has no wasm dialect, so wasm-SIMD is necessarily an external-kernel story. The emitter builds WAT text programmatically, wat2wasm compiles it, and the Go host imports it via //go:wasmimport.

Thirteen kernels ship today — matchlen, hex, hex_decode, popcount, toupper, memchr, isascii, utf8len, json_clean, adler32, base64_encode, indexany4, base64_decode — each byte-equivalent to a hand-written reference and wazero-verified against a Go stdlib function. Start with the wasm overview or the quick start.

Source lives at github.com/go-asmgen/asmgen.