Go не связывает мою сборку: undefined внешняя функция

Я пытаюсь написать SIMD в основном для учебных целей. Я знаю, что Go может связывать сборку, но я не могу заставить ее работать правильно.

Здесь самый минимальный пример, который я могу сделать (умножение по элементарным векторам):

vec_amd64.s (обратите внимание: фактический файл имеет строку пробела под RET, поскольку он вызывает ошибки в противном случае)

// 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)
    }
}

Когда я пытаюсь запустить go test, я получаю ошибку:

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

Команда go env сообщает my GOHOSTARCH как amd64, а моя версия Go - 1.3. Чтобы подтвердить, что это не проблема архитектуры, я нашел другой пакет, который использует сборку и удаляет все файлы сборки, кроме _amd64.s, и его тесты прошли нормально.

Я также попытался изменить его на экспортированный идентификатор в случае, если это вызывало странность, но не играло в кости. Я думаю, что я довольно внимательно следил за шаблоном в пакетах, таких как math/big, поэтому, надеюсь, это просто и понятно, что мне не хватает.

Я знаю, что Go не менее пытается использовать сборку, потому что, если я введу синтаксическую ошибку в файл .s, инструмент сборки будет жаловаться на это.

Edit:

Чтобы быть ясным, go build будет компилироваться чисто, но go test вызывает ошибку.

Ответ 1

Вы используете неправильную точку. вместо

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

записи

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

и все работает отлично.