docs: complete the release delta in the changelog and readme

This commit is contained in:
2026-09-21 22:45:56 +02:00
parent f720381d43
commit 057c4eb545
3 changed files with 113 additions and 72 deletions
+90 -66
View File
@@ -7,59 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [development] ## [development]
### Fixed
- **The operand forms GOROOT writes.** Numeric PC-relative jumps
(`JEQ 2(PC)`, the park loop `JMP 0(PC)`) resolve with the toolchain's
own instruction counting and fold jump-to-jump chains exactly as its
branch optimiser does; symbol immediates (`MOVQ $sym(SB), AX`)
assemble to the toolchain's RIP-relative LEA with an R_PCREL
relocation; negated constant expressions in operands (`ADJSP
$-(REGS - 8)`, the shape the cgo ABI macros write) fold; the TLS
access pair assembles as the toolchain's one-instruction form (the
bare `MOVQ TLS, r` load nops out and `off(r)(TLS*1)` folds to the
segment-prefixed absolute whose disp32 carries the R_TLSLE
relocation, per-GOOS); arm64 accepts the bare-register indirect branch
(`BL R9` beside `BL (R9)`, both BLR) and the zero-immediate store
(`MOVD $0, mem` through the zero register, rejecting non-zero immediates
as the toolchain does); `PCALIGN` now aligns on amd64, padding with the
toolchain's greedy single-instruction NOPs; the segment-absolute forms
(`MOVQ 0x30(GS), AX` and the store direction) and the absolute
crash-store (`MOVL $0xf1, 0xf1`) encode; and `gasm asm` predefines
the `GOARCH_<arch>` and `GOOS_<goos>` macros the go command passes to
`go tool asm`, so GOROOT headers' `#ifdef GOARCH_amd64` platform blocks
(`go_tls.h`'s `get_tls` and friends) select as intended. The GOROOT
corpus measure moves to 291 of 353 files assembling for every target
architecture (82.4 %), 97.4 % of the real-code corpus, from 70.8 %
and 82.2 %.
### Added ### Added
- **Per-architecture reference pages.** [docs/asm/](docs/asm/README.md) - **The go_asm.h generator.** `gasm asm` generates the package's go_asm.h
gains AMD64, ARM64, RISCV64 and LOONG64: the register files and the itself when an assembly file includes it: the Go files beside the source
roles the ABI fixes, addressing, operand order with every special form, are type-checked for the target architecture and the constants and field
constants and materialisation, alignment, fences and the relocations offsets become assembler defines, so package-context files assemble with
each target emits. An instruction inventory appendix per architecture no compiler and no `go build` in the loop. `-GOOS` selects the
is generated from the toolchain's own tables by `just gen`, and the type-checking GOOS for GOOS-specific files, and the corpus audit derives
regenerated tables recognise 147 more mnemonics than the previous the GOOS from the file name.
release carried (arm64 107, riscv64 31, loong64 9). - **ELF data relocations on arm64, riscv64 and loong64.** `gasm asm
- **The Plan 9 assembly language reference.** [docs/asm/](docs/asm/README.md) --format elf` emits `.rela.data` for symbol-valued DATA initialisers on
opens the complete language reference with its common core: the lexicon, every architecture (amd64 carried them already), so standalone ELF
statement structure and constant expressions, the operand grammar with objects link on all four targets.
the pseudo-registers and symbol naming, the directives and the function - **Corpus failure listing.** `gasm audit-instructions --corpus --list`
flag vocabulary, preprocessing with `#define` and `#include`, and the prints every failing file with its failure reason, per architecture,
Go-embedded layer (ABI0, prototypes, `go_asm.h`, `funcdata.h` and the instead of one representative file per reason.
runtime contract). Every claim is verified against `go tool asm` of - **DATA with symbol values and relaxed symbol spellings.** DATA
Go 1.27.1 and gasm's differential tests; the per-architecture pages and initialisers accept `$symbol(SB)` values, laid down as an absolute
generated instruction appendices follow. relocation at the data field (GOOBJ on all four architectures and ELF
- **GOOBJ format specification.** [docs/GOOBJ.md](docs/GOOBJ.md) on all four as of this release), and U+2215 is accepted inside symbol
documents the Go object file format in full: both containers, the 96 package paths.
byte header and all 19 blocks, every structure with its byte
offsets, symbol kinds and flag bits, all 106 relocation types with
the weak variants, aux symbols, the FuncInfo payload, the pc-value
table encoding, the content hashes and the builtin table, all
verified byte for byte against objects produced by Go 1.27.1's own
tools.
- **Macro expansion and include splicing.** `gasm asm`, `gasm diff` and - **Macro expansion and include splicing.** `gasm asm`, `gasm diff` and
`gasm audit-instructions` now preprocess assembly the way the `gasm audit-instructions` now preprocess assembly the way the
toolchain does: object and parameterised `#define` macros expand at toolchain does: object and parameterised `#define` macros expand at
@@ -100,21 +68,77 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
ranges, index-only VSIB memory operands and bare trailing immediates; ranges, index-only VSIB memory operands and bare trailing immediates;
macro substitution reaches parameters used with element suffixes macro substitution reaches parameters used with element suffixes
(`A.S4`), and `;` separates statements in plain files. (`A.S4`), and `;` separates statements in plain files.
- **`gasm asm -GOOS`.** The go_asm.h generator type-checks per target - **Per-architecture reference pages.** [docs/asm/](docs/asm/README.md)
GOOS, so the darwin-only and windows-only runtime files assemble with gains AMD64, ARM64, RISCV64 and LOONG64: the register files and the
their own defines; the corpus audit derives the GOOS from the file roles the ABI fixes, addressing, operand order with every special form,
name. DATA initialisers accept `$symbol(SB)` values (an absolute constants and materialisation, alignment, fences and the relocations
relocation at the data field, GOOBJ on all four architectures and ELF each target emits. An instruction inventory appendix per architecture
on amd64, arm64, riscv64 and loong64), and U+2215 is accepted inside is generated from the toolchain's own tables by `just gen`, and the
symbol package paths. regenerated tables recognise 147 more mnemonics than the previous
- **The corpus audit measures honestly.** Files named for Go ports gasm release carried (arm64 107, riscv64 31, loong64 9).
does not target (arm, 386, s390x, ...) are no longer attempted for the - **The Plan 9 assembly language reference.** [docs/asm/](docs/asm/README.md)
four supported architectures (no supported build compiles them), and opens the complete language reference with its common core: the lexicon,
the headline rate is reported over attemptable files: 136 of 433 on statement structure and constant expressions, the operand grammar with
the full corpus (31.4 %), 135 of 383 on real code (35.2 %), from the the pseudo-registers and symbol naming, the directives and the function
127 that the previous release measured. The probe battery that flag vocabulary, preprocessing with `#define` and `#include`, and the
decides encodability gained the operand shapes the new families use. Go-embedded layer (ABI0, prototypes, `go_asm.h`, `funcdata.h` and the
- runtime contract). Every claim is verified against `go tool asm` of
Go 1.27.1 and gasm's differential tests; the per-architecture pages and
generated instruction appendices follow.
- **GOOBJ format specification.** [docs/GOOBJ.md](docs/GOOBJ.md)
documents the Go object file format in full: both containers, the 96
byte header and all 19 blocks, every structure with its byte
offsets, symbol kinds and flag bits, all 106 relocation types with
the weak variants, aux symbols, the FuncInfo payload, the pc-value
table encoding, the content hashes and the builtin table, all
verified byte for byte against objects produced by Go 1.27.1's own
tools.
### Changed
- **The corpus audit measures like a build.** Files named for a Go port
gasm does not target (arm, 386, s390x, ...) are never attempted, because
no supported build compiles them; the GOOS comes from the file name; and
each target's go_asm.h is generated on the fly. The headline is reported
over attemptable files: 291 of 353 on the full corpus (82.4 %) assemble
for every target architecture and 295 of 303 on real code (97.4 %),
against 108 of 627 over all files (17.2 %) that the previous release
measured.
### Fixed
- **The operand forms GOROOT writes.** Numeric PC-relative jumps
(`JEQ 2(PC)`, the park loop `JMP 0(PC)`) resolve with the toolchain's
own instruction counting and fold jump-to-jump chains exactly as its
branch optimiser does; symbol immediates (`MOVQ $sym(SB), AX`)
assemble to the toolchain's RIP-relative LEA with an R_PCREL
relocation; negated constant expressions in operands (`ADJSP
$-(REGS - 8)`, the shape the cgo ABI macros write) fold; the immediate
multiply (`IMULQ $1000000000, AX`) encodes with the toolchain's
0x69/0x6B selection; the TLS access pair assembles as the toolchain's
one-instruction form (the bare `MOVQ TLS, r` load nops out and
`off(r)(TLS*1)` folds to the segment-prefixed absolute whose disp32
carries the R_TLSLE relocation, per-GOOS); arm64 accepts the
bare-register indirect branch (`BL R9` beside `BL (R9)`, both BLR) and
the zero-immediate store (`MOVD $0, mem` through the zero register,
rejecting non-zero immediates as the toolchain does); `PCALIGN` now
aligns on amd64, padding with the toolchain's greedy
single-instruction NOPs; the segment-absolute forms (`MOVQ 0x30(GS),
AX` and the store direction) and the absolute crash-store
(`MOVL $0xf1, 0xf1`) encode; and `gasm asm` predefines the
`GOARCH_<arch>` and `GOOS_<goos>` macros the go command passes to
`go tool asm`, so GOROOT headers' `#ifdef GOARCH_amd64` platform
blocks (`go_tls.h`'s `get_tls` and friends) select as intended. The
GOROOT corpus measure moves to 291 of 353 files assembling for every
target architecture (82.4 %), 97.4 % of the real-code corpus, from
70.8 % and 82.2 %.
- **Tool corrections across the pipeline.** The formatter keeps square
brackets in SIMD operands, statement separators and canonical macro
bodies; the linter drops false positives on shift counts, SETcc
spellings and ABIInternal references; the lexer treats a trailing
carriage return as a line end so comment text stays idempotent; and
arm64 rejects bare BTI with a diagnostic while accepting the full
family.
## [0.34.0] - 2026-09-20 ## [0.34.0] - 2026-09-20
+9 -6
View File
@@ -81,7 +81,10 @@ to give that syntax the tooling it deserves.
GOOBJ format, which needs the installed toolchain and which `go build` GOOBJ format, which needs the installed toolchain and which `go build`
consumes in place of the toolchain's output. Framed functions get the consumes in place of the toolchain's output. Framed functions get the
stack-split guard and the morestack block, byte-identical to the stack-split guard and the morestack block, byte-identical to the
toolchain's, so split functions link too. toolchain's, so split functions link too. The assembler preprocesses
like the toolchain (`#define`, `#include` with `-I`, `#ifdef`), generates
`go_asm.h` from the package's Go files, and carries `PCALIGN`, the
`LOCK`/`REP` prefixes and the literal-data pseudo-ops.
- **Disassembler.** `gasm dis` lists a `.s` file's functions at their real - **Disassembler.** `gasm dis` lists a `.s` file's functions at their real
offsets after assembling, or disassembles raw bytes from a file or stdin. offsets after assembling, or disassembles raw bytes from a file or stdin.
- **Dynamic verification.** `gasm verify` JIT-loads assembled functions into - **Dynamic verification.** `gasm verify` JIT-loads assembled functions into
@@ -110,9 +113,9 @@ Four architectures, the four that matter in practice:
| Architecture | GOARCH | File suffix | Instructions recognised | | Architecture | GOARCH | File suffix | Instructions recognised |
|--------------|-------------|--------------|---------------------------------------------| |--------------|-------------|--------------|---------------------------------------------|
| AMD64 | `amd64` | `_amd64.s` | 1600 + common opcodes + traditional aliases | | AMD64 | `amd64` | `_amd64.s` | 1600 + common opcodes + traditional aliases |
| ARM64 | `arm64` | `_arm64.s` | 538 + common opcodes | | ARM64 | `arm64` | `_arm64.s` | 645 + common opcodes |
| RISC-V | `riscv64` | `_riscv64.s` | 961 + common opcodes | | RISC-V | `riscv64` | `_riscv64.s` | 992 + common opcodes |
| LoongArch | `loong64` | `_loong64.s` | 799 + common opcodes | | LoongArch | `loong64` | `_loong64.s` | 808 + common opcodes |
"Common opcodes" are the instructions shared by every architecture (`RET`, "Common opcodes" are the instructions shared by every architecture (`RET`,
`JMP`, `NOP`, `CALL`, `TEXT`, `FUNCDATA`, `PCDATA`, ...). AMD64 additionally `JMP`, `NOP`, `CALL`, `TEXT`, `FUNCDATA`, `PCDATA`, ...). AMD64 additionally
@@ -124,8 +127,8 @@ can emit today is narrower, and a recognised but unencodable instruction is
reported as an explicit error, never as a wrong byte. reported as an explicit error, never as a wrong byte.
The same measurement runs over GOROOT's whole assembly corpus: The same measurement runs over GOROOT's whole assembly corpus:
`gasm audit-instructions --corpus` reports 136 of 433 attemptable files `gasm audit-instructions --corpus` reports 291 of 353 attemptable files
(31.4 %) assembling for every target architecture today (files named for (82.4 %) assembling for every target architecture today (files named for
other Go ports are counted but never attempted), with the top failure other Go ports are counted but never attempted), with the top failure
reasons per architecture; the number moves with every release. reasons per architecture; the number moves with every release.
+14
View File
@@ -119,6 +119,20 @@ identifier is a register or a label is an *architecture* question, so it is
left to `arch` and resolved in the lint/lsp layers. This keeps the parser left to `arch` and resolved in the lint/lsp layers. This keeps the parser
arch-agnostic and its output deterministic. arch-agnostic and its output deterministic.
### Optional preprocessing
With `Options{Expand: true}` the parser runs a pre-parse pass
(`preproc.go`) that splices `#include` files (the source directory, then the
`-I` directories), expands object and parameterised `#define` macros,
applies `#undef` and the `#ifdef`/`#ifndef`/`#else`/`#endif` family, and
folds constant expressions left in operands. The go command's platform
macros (`GOARCH_<arch>`, `GOOS_<goos>`) arrive through `Options.Predefines`.
The assembly path (`asm`, `diff`, `audit`) expands; `lint`, `fmt` and the
language server read the raw file. The command layer adds the go_asm.h
generator (`asmhdr.go`): a file that includes go_asm.h gets the package's
defines type-checked out of its Go files for the target architecture and
GOOS, with no compiler in the loop.
### `arch` ### `arch`
Register files are generated programmatically (the regular `R8`-`R15`, Register files are generated programmatically (the regular `R8`-`R15`,