Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go isn't linking my assembly: undefined external function

Tags:

assembly

go

I'm trying to write some SIMD mostly for learning purposes. I know Go can link assembly, but I can't get it to work correctly.

Here's the most minimal example I can make (element-wise vector multiplication):

vec_amd64.s (note: the actual file has a whitespace line under RET since it causes errors otherwise)

// func mul(v1, v2 Vec4) Vec4 TEXT .mul(SB),4,$0-48     MOVUPS v1+0(FP),  X0     MOVUPS v2+16(FP), X1     MULPS  X1, X0     // also tried ret+32 since I've seen some places do that     MOVUPS X0, toReturn+32(FP)     RET 

vec.go

package simd  type Vec4 [4]float32  func (v1 Vec4) Mul(v2 Vec4) Vec4 {     return Vec4{v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2], v1[3] * v2[3]} }  func mul(v1, v2 Vec4) Vec4 

simd_test.go

package simd  import (     "testing" )  func TestMul(t *testing.T) {     v1 := Vec4{1, 2, 3, 4}     v2 := Vec4{5, 6, 7, 8}      res := v1.Mul(v2)     res2 := mul(v1, v2)      // Placeholder until I get it to compile     if res != res2 {         t.Fatalf("Expected %v; got %v", res, res2)     } } 

When I try to run go test I get the error:

# testmain simd.TestMul: call to external function simd.mul simd.TestMul: undefined: simd.mul 

The go env command reports my GOHOSTARCH to be amd64 and my Go version to be 1.3. To confirm it wasn't the architecture causing the problem, I found another package that uses assembly and deleted all the assembly files except the _amd64.s one and its tests ran fine.

I also tried changing it to an exported identifier in case that was causing weirdness, but no dice. I think I pretty closely followed the template in packages like math/big, so hopefully it's something simple and obvious that I'm missing.

I know that Go is at least trying to use the assembly because if I introduce a syntax error to the .s file the build tool will complain about it.

Edit:

To be clear, go build will compile cleanly, but go test causes the error to appear.

like image 293
Linear Avatar asked Aug 23 '14 10:08

Linear


Video Answer


1 Answers

You are using the wrong dot. instead of

TEXT .mul(SB),4,$0-48 

write

TEXT ·mul(SB),4,$0-48 

and everything works just fine.

like image 97
fuz Avatar answered Nov 14 '22 15:11

fuz