avo

package module
v0.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 7, 2024 License: BSD-3-Clause Imports: 0 Imported by: 0

README

avo
Build Status go.dev Go Report Card

Generate x86 Assembly with Go

avo makes high-performance Go assembly easier to write, review and maintain. The avo package presents a familiar assembly-like interface that simplifies development without sacrificing performance:

  • Use Go control structures for assembly generation; avo programs are Go programs
  • Register allocation: write functions with virtual registers and avo assigns physical registers for you
  • Automatically load arguments and store return values: ensure memory offsets are correct for complex structures
  • Generation of stub files to interface with your Go package

For more about avo:

Note: APIs subject to change while avo is still in an experimental phase. You can use it to build real things but we suggest you pin a version with your package manager of choice.

Quick Start

Install avo with go get:

$ go get -u github.com/mmcloughlin/avo

avo assembly generators are pure Go programs. Here's a function that adds two uint64 values:

//go:build ignore

package main

import . "github.com/mmcloughlin/avo/build"

func main() {
	TEXT("Add", NOSPLIT, "func(x, y uint64) uint64")
	Doc("Add adds x and y.")
	x := Load(Param("x"), GP64())
	y := Load(Param("y"), GP64())
	ADDQ(x, y)
	Store(y, ReturnIndex(0))
	RET()
	Generate()
}

go run this code to see the assembly output. To integrate this into the rest of your Go package we recommend a go:generate line to produce the assembly and the corresponding Go stub file.

//go:generate go run asm.go -out add.s -stubs stub.go

After running go generate the add.s file will contain the Go assembly.

// Code generated by command: go run asm.go -out add.s -stubs stub.go. DO NOT EDIT.

#include "textflag.h"

// func Add(x uint64, y uint64) uint64
TEXT ·Add(SB), NOSPLIT, $0-24
	MOVQ x+0(FP), AX
	MOVQ y+8(FP), CX
	ADDQ AX, CX
	MOVQ CX, ret+16(FP)
	RET

The same call will produce the stub file stub.go which will enable the function to be called from your Go code.

// Code generated by command: go run asm.go -out add.s -stubs stub.go. DO NOT EDIT.

package add

// Add adds x and y.
func Add(x uint64, y uint64) uint64

See the examples/add directory for the complete working example.

Examples

See examples for the full suite of examples.

Slice Sum

Sum a slice of uint64s:

func main() {
	TEXT("Sum", NOSPLIT, "func(xs []uint64) uint64")
	Doc("Sum returns the sum of the elements in xs.")
	ptr := Load(Param("xs").Base(), GP64())
	n := Load(Param("xs").Len(), GP64())

	Comment("Initialize sum register to zero.")
	s := GP64()
	XORQ(s, s)

	Label("loop")
	Comment("Loop until zero bytes remain.")
	CMPQ(n, Imm(0))
	JE(LabelRef("done"))

	Comment("Load from pointer and add to running sum.")
	ADDQ(Mem{Base: ptr}, s)

	Comment("Advance pointer, decrement byte count.")
	ADDQ(Imm(8), ptr)
	DECQ(n)
	JMP(LabelRef("loop"))

	Label("done")
	Comment("Store sum to return value.")
	Store(s, ReturnIndex(0))
	RET()
	Generate()
}

The result from this code generator is:

// Code generated by command: go run asm.go -out sum.s -stubs stub.go. DO NOT EDIT.

#include "textflag.h"

// func Sum(xs []uint64) uint64
TEXT ·Sum(SB), NOSPLIT, $0-32
	MOVQ xs_base+0(FP), AX
	MOVQ xs_len+8(FP), CX

	// Initialize sum register to zero.
	XORQ DX, DX

loop:
	// Loop until zero bytes remain.
	CMPQ CX, $0x00
	JE   done

	// Load from pointer and add to running sum.
	ADDQ (AX), DX

	// Advance pointer, decrement byte count.
	ADDQ $0x08, AX
	DECQ CX
	JMP  loop

done:
	// Store sum to return value.
	MOVQ DX, ret+24(FP)
	RET

Full example at examples/sum.

Features

For demonstrations of avo features:

  • args: Loading function arguments.
  • returns: Building return values.
  • complex: Working with complex{64,128} types.
  • data: Defining DATA sections.
  • ext: Interacting with types from external packages.
  • pragma: Apply compiler directives to generated functions.

Real Examples

Implementations of full algorithms:

Adopters

Popular projects[^projects] using avo:

[^projects]: Projects drawn from the avo third-party test suite. Popularity estimated from Github star count collected on Jan 1, 2024.

golang / go ⭐ 116.7k

The Go programming language

klauspost / compress ⭐ 4.3k

Optimized Go Compression Packages

golang / crypto ⭐ 2.9k

[mirror] Go supplementary cryptography libraries

klauspost / reedsolomon ⭐ 1.8k

Reed-Solomon Erasure Coding in Go

cloudflare / circl ⭐ 1.1k

CIRCL: Cloudflare Interoperable Reusable Cryptographic Library

segmentio / asm ⭐ 820

Go library providing algorithms optimized to leverage the characteristics of modern CPUs

zeebo / xxh3 ⭐ 358

XXH3 algorithm in Go

zeebo / blake3 ⭐ 353

Pure Go implementation of BLAKE3 with AVX2 and SSE4.1 acceleration

lukechampine / blake3 ⭐ 316

A pure-Go implementation of the BLAKE3 cryptographic hash function

minio / md5-simd ⭐ 159

Accelerate aggregated MD5 hashing performance up to 8x for AVX512 and 4x for AVX2. Useful for server applications that need to compute many MD5 sums in parallel.

See the full list of projects using avo.

Contributing

Contributions to avo are welcome:

Credits

Inspired by the PeachPy and asmjit projects. Thanks to Damian Gryski for advice, and his extensive library of PeachPy Go projects.

License

avo is available under the BSD 3-Clause License.

Documentation

Overview

Package avo is a high-level x86 assembly generator.

Directories

Path Synopsis
Package attr provides attributes for text and data sections.
Package attr provides attributes for text and data sections.
Package build provides an assembly-like interface for incremental building of avo Files.
Package build provides an assembly-like interface for incremental building of avo Files.
Package buildtags provides types for representing and manipulating build constraints.
Package buildtags provides types for representing and manipulating build constraints.
Package examples provides examples of avo usage.
Package examples provides examples of avo usage.
add
Package add demonstrates an Add function in avo.
Package add demonstrates an Add function in avo.
args
Package args demonstrates how to load function arguments in avo.
Package args demonstrates how to load function arguments in avo.
complex
Package complex shows how to work with complex types in avo.
Package complex shows how to work with complex types in avo.
data
Package data shows how to define DATA sections in avo.
Package data shows how to define DATA sections in avo.
dot
Package dot implements vector dot product in avo.
Package dot implements vector dot product in avo.
ext
Package ext demonstrates how to interact with external types.
Package ext demonstrates how to interact with external types.
ext/ext
Package ext is used as a target package in the external types example.
Package ext is used as a target package in the external types example.
fnv1a
Package fnv1a implements FNV-1a in avo.
Package fnv1a implements FNV-1a in avo.
geohash
Package geohash implements integer geohash encoding in avo.
Package geohash implements integer geohash encoding in avo.
md5x16
Package md5x16 implements 16-lane parallel MD5 with AVX-512 instructions.
Package md5x16 implements 16-lane parallel MD5 with AVX-512 instructions.
pragma
Package pragma demonstrates the use of compiler directives.
Package pragma demonstrates the use of compiler directives.
returns
Package returns demonstrates how to write function return values in avo.
Package returns demonstrates how to write function return values in avo.
sha1
Package sha1 implements the SHA-1 hash in avo.
Package sha1 implements the SHA-1 hash in avo.
stadtx
Package stadtx implements Stadtx Hash
Package stadtx implements Stadtx Hash
sum
Package sum sums a slice in avo.
Package sum sums a slice in avo.
Package gotypes provides helpers for interacting with Go types within avo functions.
Package gotypes provides helpers for interacting with Go types within avo functions.
internal
api
Package api determines the API of avo instruction constructors.
Package api determines the API of avo instruction constructors.
cmd/asmvet
Command asmvet checks for correctness of Go assembly.
Command asmvet checks for correctness of Go assembly.
cmd/avogen
Command avogen generates code based on the instruction database.
Command avogen generates code based on the instruction database.
cmd/docgen
Command docgen generates documentation from templates.
Command docgen generates documentation from templates.
gen
Package gen provides code generators based on the instruction database.
Package gen provides code generators based on the instruction database.
github
Package github provides a client for the Github REST API.
Package github provides a client for the Github REST API.
inst
Package inst is the avo instruction database.
Package inst is the avo instruction database.
load
Package load loads the instruction database from external sources.
Package load loads the instruction database from external sources.
opcodescsv
Package opcodescsv extracts data from the Go x86.csv database.
Package opcodescsv extracts data from the Go x86.csv database.
opcodesextra
Package opcodesextra provides curated extensions to the instruction database.
Package opcodesextra provides curated extensions to the instruction database.
opcodesxml
Package opcodesxml is a reader for the Opcodes XML database.
Package opcodesxml is a reader for the Opcodes XML database.
prnt
Package prnt provides common functionality for code generators.
Package prnt provides common functionality for code generators.
stack
Package stack provides helpers for querying the callstack.
Package stack provides helpers for querying the callstack.
test
Package test provides testing utilities.
Package test provides testing utilities.
Package ir provides the intermediate representation of avo programs.
Package ir provides the intermediate representation of avo programs.
Package operand provides types for instruction operands.
Package operand provides types for instruction operands.
Package pass implements processing passes on avo Files.
Package pass implements processing passes on avo Files.
Package printer implements printing of avo files in various formats.
Package printer implements printing of avo files in various formats.
Package reg provides types for physical and virtual registers, and definitions of x86-64 register families.
Package reg provides types for physical and virtual registers, and definitions of x86-64 register families.
Package src provides types for working with source files.
Package src provides types for working with source files.
Package tests contains avo integration tests.
Package tests contains avo integration tests.
alloc/gp8
Package gp8 tests the register allocator by using as many 8-bit registers as possible.
Package gp8 tests the register allocator by using as many 8-bit registers as possible.
alloc/masks
Package masks tests that register liveness and allocation passes handle masks correctly.
Package masks tests that register liveness and allocation passes handle masks correctly.
alloc/upper32
Package upper32 tests liveness analysis of 32-bit operations on 64-bit registers.
Package upper32 tests liveness analysis of 32-bit operations on 64-bit registers.
alloc/zeroing
Package zeroing tests liveness analysis of AVX-512 operations with zeroing masking.
Package zeroing tests liveness analysis of AVX-512 operations with zeroing masking.
cast
Package cast tests casting virtual registers to different sizes.
Package cast tests casting virtual registers to different sizes.
fixedbugs/issue100/allocfail
Package allocfail is a regression test for issue 100 based on the original reported allocation failure.
Package allocfail is a regression test for issue 100 based on the original reported allocation failure.
fixedbugs/issue100/minrepro
Package minrepro contains a minimal reproducer for the aliased register allocation bug in issue 100.
Package minrepro contains a minimal reproducer for the aliased register allocation bug in issue 100.
fixedbugs/issue122
Package issue122 tests consecutive labels.
Package issue122 tests consecutive labels.
fixedbugs/issue191
Package issue191 tests for correct argument size for a function taking a single uint16 argument.
Package issue191 tests for correct argument size for a function taking a single uint16 argument.
fixedbugs/issue195
Package issue195 tests for correct argument size for a function without return types.
Package issue195 tests for correct argument size for a function without return types.
fixedbugs/issue336
Package issue336 tests boolean arguments and return values.
Package issue336 tests boolean arguments and return values.
fixedbugs/issue387
Package issue387 tests representation of floating point data with integer values.
Package issue387 tests representation of floating point data with integer values.
fixedbugs/issue50
Package issue50 tests for 32-bit MOVD/MOVQ instruction forms.
Package issue50 tests for 32-bit MOVD/MOVQ instruction forms.
fixedbugs/issue62
Package issue62 tests for using Implement() with an unexported function.
Package issue62 tests for using Implement() with an unexported function.
fixedbugs/issue65
Package issue65 is a regression test for a bug involving casting physical registers.
Package issue65 is a regression test for a bug involving casting physical registers.
fixedbugs/issue68
Package custom tests overriding package name with the CLI.
Package custom tests overriding package name with the CLI.
fixedbugs/issue76
Package issue76 deliberately produces redundant MOV instructions.
Package issue76 deliberately produces redundant MOV instructions.
fixedbugs/issue89
Package issue89 tests register allocation with self-cancelling inputs.
Package issue89 tests register allocation with self-cancelling inputs.
fmt
Package fmt tests assembly printer formatting.
Package fmt tests assembly printer formatting.
labels
Package labels tests for cleanup of redundant labels.
Package labels tests for cleanup of redundant labels.
signature
Package signature tests handling of random function signatures.
Package signature tests handling of random function signatures.
textflag
Package textflag tests that avo attribute constants agree with textflag.h.
Package textflag tests that avo attribute constants agree with textflag.h.
thirdparty
Package thirdparty executes integration tests based on third-party projects that use avo.
Package thirdparty executes integration tests based on third-party projects that use avo.
Package x86 provides constructors for all x86-64 instructions.
Package x86 provides constructors for all x86-64 instructions.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL