2012-01-27 29 views
7

Tôi đã cố gắng kết hợp bộ mã hóa nội tại SSE2 và bộ ghép nội tuyến trong gcc. Nhưng nếu tôi chỉ định một biến là xmm0/register làm đầu vào thì trong một số trường hợp tôi gặp lỗi trình biên dịch. Ví dụ:Sử dụng cả bộ mã hóa nội tại SSE2 và bộ mã hóa nội tuyến gcc

#include <emmintrin.h> 
int main() { 
    __m128i test = _mm_setzero_si128(); 
    asm ("pxor %%xmm0, %%xmm0" : : "xmm0" (test) :); 
} 

Khi biên soạn với phiên bản gcc 4.6.1 tôi nhận được:

>gcc asm_xmm.c 
asm_xmm.c: In function ‘main’: 
asm_xmm.c:10:3: error: matching constraint references invalid operand number 
asm_xmm.c:7:5: error: matching constraint references invalid operand number 

Điều lạ là trong cùng một trường hợp tôi có các biến đầu vào khác/đăng ký sau đó nó đột nhiên làm việc với xmm0 như đầu vào nhưng không xmm1, vv Và trong trường hợp khác tôi đã có thể chỉ định xmm0-xmm4 nhưng không ở trên. Một chút bối rối/thất vọng về điều này: S

Cảm ơn :)

Trả lời

11

Bạn nên để trình biên dịch thực hiện việc đăng ký. Dưới đây là một ví dụ về pshufb (ví gcc quá già để có tmmintrin cho SSSE3):

static inline __m128i __attribute__((always_inline)) 
_mm_shuffle_epi8(__m128i xmm, __m128i xmm_shuf) 
{ 
    __asm__("pshufb %1, %0" : "+x" (xmm) : "xm" (xmm_shuf)); 
    return xmm; 
} 

Lưu ý "x" vòng loại vào các đối số và chỉ cần %0 trong lắp ráp chính nó, nơi trình biên dịch sẽ thay thế trong register nó chọn.

Hãy cẩn thận khi sử dụng các công cụ sửa đổi phù hợp. "+x" nghĩa là xmm là cả thông số đầu vào và đầu ra. Nếu bạn sloppy với những sửa đổi (ví dụ: sử dụng "=x" có nghĩa là sản lượng chỉ khi bạn cần "+x") bạn sẽ chạy vào trường hợp đôi khi nó hoạt động và đôi khi không.

+0

Bạn là ngôi sao! Cảm ơn :) –