Search code examples
goassemblyarm

Go restrictions on ARM registers R10 and R11


I am looking to port a highly optimized crypto ASM implementation to Go ASM. The only documentation on Go Arm Assembly is the Quick Guide and it mentioned the following:

  • The registers R10 and R11 are reserved by the compiler and linker.
  • R10 points to the g (goroutine) structure. Within assembler source code, this pointer must be referred to as g; the name R10 is not recognized.
  • Hand-written assembly can use R11, but doing so requires being sure that the linker is not also using it to implement any of the other instructions in the function.

The ASM I am looking to port uses R10 and R11 so my question is the following:

  • Can I use R10/g?
  • If I use R10/g, so long as I store R10 value at the beginning of the call on the stack and then load it at the end, will there be any problems? (assume go:nosplit is used to stop preemptive behavior)
  • So long as I am not calling any other functions from the Go ASM, then I should not have to worry about the linker restriction on R11, correct?

Solution

  • You should not touch R10 in case e.g. your code is preempted or a panic occurs. I believe the guide is pretty clear on that.

    R11 is used by the linker to synthesise some instructions, e.g. references to global variables. Best check if R11 is used by assembling and then disassembling the code. In the disassembly, any reference to R11 introduced by the linker should be visible.