SSE:如何将每个打包字节的符号位提取到打包寄存器中?

时间:2016-04-12 04:26:17

标签: assembly intel sse sse2 sse4

给定xmm0中的压缩字节,提取符号的有效方法是什么 (即最高位)每个字节位到xmm1?换句话说,我想 为每个压缩字节计算逻辑AND和0x80。

例如:

xmm0: 0xff 0xef 0x80 0x7f 0x01 ...
xmm1: 0x80 0x80 0x80 0x00 0x00 ...

1 个答案:

答案 0 :(得分:3)

没有字节元素移位(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

如果您希望将符号位打包在一个整数reg

PMOVMSKB  reg, xmm0

但是将其解包回矢量比生成signbit-mask(until AVX512)要慢。

如果您只是这样做一次,那么可能能够提出短于4个insn的东西,尤其是如果你可以使用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

不,不是更短。根据您的需要,这个想法的一部分可能有所帮助。