使用masm for ml64,我试图将2个无符号qwords从r9和r10移动到xmm0作为无符号128b int
到目前为止,我提出了这个问题:
{this.state.showForm ?
<View>
// Your form content here
</View>
: null }
我认为它有效,因为
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
返回正确的高值
问题是,有没有更好的方法呢?我浏览了英特尔内在指南,但我不太擅长猜测这些名称可能有什么说明。
答案 0 :(得分:1)
您的字节移位/或中断,因为您仅移位了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。
答案 1 :(得分:0)
在筹码的帮助下:
push r10
push r9
ifdef ALIGNED
movdqa xmm0, xmmword ptr [esp]
else
movdqu xmm0, xmmword ptr [esp]
endif
add esp, 16
如果你的__uint128恰好存在于堆栈中,只需删除多余的指令。