MOVMSKB
能很好地将字节字段打包成位
但是我想做相反的事
我有一个16位的字段,我想放入XMM寄存器
每位1字节字段。
优选地,设置位应该设置每个字节字段的MSB(0x80),但是我可以使用设置位,从而在字节字段中产生0xFF结果。
我在https://software.intel.com/en-us/forums/intel-isa-extensions/topic/298374上看到了以下选项:
movd mm0, eax
punpcklbw mm0, mm0
pshufw mm0, mm0, 0x00
pand mm0, [mask8040201008040201h]
pcmpeb mm0, [mask8040201008040201h]
但是,此代码仅适用于MMX寄存器,不能与XMM regs一起使用,因为pshufw不允许这样做。
我知道我可以使用PSHUFB
,但那是SSSE3而我想拥有SSE2代码,因为它需要在任何AMD64系统上运行。
有没有办法做到这一点是纯SSE2代码?
没有内在函数,只需简单的intel x64代码。
答案 0 :(得分:5)
幸运的是pshufd
是SSE2,你只需要再次解压缩它。我相信这应该有效:
movd xmm0, eax
punpcklbw xmm0, xmm0
punpcklbw xmm0, xmm0
pshufd xmm0, xmm0, 0x50
pand xmm0, [mask]
pcmpeqb xmm0, [mask]
约翰说:
如果你从一个单词开始,第一个解压缩会给你一个dword,允许你像这样缩短它:
movd xmm0, eax punpcklbw xmm0, xmm0 pshufd xmm0, xmm0, 0x00 pand xmm0, [mask] pcmpeqb xmm0, [mask]
但是这段代码不起作用。示例:假设输入为0x00FF
(字),即我们希望设置低8字节。
punpcklbw xmm0, xmm0 ; 00 00 00 00 00 00 00 00 00 00 00 00 00 00 FF FF
pshufd xmm0, xmm0, 0x00 ; 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 FF FF
pand xmm0, [mask] ; 00 00 02 01 00 00 02 01 00 00 02 01 00 00 02 01
pcmpeqb xmm0, [mask] ; 00 00 FF FF 00 00 FF FF 00 00 FF FF 00 00 FF FF
这是错误的结果,因为我们想要00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF
。当然,它确实给你8个字节,而不是8个对应的位。