2010-02-02 18 views
4

GCC génère ce code pour le shuffle() ci-dessous:GCC syntaxe étendue ASM: charge de l'emplacement de mémoire 128 bits en tant que source

movaps xmm0,XMMWORD PTR [rip+0x125] 
pshufb xmm4,xmm0 

Idéalement, cela devrait être:

pshufb xmm4,XMMWORD PTR [rip+0x125] 

Quel est le étendu Syntaxe ASM pour générer cette instruction unique?

Un grand merci, Adam

PS: La commenté intrinsèque génère le code optimal pour cet exemple. Cela ne fonctionne pas en général (GCC est susceptible de générer des copies de registres inutiles en présence de variables de registre globales).

#include <stdint.h> 

typedef int8_t xmm_t __attribute__ ((vector_size (16))); 
const xmm_t xmm_shuf={128, 0, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15}; 
register xmm_t xmm __asm__("xmm4"); 

#define NTL ".intel_syntax noprefix\n" 
#define ATT ".att_syntax\n" 

void shuffle() { 
    //xmm=__builtin_ia32_pshufb128(xmm, xmm_shuf); 
    __asm__(NTL"pshufb %0, %1\n"ATT : "=x" (xmm) : "x" (xmm_shuf)); 
} 

int main() { 
} 

$ gcc -Os std = gnu99 -msse4.1 -flax-vecteur-conversions pshufb_128bit_constant.c & & objdump -d -m i386: x86-64: intel a.out | moins

0000000000400494 <shuffle>: 
    400494:  0f 28 05 25 01 00 00 movaps xmm0,XMMWORD PTR [rip+0x125]  # 4005c0 &lt;xmm_shuf+0x10&gt; 
    40049b:  66 0f 38 00 e0   pshufb xmm4,xmm0 
    4004a0:  c3      ret 

Répondre

5

Modifiez la contrainte de l'opérande d'entrée sur "xm", de sorte que les emplacements de mémoire soient autorisés en plus des registres SSE. Cependant, lorsque je l'ai testé, le compilateur a généré du code qui ne correspond pas bien à la syntaxe Intel. Donc, à la fin, c'est ce que j'ai utilisé:

__asm__("pshufb %1, %0" : "+x" (xmm) : "xm" (xmm_shuf)); 
+0

Merci beaucoup Chris! J'ai été perplexe par la syntaxe Intel. Très impressionné par votre aide. –