ASM x86_64 AVX:xmm和ymm记录差异

Sci*_*Art 3 assembly x86-64 nasm avx

xmmymm寄存器有什么区别?我以为xmm是SSE,ymm是AVX,但是我写了一些代码:

vmovups     ymm1, [r9]      
vcvtss2si   rcx, ymm1
Run Code Online (Sandbox Code Playgroud)

它给了我:

error: invalid combination of opcode and operands
Run Code Online (Sandbox Code Playgroud)

关于这条线:

vcvtss2si   rcx, ymm1
Run Code Online (Sandbox Code Playgroud)

所以我写道:

vcvtss2si   rcx, xmm1
Run Code Online (Sandbox Code Playgroud)

它按预期工作。ymm1向量的第一个值转换为整数,现在位于中rcx

这是什么一回事呢?ymm1xmm1相同的寄存器?

Sci*_*Art 9

根据维基百科,在 AVX 中:

YMM寄存器长256 位

XMM寄存器是128位长,并且代表低128位的的YMM寄存器。

YMMXMM寄存器被重叠并XMM包含在YMM

来自维基媒体的图表:

https://commons.wikimedia.org/wiki/File:AVX_registers.svg


Pet*_*des 6

xmm0是的下半部ymm0,恰好eax是的下半部rax

写入xmm0(使用VEX编码指令,而不是旧版SSE)会将的上半通道清零ymm0就像写入到eax的上半部分清零rax以避免虚假的依赖关系一样。缺少将旧版SSE指令的高位字节清零的原因,是混合使用AVX和旧版SSE指令代价

大多数AVX指令均提供128位或256位大小。例如vaddps xmm0, xmm1, xmm2vaddps ymm0, ymm1, ymm2。(大多数整数指令的256位版本仅在AVX2中可用,而AVX仅提供128位版本。有一些例外,例如vptest ymm, ymm在AVX1中。vmovdqu如果您将其视为“整数”指令)。

标量指令(如vmovdvcvtss2si和)vcvtsi2ss仅适用于XMM寄存器。读取YMM寄存器与读取XMM寄存器在逻辑上没有什么不同,但是对于XMM与YMM而言,写入低位元素(并保持其他元素vcvtsi2ss不变,就像设计欠佳的设计一样)会有所不同,因为YMM版本会保留上车道未清零。


但是在机器代码编码中不存在带有ymm的标量,即使对于真正有用的指令(如vpinsrd/ vpextrd(插入/提取标量))也是如此。

请注意,即使读取XMM寄存器并仅使用低标量元素在逻辑上与YMM相同,但对于实际实现而言,它并不相同。读取YMM寄存器表示AVX-256指令,该指令必须将CPU移出“已保存的高位”状态(对于具有SSE / AVX过渡/状态的Intel CPU)。

在任何情况下,vcvtss2si rax, ymm0都是不可编码的,并且汇编器不会神奇地将其汇编为vcvtss2si rax, xmm0。如果您正在用asm编写程序,那么您应该确切地知道自己在做什么。(虽然某些汇编将优化mov rax, 1mov eax, 1你,所以让你得逞的写作ymm作为源寄存器是可行的。但是让你写ymm的目的寄存器vcvtsi2ss会改变的意思,所以为了保持一致性,最好的是它不会做任何)。