2016-06-12 2 views
1

Учитывая следующую программу:порядка байт в сборе XMM лязга комментарии

#include "emmintrin.h" 

int main(int argc, char *argv[]) 
{ 
    volatile __m128i x = _mm_set_epi64x(1, 0); 
    return 0; 
} 

я могу получить сборку с помощью clang -O -S test.c (только листинга интересной части):

... 
movl $1, %eax 
movd %rax, %xmm0 
pslldq $8, %xmm0    # xmm0 = zero,zero,zero,zero,zero,zero,zero,zero,xmm0[0,1,2,3,4,5,6,7] 
... 

Согласно руководству по _mm_set_epi64x , %xmm0 должен быть [0, 1, 0, 0], причем каждый элемент является целым числом (32 бита).

Однако, в соответствии с комментарием, %xmm0 проводит [0, 0, 0, 1]. Я не думаю, что здесь важна преданность, потому что я только смотрю на регистр.

Я подозреваю, что это связано с обозначениями, используемыми комментарием компиляции clang, но я не могу найти никакой полезной информации об этом в Интернете.

== Edit:

Подал bug звенеть.

ответ

1

Код clang загружает значение в два этапа. Во-первых, значение 1 загружается в младшие 64 бита регистра. Затем вся вещь сдвигается на 8 двоичных мест, поэтому значение 1 заканчивается в высоких 64 битах точно так же, как ваш код указывает.

+0

Да, это тоже мое понимание. Однако комментарий '# xmm0 = zero ...', похоже, не согласен. –

+0

@AlbertNetymk Этот комментарий относится к предварительному состоянию 'xmm0', которое перед выполнением сдвига действительно содержит 1 в нижней позиции. – fuz

+0

Это было бы очень противно интуитивно. 'xmm0 = ноль, ноль, ноль, ноль, ноль, ноль, ноль, ноль, xmm0 [0,1,2,3,4,5,6,7]' читается как назначение. 'volatile __m128i y = _mm_set1_epi32 (1);' => 'movaps .LCPI0_0 (% rip),% xmm0 # xmm0 = [4294967297,4294967297]' показывает, что комментарий отражает состояние регистра впоследствии, а не состояние предыдущего, IMO , –

1

В комментарии, как представляется, описывается операция pslldq в терминах предыдущего содержимого xmm0 (даже если они известны во время компиляции).

Это похоже на обратный порядок от обычного high-element-first ([ 3 2 1 0 ]), который использует _mm_set, и это делает «левые» сдвиги имеющими смысл.

Это байтовый заказ, который вы получите в памяти, если вы сохранили вектор.

Я забыл, что это типично для clang, и у меня нет времени прямо сейчас, чтобы проверить другой пример.

Смежные вопросы