From 2a27a3a52b16b2c12f8eb23fcac0241d43425424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Balv=C3=ADn?= Date: Fri, 7 Aug 2026 22:43:40 +0200 Subject: [PATCH] docs: add BSD-3-Clause headers to generated files and update CI docs --- CONTRIBUTING.md | 11 +++++++-- _gen/gen.go | 10 +++++++-- arch/amd64_gen.go | 3 +++ arch/arm64_gen.go | 3 +++ arch/common_gen.go | 3 +++ arch/loong64_gen.go | 3 +++ arch/riscv_gen.go | 3 +++ asm/arm64_assemble.go | 23 +++++++++++++++++++ asm/loong64_assemble.go | 23 +++++++++++++++++++ cmd/gasm/main.go | 49 ++++++++++++++++++++++------------------- 10 files changed, 104 insertions(+), 27 deletions(-) create mode 100644 asm/arm64_assemble.go create mode 100644 asm/loong64_assemble.go diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cef57bb..1f02cc5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -68,8 +68,15 @@ See [AGENTS.md](AGENTS.md) for the full style guide. Key points: ## CI -There is no CI pipeline in this repository. The Definition of Done -(`just build` + `just test` + `just fmt`) is enforced locally. +CI runs on every push to `development` and on pull requests: + +- **Test** (`test.yml`) — `gofmt` check, `go vet`, `go test -race` and the + 80 % coverage gate. +- **Release** (`release.yml`) — cross-compiles release binaries for + linux/{amd64,arm64,riscv64,loong64} on version tags and publishes them. + +The Definition of Done (`just build` + `just test` + `just fmt`) must still +pass locally before pushing. ## AI-Assisted Contributions diff --git a/_gen/gen.go b/_gen/gen.go index 5d91458..f7f0b33 100644 --- a/_gen/gen.go +++ b/_gen/gen.go @@ -86,7 +86,10 @@ func filterCommon(names []string) []string { func writeCommon(names []string) error { var b strings.Builder b.WriteString("// Code generated by gasm-devkit _gen; DO NOT EDIT.\n") - b.WriteString("// Source: cmd/internal/obj/util.go from the Go toolchain.\n\n") + b.WriteString("// Source: cmd/internal/obj/util.go from the Go toolchain.\n") + b.WriteString("//\n") + b.WriteString("// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)\n") + b.WriteString("// SPDX-License-Identifier: BSD-3-Clause\n\n") b.WriteString("package arch\n\n") b.WriteString("// commonGeneratedInstrs is the set of opcodes shared by every architecture\n") b.WriteString("// (RET, JMP, NOP, CALL, TEXT, FUNCDATA, PCDATA, …).\n") @@ -154,7 +157,10 @@ func stringLit(elt ast.Expr) string { func writeGen(arch, sub string, names []string) error { var b strings.Builder b.WriteString("// Code generated by gasm-devkit _gen; DO NOT EDIT.\n") - b.WriteString("// Source: cmd/internal/obj/" + sub + "/anames.go from the Go toolchain.\n\n") + b.WriteString("// Source: cmd/internal/obj/" + sub + "/anames.go from the Go toolchain.\n") + b.WriteString("//\n") + b.WriteString("// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org)\n") + b.WriteString("// SPDX-License-Identifier: BSD-3-Clause\n\n") b.WriteString("package arch\n\n") b.WriteString("// " + arch + "GeneratedInstrs is the complete set of " + arch + " mnemonics accepted by\n// Go's Plan 9 assembler.\n") diff --git a/arch/amd64_gen.go b/arch/amd64_gen.go index d394752..88c4716 100644 --- a/arch/amd64_gen.go +++ b/arch/amd64_gen.go @@ -1,5 +1,8 @@ // Code generated by gasm-devkit _gen; DO NOT EDIT. // Source: cmd/internal/obj/x86/anames.go from the Go toolchain. +// +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause package arch diff --git a/arch/arm64_gen.go b/arch/arm64_gen.go index 97ec0eb..89108e7 100644 --- a/arch/arm64_gen.go +++ b/arch/arm64_gen.go @@ -1,5 +1,8 @@ // Code generated by gasm-devkit _gen; DO NOT EDIT. // Source: cmd/internal/obj/arm64/anames.go from the Go toolchain. +// +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause package arch diff --git a/arch/common_gen.go b/arch/common_gen.go index 57a35c6..78a0e2d 100644 --- a/arch/common_gen.go +++ b/arch/common_gen.go @@ -1,5 +1,8 @@ // Code generated by gasm-devkit _gen; DO NOT EDIT. // Source: cmd/internal/obj/util.go from the Go toolchain. +// +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause package arch diff --git a/arch/loong64_gen.go b/arch/loong64_gen.go index bd4ef59..4aedc82 100644 --- a/arch/loong64_gen.go +++ b/arch/loong64_gen.go @@ -1,5 +1,8 @@ // Code generated by gasm-devkit _gen; DO NOT EDIT. // Source: cmd/internal/obj/loong64/anames.go from the Go toolchain. +// +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause package arch diff --git a/arch/riscv_gen.go b/arch/riscv_gen.go index 94b7603..ff43613 100644 --- a/arch/riscv_gen.go +++ b/arch/riscv_gen.go @@ -1,5 +1,8 @@ // Code generated by gasm-devkit _gen; DO NOT EDIT. // Source: cmd/internal/obj/riscv/anames.go from the Go toolchain. +// +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause package arch diff --git a/asm/arm64_assemble.go b/asm/arm64_assemble.go new file mode 100644 index 0000000..9774ac0 --- /dev/null +++ b/asm/arm64_assemble.go @@ -0,0 +1,23 @@ +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause + +package asm + +import ( + "fmt" + + "sourcedock.dev/petrbalvin/gasm-devkit/ast" +) + +// assembleARM64 is a stub. The arm64 (AArch64) instruction encoder is not yet +// implemented — the instruction tables, register files and operand-count +// metadata are in place (package arch), and the lexer, parser, formatter and +// linter already handle arm64 source files. +func assembleARM64(t *ast.Text) ([]byte, map[string]int, []Reloc, error) { + return nil, nil, nil, fmt.Errorf("arm64 instruction encoding is not yet implemented") +} + +// AssembleFileARM64 is a stub, returning the same error as assembleARM64. +func AssembleFileARM64(f *ast.File) (*Image, error) { + return nil, fmt.Errorf("arm64 instruction encoding is not yet implemented") +} diff --git a/asm/loong64_assemble.go b/asm/loong64_assemble.go new file mode 100644 index 0000000..f5d6f8e --- /dev/null +++ b/asm/loong64_assemble.go @@ -0,0 +1,23 @@ +// Copyright (c) 2026 Petr Balvín (https://petrbalvin.org) +// SPDX-License-Identifier: BSD-3-Clause + +package asm + +import ( + "fmt" + + "sourcedock.dev/petrbalvin/gasm-devkit/ast" +) + +// assembleLOONG64 is a stub. The loong64 (LoongArch) instruction encoder is +// not yet implemented — the instruction tables, register files and operand-count +// metadata are in place (package arch), and the lexer, parser, formatter and +// linter already handle loong64 source files. +func assembleLOONG64(t *ast.Text) ([]byte, map[string]int, []Reloc, error) { + return nil, nil, nil, fmt.Errorf("loong64 instruction encoding is not yet implemented") +} + +// AssembleFileLOONG64 is a stub, returning the same error as assembleLOONG64. +func AssembleFileLOONG64(f *ast.File) (*Image, error) { + return nil, fmt.Errorf("loong64 instruction encoding is not yet implemented") +} diff --git a/cmd/gasm/main.go b/cmd/gasm/main.go index ff14d08..737f0d3 100644 --- a/cmd/gasm/main.go +++ b/cmd/gasm/main.go @@ -396,10 +396,10 @@ hover, document symbols, diagnostics and semantic-token highlighting. func cmdAsm(args []string) int { fs := newCommand("asm", "gasm asm [--format raw|elf|goobj] [-p pkg] [-o out] ", ` -Assemble FILE (amd64 or riscv64) without the Go toolchain: every TEXT function is -encoded to machine code — scalar, VEX/AVX2 and EVEX/AVX-512 instructions, -FP/SP frame mapping, local labels and file-local static symbols (GLOBL/DATA) -resolved RIP-relative — and printed as a hex dump. + Assemble FILE without the Go toolchain: every TEXT function is encoded to + machine code and printed as a hex dump. Supported architectures: amd64 + (including VEX/AVX2 and EVEX/AVX-512) and riscv64 (RV64IMAFDC + RVC); + arm64 and loong64 encoding is not yet implemented. With -o the output is written to a file instead. The --format flag selects what is written: raw (the default) concatenates the functions and the data @@ -419,10 +419,6 @@ requires -p, the package path, and the installed Go toolchain). } path := fs.Arg(0) targetArch := arch.FromFilename(path) - if targetArch != arch.AMD64 && targetArch != arch.RISCV { - fmt.Fprintln(os.Stderr, "gasm asm: only amd64 and riscv64 are supported") - return 1 - } src, err := readSource(path) if err != nil { fmt.Fprintln(os.Stderr, "gasm:", err) @@ -436,12 +432,7 @@ requires -p, the package path, and the installed Go toolchain). return 1 } - var img *asm.Image - if targetArch == arch.RISCV { - img, err = asm.AssembleFileRISCV(f) - } else { - img, err = asm.AssembleFile(f) - } + img, err := assembleFile(path, targetArch, f) if err != nil { fmt.Fprintf(os.Stderr, "%s: %v\n", path, err) return 1 @@ -565,12 +556,12 @@ e.g. --map wideCopyAVX2=wideCopyAVX512 pairs the two regardless of suffix. } // Assemble both files. - img1, err := assembleFile(path1) + img1, err := assemblePath(path1) if err != nil { fmt.Fprintf(os.Stderr, "gasm diff: %s: %v\n", path1, err) return 1 } - img2, err := assembleFile(path2) + img2, err := assemblePath(path2) if err != nil { fmt.Fprintf(os.Stderr, "gasm diff: %s: %v\n", path2, err) return 1 @@ -629,8 +620,24 @@ e.g. --map wideCopyAVX2=wideCopyAVX512 pairs the two regardless of suffix. return 1 } -// assembleFile assembles a file and returns the image. -func assembleFile(path string) (*asm.Image, error) { +// assembleFile assembles a parsed file for the given architecture and returns the image. +func assembleFile(path string, targetArch arch.Arch, f *ast.File) (*asm.Image, error) { + switch targetArch { + case arch.AMD64: + return asm.AssembleFile(f) + case arch.RISCV: + return asm.AssembleFileRISCV(f) + case arch.ARM64: + return asm.AssembleFileARM64(f) + case arch.LOONG64: + return asm.AssembleFileLOONG64(f) + default: + return nil, fmt.Errorf("unsupported architecture %q", targetArch) + } +} + +// assemblePath reads, parses and assembles a file (used by cmdDiff). +func assemblePath(path string) (*asm.Image, error) { src, err := readSource(path) if err != nil { return nil, err @@ -642,11 +649,7 @@ func assembleFile(path string) (*asm.Image, error) { if len(errs) > 0 { return nil, fmt.Errorf("parse errors") } - targetArch := arch.FromFilename(path) - if targetArch == arch.RISCV { - return asm.AssembleFileRISCV(f) - } - return asm.AssembleFile(f) + return assembleFile(path, arch.FromFilename(path), f) } // printByteDiff shows the first few byte differences between two code blocks.