AVX512 舍入模式如何工作(或者 NDISASM 只是混淆)?

How do AVX512 rounding modes work (or is NDISASM simply confused)?

我正在尝试了解特定的 AVX512F 指令 vcvtps2udq

指令的签名是VCVTPS2UDQ zmm1 {k1}{z}, zmm2/m512/m32bcst{er}。手册信息如下。

为了理解新的舍入模式,以下代码片段与 NASM (2.12.02)

组合而成
vcvtps2udq zmm0,zmm1
vcvtps2udq zmm0,zmm1,{rz-sae}
vcvtps2udq xmm0,xmm1

使用 NDISASM (2.12.02) 反汇编结果会造成很多混乱,代码如下:

62F17C4879C1      vcvtps2udq zmm0,zmm1
62F17C7879C1      vcvtps2udq xmm0,xmm1
62F17C0879C1      vcvtps2udq xmm0,xmm1

问题:第二行是用xmm寄存器反汇编的,而不是zmm寄存器(这是我所期望的)。与零舍入模式(rz-sae)有关。或者只是 NDISASM 错误,无法区分操作码 62F17C7879C1 和 62F17C0879C1。

Intel指令集参考手册有如下描述:

Converts sixteen packed single-precision floating-point values in the source operand to sixteen unsigned doubleword integers in the destination operand.

When a conversion is inexact, the value returned is rounded according to the rounding control bits in the MXCSR register or the embedded rounding control bits. If a converted result cannot be represented in the destination format, the floating-point invalid exception is raised, and if this exception is masked, the integer value 2w – 1 is returned, where w represents the number of bits in the destination format.

The source operand is a ZMM/YMM/XMM register, a 512/256/128-bit memory location, or a 512/256/128-bit vector broadcasted from a 32-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with writemask k1.

操作码编码为 0x62 P0 P1 P2 ... see here section 4.2。在这种情况下,P2 字节是

P2
48  <- vcvtps2udq zmm0,zmm1
78  <- vcvtps2udq zmm0,zmm1,{rz-sae}
08  <- vcvtps2udq xmm0,xmm1

进一步细分为以下字段

                       zmm  zmm+sae  xmm
EVEX.aaa  = P2[2:0]     0     0       0
EVEXV'    = P2[3]       1     1       1
EVEX.b    = P2[4]       0     1       0  "Broadcast/RC/SAE Context"
EVEX.L'L  = P2[6:5]     2     3       0  "Vector length/RC"
EVEX.z    = P2[7]       0     0       0

所以不同的字段是 EVEX.b 和 EVEX.L'L。根据文档,如果未设置 b,则 L'L 是 SIMD 长度,因此 0 = xmm2 = zmm。如果设置了b,则L'L被重新解释为静态舍入模式,长度假定为zmm(512位)。

NDISASM 没有正确解释 EVEX.B 位,因此 EVEX.L'L 字段也没有正确解释。