How to deal with Slices as inputs and outputs in Go ASM

262 Views Asked by At

I am trying to understand how to send more complicated values to and from Go ASM functions; beyond the typical uint in, uint out case. I stumbled upon a great example of this advanced usage in the crypto/elliptic with the function p256BigToLittle in p256_asm_arm64.s. It takes an byte slice and uint64 slice, it then processes the bytes and puts the output value into the uint64 slice. Below is the function with the preprocessor define statements substituted. Here are the main things I do not understand:

  • I cannot find define statements for res or in so are these being resolved at compile time from the function signature in the .go file? (IE: if I made a function func myFunc(arg1 *int) can I reference arg1 in the corresponding asm file?)
  • Where did the magic number +24 in MOVD in+24(FP), R1 come from?
  • I am assuming the 1*16(R1) is just meant to point to the second element of the in byte slice (8*2)? How do you know the spacing between elements of a slice? If in were a uint32 slice would the second element be be 1*64(R1)?
  • Where is the Go Slice header during all of this? How is it being avoided?
// func p256BigToLittle(res []uint64, in []byte)
TEXT ·p256BigToLittle(SB),NOSPLIT,$0
    MOVD    res+0(FP), R0
    MOVD    in+24(FP), R1

    LDP 0*16(R1), (R3, R4)
    LDP 1*16(R1), (R5, R6)

    REV R3, R3
    REV R4, R4
    REV R5, R5
    REV R6, R6

    STP (R6, R5), 0*16(R0)
    STP (R4, R3), 1*16(R0)
    RET
0

There are 0 best solutions below