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.
| Package | What it is |
|---|---|
amd64 | builder emitting Plan 9 amd64 instructions (MOVQ, MOVSS/MOVSD) |
arm64 | builder emitting Plan 9 arm64 instructions (MOVD, FMOVS/FMOVD) |
riscv64 | builder emitting Plan 9 riscv64 instructions (MOV, MOVF/MOVD) |
loong64 | builder emitting Plan 9 loong64 instructions (MOVV, MOVF/MOVD) |
ppc64le | builder emitting Plan 9 ppc64le instructions (MOVD, FMOVS/FMOVD) |
s390x | builder emitting Plan 9 s390x instructions (MOVD, FMOVS/FMOVD; big-endian) |
abi | the architecture-independent ABI0 layout model all builders share |
emit | a 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.