Использовать как SSE2 набор встроенных функций и встроенный ассемблер компилятора GCC
Я попытался смешать встроенные функции 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 ответ:
Вы должны позволить компилятору выполнить назначение регистра. Вот пример
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"
) вы столкнетесь с случаями, когда это иногда работает, а иногда нет.