{"id":13601212,"url":"https://github.com/mmcloughlin/avo","last_synced_at":"2025-04-23T20:54:04.806Z","repository":{"id":34004087,"uuid":"156108485","full_name":"mmcloughlin/avo","owner":"mmcloughlin","description":"Generate x86 Assembly with Go","archived":false,"fork":false,"pushed_at":"2025-04-02T05:34:06.000Z","size":6946,"stargazers_count":2818,"open_issues_count":88,"forks_count":92,"subscribers_count":35,"default_branch":"master","last_synced_at":"2025-04-23T20:53:59.233Z","etag":null,"topics":["assembly","code-generation","go","golang","x86-64"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mmcloughlin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-11-04T17:44:21.000Z","updated_at":"2025-04-23T17:50:02.000Z","dependencies_parsed_at":"2023-10-02T06:58:41.096Z","dependency_job_id":"5a81adaf-0b39-471f-8382-61057c68756f","html_url":"https://github.com/mmcloughlin/avo","commit_stats":{"total_commits":442,"total_committers":9,"mean_commits":"49.111111111111114","dds":0.1357466063348416,"last_synced_commit":"9e39c75709a92b267b9c9394fbf5fba87194ffdc"},"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcloughlin%2Favo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcloughlin%2Favo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcloughlin%2Favo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mmcloughlin%2Favo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mmcloughlin","download_url":"https://codeload.github.com/mmcloughlin/avo/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250514767,"owners_count":21443208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assembly","code-generation","go","golang","x86-64"],"created_at":"2024-08-01T18:00:58.688Z","updated_at":"2025-04-23T20:54:04.786Z","avatar_url":"https://github.com/mmcloughlin.png","language":"Go","funding_links":[],"categories":["HarmonyOS","Go","开源类库","Assembly","Open source library","Tools"],"sub_categories":["Windows Manager","解释器","Interpreter"],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"logo.svg\" width=\"40%\" border=\"0\" alt=\"avo\" /\u003e\n  \u003cbr /\u003e\n  \u003cimg src=\"https://img.shields.io/github/actions/workflow/status/mmcloughlin/avo/ci.yml?style=flat-square\" alt=\"Build Status\" /\u003e\n  \u003ca href=\"https://pkg.go.dev/github.com/mmcloughlin/avo\"\u003e\u003cimg src=\"https://img.shields.io/badge/doc-reference-007d9b?logo=go\u0026style=flat-square\" alt=\"go.dev\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://goreportcard.com/report/github.com/mmcloughlin/avo\"\u003e\u003cimg src=\"https://goreportcard.com/badge/github.com/mmcloughlin/avo?style=flat-square\" alt=\"Go Report Card\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003eGenerate x86 Assembly with Go\u003c/p\u003e\n\n`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:\n\n* **Use Go control structures** for assembly generation; `avo` programs _are_ Go programs\n* **Register allocation**: write functions with virtual registers and `avo` assigns physical registers for you\n* **Automatically load arguments and store return values**: ensure memory offsets are correct for complex structures\n* **Generation of stub files** to interface with your Go package\n\nFor more about `avo`:\n\n* Introductory talk [\"Better `x86` Assembly Generation with Go\"](https://www.youtube.com/watch?v=6Y5CZ7_tyA4) at [dotGo 2019](https://2019.dotgo.eu/) ([slides](https://speakerdeck.com/mmcloughlin/better-x86-assembly-generation-with-go))\n* [Longer tutorial at Gophercon 2019](https://www.youtube.com/watch?v=WaD8sNqroAw) showing a highly-optimized dot product ([slides](https://speakerdeck.com/mmcloughlin/better-x86-assembly-generation-with-go-gophercon-2019))\n* Watch [Filippo Valsorda](https://filippo.io/) live code the [rewrite of `filippo.io/edwards25519` assembly with `avo`](https://vimeo.com/679848853)\n* Explore [projects using `avo`](doc/adopters.md)\n* Discuss `avo` and general Go assembly topics in the [#assembly](https://gophers.slack.com/archives/C6WDZJ70S) channel of [Gophers Slack](https://invite.slack.golangbridge.org/)\n\n_Note: APIs subject to change while `avo` is still in an experimental phase. You can use it to build [real things](examples) but we suggest you pin a version with your package manager of choice._\n\n## Quick Start\n\nInstall `avo` with `go get`:\n\n```\n$ go get -u github.com/mmcloughlin/avo\n```\n\n`avo` assembly generators are pure Go programs. Here's a function that adds two `uint64` values:\n\n```go\n//go:build ignore\n\npackage main\n\nimport . \"github.com/mmcloughlin/avo/build\"\n\nfunc main() {\n\tTEXT(\"Add\", NOSPLIT, \"func(x, y uint64) uint64\")\n\tDoc(\"Add adds x and y.\")\n\tx := Load(Param(\"x\"), GP64())\n\ty := Load(Param(\"y\"), GP64())\n\tADDQ(x, y)\n\tStore(y, ReturnIndex(0))\n\tRET()\n\tGenerate()\n}\n```\n\n`go run` this code to see the assembly output. To integrate this into the rest of your Go package we recommend a [`go:generate`](https://blog.golang.org/generate) line to produce the assembly and the corresponding Go stub file.\n\n```go\n//go:generate go run asm.go -out add.s -stubs stub.go\n```\n\nAfter running `go generate` the [`add.s`](examples/add/add.s) file will contain the Go assembly.\n\n```s\n// Code generated by command: go run asm.go -out add.s -stubs stub.go. DO NOT EDIT.\n\n#include \"textflag.h\"\n\n// func Add(x uint64, y uint64) uint64\nTEXT ·Add(SB), NOSPLIT, $0-24\n\tMOVQ x+0(FP), AX\n\tMOVQ y+8(FP), CX\n\tADDQ AX, CX\n\tMOVQ CX, ret+16(FP)\n\tRET\n```\n\nThe same call will produce the stub file [`stub.go`](examples/add/stub.go) which will enable the function to be called from your Go code.\n\n```go\n// Code generated by command: go run asm.go -out add.s -stubs stub.go. DO NOT EDIT.\n\npackage add\n\n// Add adds x and y.\nfunc Add(x uint64, y uint64) uint64\n```\n\nSee the [`examples/add`](examples/add) directory for the complete working example.\n\n## Examples\n\nSee [`examples`](examples) for the full suite of examples.\n\n### Slice Sum\n\nSum a slice of `uint64`s:\n\n```go\nfunc main() {\n\tTEXT(\"Sum\", NOSPLIT, \"func(xs []uint64) uint64\")\n\tDoc(\"Sum returns the sum of the elements in xs.\")\n\tptr := Load(Param(\"xs\").Base(), GP64())\n\tn := Load(Param(\"xs\").Len(), GP64())\n\n\tComment(\"Initialize sum register to zero.\")\n\ts := GP64()\n\tXORQ(s, s)\n\n\tLabel(\"loop\")\n\tComment(\"Loop until zero bytes remain.\")\n\tCMPQ(n, Imm(0))\n\tJE(LabelRef(\"done\"))\n\n\tComment(\"Load from pointer and add to running sum.\")\n\tADDQ(Mem{Base: ptr}, s)\n\n\tComment(\"Advance pointer, decrement byte count.\")\n\tADDQ(Imm(8), ptr)\n\tDECQ(n)\n\tJMP(LabelRef(\"loop\"))\n\n\tLabel(\"done\")\n\tComment(\"Store sum to return value.\")\n\tStore(s, ReturnIndex(0))\n\tRET()\n\tGenerate()\n}\n```\n\nThe result from this code generator is:\n\n```s\n// Code generated by command: go run asm.go -out sum.s -stubs stub.go. DO NOT EDIT.\n\n#include \"textflag.h\"\n\n// func Sum(xs []uint64) uint64\nTEXT ·Sum(SB), NOSPLIT, $0-32\n\tMOVQ xs_base+0(FP), AX\n\tMOVQ xs_len+8(FP), CX\n\n\t// Initialize sum register to zero.\n\tXORQ DX, DX\n\nloop:\n\t// Loop until zero bytes remain.\n\tCMPQ CX, $0x00\n\tJE   done\n\n\t// Load from pointer and add to running sum.\n\tADDQ (AX), DX\n\n\t// Advance pointer, decrement byte count.\n\tADDQ $0x08, AX\n\tDECQ CX\n\tJMP  loop\n\ndone:\n\t// Store sum to return value.\n\tMOVQ DX, ret+24(FP)\n\tRET\n```\n\nFull example at [`examples/sum`](examples/sum).\n\n### Features\n\nFor demonstrations of `avo` features:\n\n* **[args](examples/args):** Loading function arguments.\n* **[returns](examples/returns):** Building return values.\n* **[complex](examples/complex):** Working with `complex{64,128}` types.\n* **[data](examples/data):** Defining `DATA` sections.\n* **[ext](examples/ext):** Interacting with types from external packages.\n* **[pragma](examples/pragma):** Apply compiler directives to generated functions.\n\n### Real Examples\n\nImplementations of full algorithms:\n\n* **[sha1](examples/sha1):** [SHA-1](https://en.wikipedia.org/wiki/SHA-1) cryptographic hash.\n* **[fnv1a](examples/fnv1a):** [FNV-1a](https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV-1a_hash) hash function.\n* **[dot](examples/dot):** Vector dot product.\n* **[md5x16](examples/md5x16):** AVX-512 accelerated [MD5](https://en.wikipedia.org/wiki/MD5).\n* **[geohash](examples/geohash):** Integer [geohash](https://en.wikipedia.org/wiki/Geohash) encoding.\n* **[stadtx](examples/stadtx):** [`StadtX` hash](https://github.com/demerphq/BeagleHash) port from [dgryski/go-stadtx](https://github.com/dgryski/go-stadtx).\n\n## Adopters\n\nPopular projects[^projects] using `avo`:\n\n[^projects]: Projects drawn from the `avo` third-party test suite. Popularity\nestimated from Github star count collected on Apr 1, 2025.\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fgolang.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [golang / **go**](https://github.com/golang/go)\n:star: 126.9k\n\u003e The Go programming language\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fklauspost.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [klauspost / **compress**](https://github.com/klauspost/compress)\n:star: 5k\n\u003e Optimized Go Compression Packages\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fgolang.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [golang / **crypto**](https://github.com/golang/crypto)\n:star: 3.1k\n\u003e [mirror] Go supplementary cryptography libraries\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fklauspost.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [klauspost / **reedsolomon**](https://github.com/klauspost/reedsolomon)\n:star: 1.9k\n\u003e Reed-Solomon Erasure Coding in Go\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fbytedance.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [bytedance / **gopkg**](https://github.com/bytedance/gopkg)\n:star: 1.8k\n\u003e Universal Utilities for Go\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fcloudflare.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [cloudflare / **circl**](https://github.com/cloudflare/circl)\n:star: 1.4k\n\u003e CIRCL: Cloudflare Interoperable Reusable Cryptographic Library\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fsegmentio.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [segmentio / **asm**](https://github.com/segmentio/asm)\n:star: 885\n\u003e Go library providing algorithms optimized to leverage the characteristics of modern CPUs\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fzeebo.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [zeebo / **xxh3**](https://github.com/zeebo/xxh3)\n:star: 443\n\u003e XXH3 algorithm in Go\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Fzeebo.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [zeebo / **blake3**](https://github.com/zeebo/blake3)\n:star: 415\n\u003e Pure Go implementation of BLAKE3 with AVX2 and SSE4.1 acceleration\n\n\u003cimg src=\"https://images.weserv.nl?fit=cover\u0026h=24\u0026mask=circle\u0026maxage=7d\u0026url=https%3A%2F%2Fgithub.com%2Flukechampine.png\u0026w=24\" width=\"24\" height=\"24\" hspace=\"4\" valign=\"middle\" /\u003e [lukechampine / **blake3**](https://github.com/lukechampine/blake3)\n:star: 378\n\u003e An AVX-512 accelerated implementation of the BLAKE3 cryptographic hash function\n\nSee the [full list of projects using `avo`](doc/adopters.md).\n\n## Contributing\n\nContributions to `avo` are welcome:\n\n* Feedback from using `avo` in a real project is incredibly valuable. Consider [porting an existing project to `avo`](https://github.com/mmcloughlin/avo/issues/40).\n* [Submit bug reports](https://github.com/mmcloughlin/avo/issues/new) to the issues page.\n* Pull requests accepted. Take a look at outstanding [issues](https://github.com/mmcloughlin/avo/issues) for ideas (especially the [\"good first issue\"](https://github.com/mmcloughlin/avo/labels/good%20first%20issue) label).\n* Join us in the [#assembly](https://gophers.slack.com/archives/C6WDZJ70S) channel of [Gophers Slack](https://invite.slack.golangbridge.org/).\n\n## Credits\n\nInspired by the [PeachPy](https://github.com/Maratyszcza/PeachPy) and [asmjit](https://github.com/asmjit/asmjit) projects. Thanks to [Damian Gryski](https://github.com/dgryski) for advice, and his [extensive library of PeachPy Go projects](https://github.com/mmcloughlin/avo/issues/40).\n\n## License\n\n`avo` is available under the [BSD 3-Clause License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmcloughlin%2Favo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmmcloughlin%2Favo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmmcloughlin%2Favo/lists"}