如何将128位 xmm
登记为两个64位四字?
我在xmm1
中有很大的数量,并希望将更高的四词置于 r9
,而较低的QUADWORD到r10
,或RAX
和RDX
。
movlpd
或movhpd
仅与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
。