Встроенная сборка инструкций SSE в g ++ 4.2 объединяет код пользовательской сборки с выровненной копией регистра XMM - PullRequest
2 голосов
/ 02 ноября 2011

У меня есть функция, использующая встроенную сборку:

  vec8w x86_sse_ldvwu(const vec8w* m) { 
     vec8w rd; 
     asm("movdqu %[m],%[rd]" : [rd] "=x" (rd) : [m] "xm" (*m)); 
     return rd; 
  } 

Компилируется в следующий код сборки:

  sub    $0x1c,%esp
  mov    0x24(%esp),%eax
  movdqa (%eax),%xmm0 
  movdqu %xmm0,%xmm0
  movdqa %xmm0,(%esp)
  movdqa (%esp),%xmm0
  add    $0x1c,%esp
  ret 

Код не очень эффективен, но это не мое дело. Как вы видите, встроенный ассемблер вставляет инструкцию movdqa, копируя с адреса в% eax в xmm0. Проблема в том, что указатель vec8w * m не 128 байтов выровнен, поэтому я получаю ошибку сегмента при выполнении movdqa. Мой вопрос заключается в том, есть ли способ указать встроенному ассемблеру использовать movdqu вместо movdqa (который он использует по умолчанию)? Я пытался найти обходной путь, используя встроенные функции SSE для g ++, но почему-то я не могу найти movdqu в файле xmmintrin.h (где он должен быть объявлен, я полагаю). К сожалению, я не могу изменить код так, чтобы функция всегда вызывалась для выровненного аргумента m.

1 Ответ

2 голосов
/ 02 ноября 2011

Свойство, которое вы ищете, это _mm_loadu_si128. Это определено в emmintrin.h. Какой SSE2. Заголовок xmmintrin.h содержит только инструкции SSE (1).

http://software.intel.com/sites/products/documentation/studio/composer/en-us/2011/compiler_c/intref_cls/common/intref_sse2_int_load.htm

_mm_loadu_si128 выдаст команду movdqu, которую вы ищете. Кажется, это именно то, что вы пытаетесь выполнить с помощью встроенной функции сборки. (смещенная нагрузка)

...