2012-01-27 2 views
7

Я попытался использовать встроенные ассемблеры SSE2 и встроенный ассемблер в gcc. Но если я укажу переменную как xmm0/register в качестве входных данных, то в некоторые случаях я получаю ошибку компилятора. Пример:Использовать встроенный ассемблер SSE2 и встроенный ассемблер gcc

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

При компиляции с GCC версии 4.6.1 я получаю:

>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 

Самое странное в том, что в тех же случаях, когда у меня есть другие входные переменные/регистры, то он вдруг работает с XMM0 как но не xmm1 и т. д. И в другом случае я смог указать xmm0-xmm4, но не выше. Немного запутался/разочарование по этому поводу: S

Спасибо :)

ответ

11

Вы должны позволить компилятору выполнить задание регистра. Вот пример pshufb (для gcc слишком стар, чтобы иметь tmmintrin для 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; 
} 

Обратите внимание на "x" отборочные на аргументы и просто %0 в самой сборки, где компилятор заменит в регистре он выбран.

Будьте осторожны с использованием правых модификаторов. "+x" означает, что xmm является как входным, так и выходным параметром. Если вы неаккуратно с этими модификаторами (например, используя "=x", значит выводятся только тогда, когда вам нужно "+x"), вы столкнетесь с случаями, когда он иногда работает, а иногда нет.

+0

Вы - звезда! Благодаря :) –

Смежные вопросы