将单词广播到xmm寄存器

时间:2019-07-11 14:33:59

标签: assembly x86 sse

我需要将16位字八次移入xmm寄存器以进行SSE操作

E。 g .:我想在xmm0寄存器中使用16位字ABCD,以便最终结果看起来像

ABCD | ABCD | ABCD | ABCD | ABCD | ABCD | ABCD | ABCD

我要执行此操作,以便以后使用paddw操作。到目前为止,我已经找到了pushfd操作,该操作可以完成我想要的操作,但仅适用于双字(32位)。 pshufw仅适用于-64位寄存器(如果我没有记错的话)。我是否正在寻找所需的操作,还是必须用多个pshufw以某种方式模拟它?

1 个答案:

答案 0 :(得分:4)

您可以通过随机播放然后再打开包装来实现所需的目标。使用NASM语法:

    # load 16 bit from memory into all words of xmm0
    # assuming 16-byte alignment
    pshuflw xmm0, [mem], 0 # gives you [ M, M, M, M, ?, ?, ?, ? ]
    punpcklwd xmm0, xmm0   # gives you [ M, M, M, M, M, M, M, M ]

请注意,这会从mem中读取16个字节,因此需要16个字节的对齐方式

仅实际使用前2个字节。如果该号码不在内存中,或者您不能保证可以读完末尾,请使用以下命令:

    # load ax into all words of xmm0
    movd      xmm0, eax                  ; or movd xmm0, [mem]  4-byte load
    pshuflw   xmm0, xmm0, 0
    punpcklwd xmm0, xmm0

对于AVX2,您可以使用vpbroadcast*广播负载或来自寄存器源的广播。如果愿意,目的地可以是YMM。

    vpbroadcastw  xmm0, [mem]            ; 16-bit load + broadcast

    vmovd         xmm0, eax
    vpbroadcastw  xmm0, xmm0

1或2字节元素的内存源广播仍会解码为Intel CPU上的load + shuffle uop,但4字节或8字节块的广播负载甚至更便宜:在load端口中处理而无需需要洗牌。

无论哪种方式,这仍然比没有AVX2或SSSE3 pshufb时所需的2个单独的改组便宜。