Там нет байт-элемент сдвига (psrlb
или любой другой), так что вы не можете просто сбить биты вы не хотите с правой и затем сдвиг влево. Даже если вам нужно сделать это только один раз, лучше всего использовать маску.
Вы можете generate the mask on the fly in fewer instruction bytes than it takes to store the mask, не имея возможности пропустить кеш.
pcmpeqw xmm1,xmm1 ; -1
pabsb xmm1,xmm1 ; 1
psllw xmm1, 7 ; set1_epi8(0x80)
pand xmm1, xmm0
Если вы хотите знаковые биты упакованы вместе в целочисленном обл
PMOVMSKB reg, xmm0
Но распаковка, что обратно в вектор медленнее, чем генерации signbit-маски (until AVX512).
Если вы только делаете это один раз, вы могли быть в состоянии придумать что-то короче, чем 4 insns, особ. если вы можете использовать неразрушающие операции AVX. Вот идея, которая не была короче:
vpcmpeqw xmm1, xmm1,xmm1
vpsignb xmm2, xmm1, xmm0 ; xmm2 = -1 or +1 (or 0) depending on xmm0
vpsubb xmm3, xmm2, xmm1 ; xmm3 = 0 or +2 (or +1) depending on xmm0. (subtract -1 => add 1)
vpsllw xmm4, xmm3, 6 ; xmm4 = 0 or 0x80 (or 0x40) depending on xmm0
Нет, не был короче. В зависимости от того, что вам нужно, часть этой идеи может помочь.
Вы пробовали '_mm_and_si128()'? – Mysticial
Я могу представить, используя '_mm_and_si128' (т. Е.' Pand'), но для этого требуется сначала загрузить соответствующую маску. (Какой самый эффективный способ сделать это?) Мне интересно, есть ли что-то специализированное, которое может сделать лучше. – jacobsa