问题
I have tried to mix SSE2 intrinsics and inline assembler in gcc. But if I specify a variable as xmm0/register as input then in some cases I get a compiler error. Example:
#include <emmintrin.h>
int main() {
__m128i test = _mm_setzero_si128();
asm ("pxor %%xmm0, %%xmm0" : : "xmm0" (test) : );
}
When compiled with gcc version 4.6.1 I get:
>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
The strange thing is that in same cases where I have other input variables/registers then it suddenly works with xmm0 as input but not xmm1, etc. And in another case I was able to specify xmm0-xmm4 but not above. A little confused/frustrated about this :S
Thanks :)
回答1:
You should let the compiler do the register assignment. Here's an example of pshufb
(for gcc
too old to have tmmintrin
for 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;
}
Note the "x"
qualifier on the arguments and simply %0
in the assembly itself, where the compiler will substitute in the register it selected.
Be careful to use the right modifiers. "+x"
means xmm
is both an input and an output parameter. If you are sloppy with these modifiers (eg using "=x"
meaning output only when you needed "+x"
) you will run into cases where it sometimes works and sometimes doesn't.
来源:https://stackoverflow.com/questions/9040361/use-both-sse2-intrinsics-and-gcc-inline-assembler