128位值 - 从XMM寄存器到通用

Goa*_*444 9 x86 assembly sse

我有几个与将XMM值移动到通用寄存器有关的问题.在SO上找到的所有问题都集中在相反的方面,即将gp寄存器中的值传递给XMM.

  1. 如何将XMM寄存器值(128位)移动到两个64位通用寄存器?

    movq RAX XMM1 ; 0th bit to 63th bit
    mov? RCX XMM1 ; 64th bit to 127th bit
    
    Run Code Online (Sandbox Code Playgroud)
  2. 同样,如何将XMM寄存器值(128位)移动到4个32位通用寄存器?

    movd EAX XMM1 ; 0th bit to 31th bit
    mov? ECX XMM1 ; 32th bit to 63th bit
    
    mov? EDX XMM1 ; 64th bit to 95th bit
    mov? ESI XMM1 ; 96th bit to 127 bit
    
    Run Code Online (Sandbox Code Playgroud)

Joh*_*ica 11

您不能直接将XMM寄存器的高位移动到通用寄存器中.
你必须遵循两个步骤,这可能涉及或不涉及往返记忆或破坏寄存器.

在寄存器中

movq rax,xmm0       ;lower 64 bits
movhlps xmm0,xmm0   ;move high 64 bits to low 64 bits.
movq rbx,xmm0       ;high 64 bits.
Run Code Online (Sandbox Code Playgroud)

通过记忆

movdqu [mem],xmm0
mov rax,[mem]
mov rbx,[mem+8]
Run Code Online (Sandbox Code Playgroud)

慢,但不破坏xmm寄存器

mov rax,xmm0
pextrq rbx,xmm0,1        ;3 cycle latency on Ryzen!
Run Code Online (Sandbox Code Playgroud)

对于32位,代码类似:

在寄存器中

movd eax,xmm0
psrldq xmm0,xmm0,4    ;shift 4 bytes to the right
movd ebx,xmm0
psrldq xmm0,xmm0,4
movd ecx,xmm0
psrlq xmm0,xmm0,4
movd edx,xmm0
Run Code Online (Sandbox Code Playgroud)

通过记忆

movdqu [mem],xmm0
mov eax,[mem]
mov ebx,[mem+4]
mov ecx,[mem+8]
mov edx,[mem+12]
Run Code Online (Sandbox Code Playgroud)

慢,但不破坏xmm寄存器

mov eax,xmm0
pextrd ebx,xmm0,1        ;3 cycle latency on Skylake!
pextrd ecx,xmm0,2       
pextrd edx,xmm0,3       
Run Code Online (Sandbox Code Playgroud)

64位移位变体可以在2个周期内运行.该pextrq版本至少需要4个.对于32位,数字分别为4和10.

  • `pextrq`的好处是它不会破坏寄存器.但它有点慢. (4认同)
  • FWIW,使用SSE4,您也可以使用`pextrq`,为64位情况提供两个指令解决方案(类似地,使用`pextrd`为32位情况提供4指令解决方案). (2认同)