将2个QWORD从通用寄存器移动到XMM寄存器作为高/低 [英] Moving 2 QWORDs from general purpose registers into an XMM register as high/low
本文介绍了将2个QWORD从通用寄存器移动到XMM寄存器作为高/低的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
使用MASM for ml64,我正在尝试将R9和R10中的两个无符号qword作为无符号128B int移到xmm0中
到目前为止,我想出了这个:
mov r9, 111 ;low qword for test
mov r10, 222 ;high qword for test
movq xmm0, r9 ;move low to xmm0 lower bits
movq xmm1, r10 ;move high to xmm1 lower bits
pslldq xmm1, 4 ;shift xmm1 lower half to higher half
por xmm0, xmm1 ;or the 2 halves together
我认为它是可行的,因为
movq rax, xmm0
返回正确的下限
psrldq xmm0, 4
movq rax, xmm0
返回正确的高值
问题是,有没有更好的方法呢?我正在浏览英特尔内部指南,但我不太擅长猜测它们可能具有的任何指令的名称。推荐答案
您的字节移位/或被破坏,因为您只移位了4个字节,而不是8个字节;当您的8字节qword测试值的上半部分中没有设置任何位时,它恰好起作用。
SSE/AVX SIMD指令集包括可用于此的unpack instruction:
mov r9, 111 ; test input: low half
mov r10, 222 ; test input: high half
vmovq xmm0, r9 ; move 64 bit wide general purpose register into lower xmm half
vmovq xmm1, r10 ; ditto
vpunpcklqdq xmm0, xmm0, xmm1 ; i.e. xmm0 = low(xmm1) low(xmm0)
这意味着vpunpcklqdq
instruction将每个低源四字(=64位)解包(或交织)为双四字(即完整的XMM寄存器宽度)。
与原始代码段相比,您保存了一条指令。
(我用过VEX AVX助记法。如果要以SSE2为目标,则必须删除v
前缀。)
或者,您可以使用insert instruction将第二个值移到上半部分:
mov r9, 111 ; test input
mov r10, 222 ; test input
vmovq xmm0, r9 ; move 64 bit wide general purpose register into lower xmm half
vpinsrq xmm0, xmm0, r10, 1 ; i.e. xmm0 = r9 low(ymm0)
在执行方面,在微操作级别上,这没有太大区别,即vpinsrq
与vmov + vpunpcklqdq
一样‘昂贵’,但它编码成更短的代码。
此的非AVX版本需要pinsrq
的SSE4.1。
这篇关于将2个QWORD从通用寄存器移动到XMM寄存器作为高/低的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文