如何将XMM 128位寄存器分为两个64位整数寄存器



如何将128位 xmm登记为两个64位四字?

我在xmm1中有很大的数量,并希望将更高的四词置于 r9,而较低的QUADWORD到r10,或RAXRDX

movlpdmovhpd仅与Reg一起使用,反之亦然。

SSE2(X86-64的基线)具有直接在XMM和Integer寄存器之间移动数据的说明(无需通过内存弹跳)。对于向量的低元素:MOVD或MOVQ很容易。要提取更高的元素,您只需将想要的元素调整为向量的低元素。

sse4.1还为16位以外的大小(例如PEXTRQ)添加了插入/提取物。除了代码尺寸外,它实际上并不比任何现有CPU上的单独的shuffle and MovQ更快,但这意味着您不需要任何额外的TMP寄存器。

#SSE4.1
movq    rax, xmm0       # low qword
pextrq  rdx,  xmm0, 1   # high qword
# 128b result in rdx:rax, ready for use with div r64 for example.
# (But watch out for #DE on overflow)
# also ready for returning as a __int128_t in the SystemV x86-64 ABI
#SSE2
movq       r10, xmm0
punpckhqdq xmm0, xmm0    # broadcast the high half of xmm0 to both halves
movq       r9,  xmm0

punpckhqdq是最有效的方法。即使在旧的CPU上,较小的元素尺寸小于64位,例如65nm core2(merom/conroe)。有关此的更多详细信息,请参见我的水平总和答案。punpckhqdq没有立即操作数,只有SSE2,因此只有4个字节。

要保留XMM0的原始值,请在其他目的地使用pshufd。或将高点和低到就地或其他交换。


movlpd或movhpd ...

使用它们没有意义。改用Movlps/Movhps,因为它们较短,并且没有CPU对Float与Double的关心。

您可以使用movhlps xmm1, xmm0将XMM0的高度提取到另一个寄存器中,但是将FP Shuffles与Integer-Vector操作混合会导致某些CPU(特别是Intel Nehalem)的旁路延迟。还要提防对XMM1产生潜伏期瓶颈的依赖性。

绝对更喜欢pshufd。但是,如果您要为特定的CPU进行调整,例如movhlps快速并且在整数域运行,并且pshufd很慢。

,则可以使用movhlps

最新更新