是否可以将 ymm16 - ymm31 用于 AVX2 vpcmpeq{size} 指令?

Noa*_*oah 4 assembly x86-64 avx avx2 avx512

我想知道是否可以按照以下方式做一些事情:

vpcmpeqb %ymm16, %ymm17, %ymm16
Run Code Online (Sandbox Code Playgroud)

尝试使用 gcc 进行编译,我得到:

Assembler messages: Error: unsupported instruction `vpcmpeqb'
Run Code Online (Sandbox Code Playgroud)

AFAICT 这是不可能的felixcloutier说唯一的 EVEX 前缀指令cmpeq有一个掩码目的地,但可能我遗漏了一些东西,或者直接用字节编码来做到这一点。

谢谢!

Pet*_*des 6

X / YMM16..31 完全需要 EVEX 才能访问。

您不能将它们与 AVX1 / AVX2 形式的指令一起使用。
所以不,要么只比较掩码寄存器,要么使用 ymm0..15。

VEX 前缀 + modrm 每条指令总共只有 4 位,因此 AVX1/2 编码无法使用需要 5 位的寄存器编号。


GAS 的错误信息没有帮助。也许它基于仅使用 AVX-512 寄存器的使用决定它是 EVEX 形式,然后注意到它是错误的操作数集。

NASM 说“操作码和操作数的无效组合”也不是很具体,但至少是正确的。

clang 的内置汇编器可能是最好的:

foo.s:1:26: error: invalid operand for instruction
vpcmpeqb %ymm16, %ymm17, %ymm16
                         ^~~~~~
Run Code Online (Sandbox Code Playgroud)

  • @Noah:vpxor-zeroing你使用的regs*不*相当于vzeroupper,以避免[SSE指令的后续问题](/sf/ask/2891264631/ -times-slower-without-vzeroupper-on-skylake/41349852#41349852)。我忘记是否有问答明确确认这一点,但[this](/sf/ask/3431373011/)是相关的。也许您可以在事务之后使用“vzeroupper”,也许可以在外部函数中使用“_mm_zeroupper()”,如果您要调用手写的 asm 函数作为事务的一部分,因此不能将其放在那里。 (2认同)