8000 GitHub - dominikh/avo: Generate x86 Assembly with Go · GitHub
[go: up one dir, main page]

Skip to content
  • dominikhPublic
    forked from mmcloughlin/avo

    About

    Generate x86 Assembly with Go

    Resources

    Contributing

    Stars

    0 stars

    Watchers

    0 watching

    Forks

     
     

    Latest commit

     

    History

    521 Commits

    Folders and files

    Repository files navigation

    This is a personal fork of Avo. You probably don't want to depend on this.

    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 honnef.co/go/avo
    

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

    //go:build ignore
    
    package main
    
    import . "honnef.co/go/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 8000 generated functions.

    Real Examples

    Implementations of full algorithms:

    Adopters

    Popular projects1 using avo:

    golang / go ⭐ 132.2k

    The Go programming language

    klauspost / compress ⭐ 5.4k

    Optimized Go Compression Packages

    golang / crypto ⭐ 3.3k

    [mirror] Go supplementary cryptography libraries

    klauspost / reedsolomon ⭐ 2k

    Reed-Solomon Erasure Coding in Go

    bytedance / gopkg ⭐ 2k

    Universal Utilities for Go

    cloudflare / circl ⭐ 1.6k

    CIRCL: Cloudflare Interoperable Reusable Cryptographic Library

    segmentio / asm ⭐ 910

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

    zeebo / xxh3 ⭐ 523

    XXH3 algorithm in Go

    zeebo / blake3 ⭐ 458

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

    lukechampine / blake3 ⭐ 410

    An AVX-512 accelerated implementation of the BLAKE3 cryptographic hash function

    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.

    Footnotes

    1. Projects drawn from the avo third-party test suite. Popularity estimated from Github star count collected on Feb 1, 2026. ↩

    About

    Generate x86 Assembly with Go

    Resources

    Contributing

    Stars

    0 stars

    Watchers

    0 watching

    Forks

    Releases

    Packages

    Contributors

    Languages

    0