assembly ASM x86_64 AVX:xmm和ymm寄存器差异

p1tboqfb  于 2023-05-18  发布在  其他
关注(0)|答案(2)|浏览(401)

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

vmovups     ymm1, [r9]      
vcvtss2si   rcx, ymm1

它给了我:

error: invalid combination of opcode and operands

是关于那句台词:

vcvtss2si   rcx, ymm1

于是我写道:

vcvtss2si   rcx, xmm1

并且它按预期工作。ymm1向量的第一个值,转换为整数,现在在rcx中。
这是怎么回事?ymm1xmm1是同一个寄存器吗?

z9zf31ra

z9zf31ra1#

xmm0ymm0的下半部分,就像eaxrax的下半部分一样。
写入xmm0(使用像vaddps xmm这样的VEX编码指令,而不是传统SSE addps xmm)会将ymm0just like writing to eax zeros the upper half of rax to avoid false dependencies的上通道置零。遗留SSE指令的高位字节未归零是存在penalty for mixing AVX and legacy SSE instructions的原因。
大多数AVX指令都有128位或256位大小。例如vaddps xmm0, xmm1, xmm2vaddps ymm0, ymm1, ymm2。(大多数整数指令的256位版本仅在AVX 2中可用,AVX仅提供128位版本。有几个例外,如AVX 1中的vptest ymm, ymm。和vmovdqu,如果您将其视为“整数”指令)。
标量指令,如vmovdvcvtss2sivcvtsi2ss,只能在XMM寄存器中使用。阅读YMM寄存器与读取XMM寄存器在逻辑上没有不同,但是 * 写入 * 低元素(并保持其他元素不变,如设计不良的vcvtsi2ss)对于XMM与YMM,因为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的目标寄存器会改变含义,所以为了一致性,最好不要这样做)。

brgchamk

brgchamk2#

根据维基百科,在AVX中:
YMM寄存器的长度为256位
XMM寄存器的长度为128位,表示YMM寄存器的低128位**。
YMMXMM寄存器重叠,XMM包含在YMM中。
图自wikimedia

相关问题