asm2go

module
v0.0.0-...-2ff52b8 Latest Latest
Warning

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

Go to latest
Published: Jun 6, 2018 License: GPL-3.0

README

asm2go

Go Report Card license Build Status codecov Snap Status FOSSA Status

This project aims to automatically generate working Golang assembly from native assembly and a golang declaration file, mainly used for implementing performance-intensive complex functions in assembly.

Usage

asm2go requires 2 files, a native assembly file that assembles properly using as (the GNU assembler), and a Golang declaration file that contains signatures for the functions implemented in assembly. These names must match exactly, if a symbol in the assembly doesn't have a corresponding go function declaration the generation fails (this restriction is somewhat arbitrary right now and may be lifted in the future).

As to writing the actual assembly code to be translated, there are a few caveats.

  1. Argument calling convention in Go places arguments on the stack, so you should write the assembly code to reference the stack for accessing arguments provided to functions. This may or may not match what is normally done, for example registers are sometimes used instead for passing arguments, but referencing the stack seems to be the best way to do this.
  2. Data symbols are not yet supported. For example, defining an array of data with a symbol referring to the start of the array isn't supported. This is due to the fact that this tool translates the compiled object code into Golang assembly, at which point most data symbol references in the code have been translated into addresses, which means that simply including the array won't work as it will likely be repositioned in the final binary by go. This translation could be made to work, but it would be quite difficult.
  3. The produced Golang assembly currently includes a RET at the end, which means that you shouldn't also include returning instructions (such as bx lr for ARM) as the Golang assembler will already insert this information.
  4. Supported instructions are translated from native assembly into Golang's supported syntax. For example mov r2 lr in native ARM is translated to MOVW R14, R2 in native plan9 assembly. Currently this is only supported for ARM, but it would be easy to support this on other architecture's using golang.org/x/arch.
  5. No assembly function flags are currently supported. I eventually hope to solve this by annotating the function's declaration in the go source file. For example to insert the NOPTR flag, I think eventually a comment like // asm2go:noptr would be included above the function's declaration. Specifying the frame sizes should also probably be supported this way. It would be nice for asm2go to dynamically determine the size of the arguments, but this isn't currently implemented.

Furthermore, the assembler must either be specified with the -as option, which can be a absolute path or a name on $PATH. In the same folder as the assembler must be the executables strip and objdump must also be available (note that assemblers specified with a prefix such as arm-linux-gnueabihf-as works properly; the prefix is resolved to find arm-linux-gnueabihf-objdump, etc - this allows cross compiling to work as expected). strip is used to remove debugging information from the compiled object file, and objdump is used to parse the actual hex instructions that are associated with instructions.

Assembler options may be specified with as-opts, as many times as needed. For example to use the options -march=armv7-a and the option -mfpu=neon-vfpv4, you would invoke asm2go as follows:

asm2go -file somefile.s -gofile somefile.go -as-opts -march=armv7-a -as-opts -mfpu=neon-vfpv4

The output can either be a file specified with the -out option, or if not specified the output is dumped to stdout.

Usage message
$ asm2go --help
Usage of asm2go:
  -as string
    	assembler to use (default "gas")
  -as-opts value
    	Assembler options to use
  -file string
    	file to assemble
  -gofile string
    	go file with function declarations
  -out string
    	output file to place data in (empty uses stdout)

Examples

Keccak

This example uses the assembly file from the KeccakCodePackage here : https://github.com/gvanas/KeccakCodePackage. Specifically, the ARMv7A implementation here: https://github.com/gvanas/KeccakCodePackage/blob/master/lib/low/KeccakP-1600/OptimizedAsmARM/KeccakP-1600-armv7a-le-neon-gcc.s was modified to only contain the KeccakF-1600 function (it was also modified to use some constants passed in as an argument instead of hard-coded into the assembly as a symbol).

To generate the native go assembly from the native ARM assembly copied here run:

$ git clone github.com/anonymouse64/asm2go
$ cd asm2go
$ go install
$ export PATH="$GOPATH/bin:$PATH"
$ cd tests/keccak_arm
$ go generate
$ go build keccak_check.go
$ ./keccak_check
Success!
$

This uses the go:generate comment inside keccak_check.go

The assembly generated uses the WORD feature of Plan9 assembly to translate all unsupported native instructions like such:

TEXT ·KeccakF1600(SB), 0, $0-8
    MOVW 0x4(R13), R0  // ldr      r0        [sp #4] 
    MOVW 0x8(R13), R1  // ldr      r1        [sp #8] 
    WORD $0xed2d8b10;  // vpush    {d8-d15}  
    WORD $0xf42007dd;  // vld1.64  {d0}      [r0 :64]!  
    WORD $0xf42027dd;  // vld1.64  {d2}      [r0 :64]!  
    WORD $0xf42047dd;  // vld1.64  {d4}      [r0 :64]!  
...

The only required parts are the ARM assembly file (keccak.s) and the go declaration file which declares the assembly-implemented function in go. The go file doesn't need anything extra, just the function declaration:

package keccak

// go:noescape
// This function is implemented in keccak.s
func KeccakF1600(state *[25]uint64, constants *[24]uint64)

License

This project is licensed under the GPLv3. See LICENSE file for full license. Copyright 2018 Canonical Ltd.

Directories

Path Synopsis
gnu
cmd

Jump to

Keyboard shortcuts

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