Используйте встроенные функции SSE2 и встроенный ассемблер gcc - PullRequest
7 голосов
/ 28 января 2012

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

#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

Спасибо:)

1 Ответ

11 голосов
/ 28 января 2012

Вы должны позволить компилятору выполнить присваивание регистра.Вот пример 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"), вы столкнетесь с ситуациями, когда иногда это работает, а иногда нет.

...