首页 > 解决方案 > VPCMPB 的操作数

问题描述

我在 Intel 内在函数指南上看到,您vpcmpb无需立即使用即可实现相等比较的效果:https ://software.intel.com/sites/landingpage/IntrinsicsGuide/#techs=AVX_512&expand=6816,804,804,4867,351,804 ,4222,914&text=vpcmpb

我尝试编写以下汇编指令:vpcmpb %zmm30, %zmm0, %k1(g++ 语法),比较相等zmm30zmm0,将结果写入k1. 但是,汇编器抱怨操作数数量错误。这里发生了什么?

标签: assemblyx86-64intrinsicsavx512

解决方案


执行此操作有 3 个有效的机器操作码:

  • vpcmpeqb k, zmm, zmm
    ( MMX/SSE2/AVX2操作码EVEX 形式66 0F 74[v]pcmpeq [xy]mm, [xy]mm。这些从未立即生效,只有带eq符号gt的谓词可用作不同的操作码)

  • vpcmpbvpcmpub立即0
    (只有 EVEX 形式的新指令,EVEX.512.66.0F3A.W0 3F3E)。

在 asm source中,汇编器允许您使用vpcmpleb k, zmm, zmm例如作为更有意义的编写方式,如Intel 的 vol.2 手册中的表 5-17vpcmpb k, z, z, 2中所建议的那样。即谓词作为助记符的一部分,暗示直接。

该表包括一行VPCMPEQ* reg1, reg2, reg3-> ,但在实际汇编程序中VPCMP* reg1, reg2, reg3, 0,较短的非立即形式优先。vpcmpeqb k, zmm, zmm

NASM 源与objdump -S -drwC -Mintel反汇编混合。(使用气体组装的结果相同.intel_syntax noprefix):

                                vpcmpeqb k1, zmm0, zmm1
   0:   62 f1 7d 48 74 c9       vpcmpeqb k1,zmm0,zmm1    # 74 opcode

                                vpcmpb k1, zmm0, zmm1, 0
   6:   62 f3 7d 48 3f c9 00    vpcmpeqb k1,zmm0,zmm1    # 3f opcode

                                vpcmpequb k1, zmm0, zmm1
   d:   62 f3 7d 48 3e c9 00    vpcmpequb k1,zmm0,zmm1   # 3e opcode

                                vpcmpub k1, zmm0, zmm1, 0
  14:   62 f3 7d 48 3e c9 00    vpcmpequb k1,zmm0,zmm1   # 3e opcode

有趣的是,NASM/GAS 将vpcmpb k1, zmm0, zmm1, 0按照书面形式组装成带有立即数的形式。但是objdump会将其反汇编回vpcmpeqb k1,zmm0,zmm1,与非立即操作码相同,因此这是反汇编/重新组装往返会更改机器代码的情况之一。(当然不是指令的架构效果)

NASM / GAS 不会为您优化vpcmpequbvpcmpeqb因此在比较整数相等时始终避免使用无符号版本。


内在指南中的错误

如果您使用 asm 编写,请查看 asm 参考手册(HTML 摘录https://www.felixcloutier.com/x86/vpcmpb:vpcmpub或英特尔的原始 PDF),而不是 Intrinsics 指南。尤其是当您在某事所说的内容与工具和/或 CPU 似乎在做什么之间遇到任何谜团或分歧时!

众所周知,内在函数指南存在错误(尽管人们在英特尔论坛上报告它们时它们确实得到了修复)。特别有可能在对正确使用 C/C++ 内在函数不重要的部分中看到错误。

英特尔的 asm 手册也并非不可能出现错误,但不会像为已发布的指令集遗漏指令的整个机器操作码形式那样重要。

如果没有vpcmpb k, zmm, zmm明确的立即数,在真实的 asm 源中或作为机器代码的描述,绝不是有效的,所以是的,这绝对是内在指南中的错误。


vpcmpeqb %zmm, %zmm, %k具有反向操作数列表的asm 语法$immediate是“AT&T 语法”。它恰好是 GAS 默认用于.s/.S文件的一种,但您可以使用.intel_syntax noprefix.

对单个指令使用内联汇编通常没有意义——编译器通常在内部函数方面做得足够好,尽管对于 AVX-512 掩码的东西可能并不总是如此。


推荐阅读