Go không liên kết assembly của tôi: hàm bên ngoài không xác định


82

Tôi đang cố gắng viết một số SIMD chủ yếu cho mục đích học tập. Tôi biết Go có thể liên kết lắp ráp, nhưng tôi không thể làm cho nó hoạt động chính xác.

Đây là ví dụ tối thiểu nhất mà tôi có thể làm (phép nhân vectơ theo phần tử):

vec_amd64.s (lưu ý: tệp thực tế có một dòng khoảng trắng bên dưới RETvì nó gây ra lỗi nếu không)

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

Khi tôi cố gắng chạy, go testtôi gặp lỗi:

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

Các go envlệnh báo cáo của tôi GOHOSTARCHđược amd64và phiên bản Go của tôi là 1,3. Để xác nhận đó không phải là kiến ​​trúc gây ra sự cố, tôi đã tìm thấy một gói khác sử dụng lắp ráp và đã xóa tất cả các tệp lắp ráp ngoại trừ _amd64.smột và các thử nghiệm của nó chạy tốt.

Tôi cũng đã thử thay đổi nó thành một số nhận dạng đã xuất trong trường hợp gây ra sự kỳ lạ, nhưng không có xúc xắc. Tôi nghĩ rằng tôi đã theo dõi khá chặt chẽ mẫu trong các gói như math/bigvậy, vì vậy hy vọng đó là một cái gì đó đơn giản và rõ ràng mà tôi đang thiếu.

Tôi biết rằng Go ít nhất đang cố gắng sử dụng hợp ngữ vì nếu tôi đưa ra một lỗi cú pháp cho tệp .s, công cụ xây dựng sẽ phàn nàn về nó.

Biên tập:

Để rõ ràng, go buildsẽ biên dịch sạch sẽ, nhưng go testgây ra lỗi xuất hiện.


go buildhoàn thành sạch sẽ, go testkhông thành công.
LinearZoetrope

1
Làm thế nào để bạn biên dịch? Bạn đã không trả lời câu hỏi.
fuz

1
Bạn đã nhập những lệnh nào từ thư mục nào liên quan đến tệp nguồn của bạn? Tôi biên dịch bằng gocông cụ xây dựng. là rất mơ hồ. Nó có thể có nghĩa là bất cứ điều gì.
fuz

1
Có sự khác biệt giữa cách gọi go buildgo build foo.go, v.v. Cũng có thể là bạn có cài đặt sôi nổi trong của mình $GOPATH, v.v. Bạn càng viết nhiều về chính xác những gì bạn đã làm, bạn càng dễ dàng giúp đỡ bạn. Điều tốt nhất là đăng bảng điểm của các phiên shell thay vì prosa.
fuz

12
Ngôn ngữ cờ vây thực sự có vẻ tôn sùng ký tự dấu chấm giữa. Liên quan: Dấu gạch chéo và dấu chấm trong tên hàm và nguyên mẫu?
Cody Grey

Câu trả lời:


96

Bạn đang sử dụng dấu chấm sai. thay vì

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

viết

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

và mọi thứ hoạt động tốt.


11
Ồ, thật là tinh tế, tôi không nhận thấy rằng đó là một dấu chấm ở giữa. Cảm ơn.
LinearZoetrope

13
Làm thế nào để mọi người gõ nó trên bàn phím QWERTY của Mỹ? Hay đây không phải là một trường hợp sử dụng phổ biến, nơi bạn có thể chỉ cần google ký hiệu khi cần thiết?
Seiyria

9
Như thế này . Hệ điều hành không hấp dẫn (tức là không phải Windows) ánh xạ các lớp không sử dụng của bố cục QWERTY để có thể nhập các ký tự như dấu xen kẽ.
fuz

7
@FUZxxl FYI Alt-0183 (sử dụng bàn phím số) vẫn hoạt động cho Windows. Không hoàn toàn đẹp và thường khó trên máy tính xách tay, nhưng nó hoạt động.
Intermernet

4
Trên linux (ít nhất là Ubuntu) nếu bạn đã bật khóa soạn : <compose> ^ .=·
Izkata
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.