petrbalvin be2ceaafb9
Test / vet (push) Successful in 47s
Test / test (push) Successful in 2m34s
Test / build (push) Successful in 41s
feat(amd64): encode legacy SSE packed binaries and imm8 shuffles
2026-08-27 17:15:10 +02:00
2026-08-20 16:03:26 +02:00
2026-08-20 16:03:26 +02:00

gasm-devkit

Developer tooling for GAsm — Go's built-in Plan 9 assembler.

Go ships an assembler but no tooling for it. There is no syntax highlighting, no autocomplete, no linter, no static analyser, no formatter, no standalone assembler and no debugger for .s files. Developers write assembly blind, validate it by benchmark, and debug it by print statement.

gasm-devkit is the missing toolkit. It is a single, self-contained binary — gasm — that brings proper developer tooling to Plan 9 assembly:

gasm tokens   dump the lexical token stream
gasm parse    parse and report syntax errors
gasm fmt      canonicalise formatting (gofmt for assembly)
gasm lint     static checks
gasm lsp      language server (completion, hover, symbols, diagnostics, highlighting)
gasm asm      standalone assembler
gasm verify   dynamic analysis & verification
gasm debug    source-level debugger
gasm diff     compare machine code of two .s files
gasm profile  show basic-block structure of functions

Architecture support

gasm-devkit targets every architecture Go's assembler speaks. The instruction tables are generated from the Go toolchain's own assembler source (cmd/internal/obj/<arch>), so gasm-devkit recognises every mnemonic the real assembler accepts — not a hand-maintained subset that drifts and rots.

Architecture GOARCH File suffix Instructions recognised
AMD64 amd64 _amd64.s 1600 + common opcodes + traditional aliases
ARM64 arm64 _arm64.s 538 + common opcodes
RISC-V riscv64 _riscv64.s 961 + common opcodes
LoongArch loong64 _loong64.s 799 + common opcodes

"Common opcodes" are the instructions shared by every architecture (RET, JMP, NOP, CALL, TEXT, FUNCDATA, PCDATA, …). AMD64 additionally carries the traditional conditional-jump spellings (JZ, JNZ, JA, JC, …) that the assembler accepts as aliases. Regenerating the tables is one command — just gen — and requires only a Go installation; the committed output has no runtime dependency on the toolchain.

Supported Platforms

The toolkit runs on Linux. All four Linux architectures are supported as hosts — amd64, arm64, riscv64 and loong64 — and the release matrix cross-compiles the same four targets.

FreeBSD support is planned for a future release.

Principles

  • Pure Go and GAsm only. No C, no cgo, no external toolchains, no native binaries, no JavaScript runtimes. The parser is hand-written; there is no parser generator.
  • Self-contained. The toolkit's production code depends only on the standard library; one binary, no runtime data files. The single module dependency, golang.org/x/arch, is used only in tests to validate the instruction encoder by round-trip decoding — it is never linked into the gasm binary.
  • Linux-only. Runs natively on amd64, arm64, riscv64 and loong64 Linux hosts; the release matrix cross-compiles the same four targets. Latest stable Go only.
  • No vendor lock-in. The integration surface is the Language Server Protocol and a command-line interface — both open standards. No cloud service, no proprietary API, no dependence on any one editor's internals.
  • Complete and verifiable. Instruction coverage is generated from the assembler's own source and regenerated on demand, so it cannot silently fall behind the toolchain.

Components

Package Purpose
token Lexical token kinds and source positions.
lexer Hand-written scanner for Plan 9 assembly.
ast The abstract syntax tree.
parser Line-oriented, error-tolerant parser producing the AST.
arch amd64, arm64, riscv64 and loong64 register files and instruction tables.
lint Conservative static checks (13 rules including unused-label, invalid-textflag, stack-imbalance).
format A canonical formatter — gofmt for assembly.
asm The standalone assembler: all four architecture encoders, linker, object-file emitters (ELF with DWARF5, GOOBJ).
verify JIT execution substrate for dynamic analysis, combined ABI+fuzz differential testing. Assembly trampolines for all four architectures.
debug Interactive ptrace debugger for all four architectures: single-stepping, breakpoints, hardware watchpoints, register and memory inspection.
lsp Language Server Protocol server: completion, hover, symbols, diagnostics, semantic tokens, find references, rename, formatting, inlay hints.
cmd/gasm The gasm binary tying it all together.
_gen The generator that rebuilds the instruction tables from the Go toolchain.

See docs/ARCHITECTURE.md for the design rationale and data flow, and docs/DECISIONS.md for design decisions deliberately postponed (with the analysis needed to pick them up again).

Quick start

just install     # download dependencies (there are none)
just build       # go vet + gofmt check — zero errors, zero warnings
just test        # full suite, race detector, 80 % coverage gate
just fmt         # gofmt the tree
just gen         # regenerate the instruction tables from the Go toolchain

Install the binary and use it:

just install-bin                    # installs gasm into $GOBIN

gasm --help                         # overview of commands and flags
gasm tokens kernel_amd64.s          # dump the token stream
gasm parse  kernel_amd64.s          # parse, report syntax errors
gasm fmt    -w kernel_amd64.s       # canonicalise in place
gasm fmt                            # reformat every .s below here, like go fmt
gasm lint   *.s                     # static checks
gasm asm --format elf -o k.o k.s    # assemble to a linkable ELF object
gasm verify kernel_amd64.s           # JIT-load and report functions
gasm verify --ground-truth k.s      # byte-for-byte vs go tool asm
gasm verify --call decodeBlockAVX2 --buf src:64:hex...,dst:256:zero k.s
gasm debug --func name k.s           # interactive debugger
gasm diff a.s b.s                    # compare machine code byte-for-byte
gasm diff --map wideCopyAVX2=wideCopyAVX512 avx2.s avx512.s
gasm profile k.s                     # show basic-block structure

See CONTRIBUTING.md for the full development workflow, docs/CLI.md for the command reference, and docs/DEVELOPMENT.md for setup and recipes.

Editor integration

gasm lsp speaks the Language Server Protocol over standard input/output, so any LSP-capable editor can use it — point your editor's LSP client at the binary and associate it with .s files. Syntax highlighting is delivered as LSP semantic tokens, so no editor-specific grammar is required. The server infers the target architecture from the file-name suffix (_amd64.s / _arm64.s / _riscv64.s / _loong64.s).

License

BSD-3-Clause — see LICENSE.
Copyright © 2026 Petr Balvín

S
Description
A complete software development kit for the Go Plan 9 assembler: lexer, parser, linter, formatter, an assembler with AVX-512 and RISC-V support, a debugger, and an LSP server. Pure Go, no external toolchains.
Readme BSD-3-Clause
5.5 MiB
v0.35.0
Latest
2026-09-21 23:33:11 +00:00
Languages
Go 99%
Assembly 0.8%
Just 0.2%