AVX512矢量长度和SAE控制

vit*_*oft 5 x86 assembly avx512

我的问题是关于EVEX编码不四舍五入语义打包REG-REG的指令允许SAE控制(禁止所有的例外),如VMIN*,*VCVTT,VGETEXT*,VREDUCE*,VRANGE*等英特尔只全声明SAE-意识512位向量长度,例如

VMINPD xmm1 {k1}{z}, xmm2, xmm3
VMINPD ymm1 {k1}{z}, ymm2, ymm3
VMINPD zmm1 {k1}{z}, zmm2, zmm3{sae}
Run Code Online (Sandbox Code Playgroud)

但我没有看到为什么SAE不能应用于使用xmm或ymm寄存器的指令的原因.

英特尔指令集扩展编程参考的第4.6.4章中, 表4-7表示在没有舍入语义位的指令中,EVEX.b指定应用SAE,并且位EVEX.L'L指定显式向量长度:

00b: 128bit (XMM)
01b: 256bit (YMM)
10b: 512bit (ZMM)
11b: reserved
Run Code Online (Sandbox Code Playgroud)

所以他们的组合应该是合法的.

然而,NASM汇编vminpd zmm1,zmm2,zmm3,{sae} 为62F1ED185DCB,即EVEX.L'L = 00b,EVEX.b = 1,由NDISASM 2.12反汇编为vminpd xmm1,xmm2,xmm3

NASM拒绝组装vminpd ymm1,ymm2,ymm3,{sae} ,NDISASM将62F1ED385DCB(EVEX.L'L = 01b,EVEX.b = 1)拆解为vminpd xmm1,xmm2,xmm3

我想知道Knights Landing CPU是如何执行的VMINPD ymm1, ymm2, ymm3{sae} (组装为62F1ED385DCB,EVEX.L'L = 01b,EVEX.b = 1):

  1. CPU抛出异常.英特尔doc表4-7具有误导性.
  2. SAE有效,CPU仅以xmm运行,与标量运算相同.NASM和NDISASM做得对,英特尔文档是错误的.
  3. SAE被忽略,根据英特尔文档中的VMINPD规范,CPU以256位运行.NASM和NDISASM是错误的.
  4. SAE有效,CPU按指令代码指定的256位运行.NASM和NDISASM是错误的,英特尔doc需要用{sae}补充装饰xmm/ymm指令.
  5. SAE有效,CPU运行时隐含的全向量大小为512位,与EVEX.L'L无关,就像允许静态舍入{er}一样.NDISASM和Intel doc表4-7都是错误的.

Ros*_*dge 4

您的VMINPD ymm1, ymm2, ymm3{sae}指令无效。根据英特尔架构指令集扩展编程参考(2016 年 2 月)中 MINPD 的指令集参考,仅允许以下编码:

\n\n
\n
66 0F 5D /r                  MINPD xmm1, xmm2/m128 \nVEX.NDS.128.66.0F.WIG 5D /r  VMINPD xmm1, xmm2, xmm3/m128\nVEX.NDS.256.66.0F.WIG 5D /r  VMINPD ymm1, ymm2, ymm3/m256\nEVEX.NDS.128.66.0F.W1 5D /r  VMINPD xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst\nEVEX.NDS.256.66.0F.W1 5D /r  VMINPD ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst\nEVEX.NDS.512.66.0F.W1 5D /r  VMINPD zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst{sae}\n
Run Code Online (Sandbox Code Playgroud)\n
\n\n

请注意,仅显示最后一个版本带有{sae}后缀,这意味着它是您可以使用它的指令的唯一形式。仅仅因为这些位的存在是为了对特定指令进行编码,并不意味着它是有效的。

\n\n

另请注意,第 4.6.3 节“EVEX 中的 SAE 支持”明确表示 SAE 不适用于 128 位或 256 位向量:

\n\n
\n

EVEX 编码系统允许使用 SAE 属性对不带舍入语义的算术浮点指令进行编码。通过设置 EVEX.b,此功能适用于标量和 512 位向量长度(仅寄存器到寄存器)。设置 EVEX.b 时,隐含 \xe2\x80\x9c 抑制所有异常\xe2\x80\x9d。[...]

\n
\n\n

但是,我不确定您的手工制作的指令是否会生成无效操作码异常,是否会简单地忽略 EVEX.b 位,或者是否会忽略 EVEX.L\'L 位。EVEX 编码的 VMINPD 指令属于 E2 类异常类,根据表 4-17 E2 类异常条件,该指令在以下任何情况下都可以生成 #UD 异常:

\n\n
\n
    \n
  • 未满足国家要求,表4-8。
  • \n
  • 与操作码无关的#UD 条件见表4-9。
  • \n
  • 操作数编码#UD条件见表4-10。
  • \n
  • Opmask 编码#UD 条件见表4-11。
  • \n
  • 如果 EVEX.L\xe2\x80\x99L != 10b (VL=512)。
  • \n
\n
\n\n

只有最后一个原因似乎适用于此,但这意味着您的指令将在带或不带修饰符的情况下生成 #UD 异常{sae}。由于这似乎与指令摘要中允许的编码直接矛盾,因此我不确定会发生什么。

\n

  • @Mysticial 我没有看到矛盾。VMINPD 不在“舍入语义”类中,因为指令摘要在任何指令版本上都没有“{er}”。表 4-7 表示这意味着 P2[6:5] 位编码 EVEX.L'L,而 VMINPD 摘要表示如果使用“{sae}”,则长度必须为 512,即。EVEX.L'L 必须为 10b。 (2认同)
  • 从设计POV来思考这个问题。表 4-7 似乎暗示英特尔最初可能“打算”允许 SAE 具有向量长度而无需舍入语义。但当需要实现硬件时,它可能会成为障碍。就目前而言,硬件不需要单独的指令类。`P2[6:5]` 位并不重要,因为舍入是无操作的。所以这就变成了#UD在无效的情况下是否有逻辑的问题。我很好奇英特尔模拟器会做什么以及它是否与实际硬件相同。 (2认同)