Reputation: 22154
I have a function written on Go that I would like to optimize in assembly. I currently only want to write it for amd64 which is the most frequent target. Assembly for other targets may be added later. By default it should use the Go code.
Unfortunately I didn't manage to achieve this. Looking at the documentation I found online it seam that I have to declare an external function, and provide the assembly for every possible target.
I can provide a Go function with a different name, and then in the assembly code jump to it. This looks tedious and I can't ensure I have provided the assembly file for all possible targets.
Is there a way to provide a Go function, and an alternate version to use instead when compiling for particular targets (e.g. amd64) ?
Upvotes: 4
Views: 302
Reputation:
The standard way to do this is to have at least four files, three of which are protected by build constraints, either by use of the +build
tag or by the filename.
wrapper.go
package mypkg
import "fmt"
func Wrapper(s string) {
fmt.Println(impl(s))
}
impl_generic.go
// +build !amd64
package mypkg
func impl(s string) string {
// TODO: non-assembly implementation
}
impl_asm.go
// +build amd64
package mypkg
// defined in *.s
func impl(s string) string
impl_amd64.s
TEXT ·impl(SB),$0
// TODO: AMD64 implementation
RET
To add an assembly implementation for another architecture:
,!$arch
to the first impl_generic.go build constraint item$arch
to the impl_asm.go build constraint listimpl_$arch.s
Upvotes: 5