4

我正在尝试了解特定的 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指令集参考手册有如下描述:

将源操作数中的十六个压缩单精度浮点值转换为目标操作数中的十六个无符号双字整数。

当转换不精确时,返回的值根据 MXCSR 寄存器中的舍入控制位或嵌入的舍入控制位进行舍入。如果转换后的结果无法以目标格式表示,则引发浮点无效异常,如果此异常被屏蔽,则返回整数值 2w – 1,其中 w 表示目标格式的位数。

源操作数是一个 ZMM/YMM/XMM 寄存器,一个 512/256/128 位内存位置,或从 32 位内存位置广播的 512/256/128 位向量。目标操作数是一个 ZMM/YMM/XMM 寄存器,使用写掩码 k1 有条件地更新。

4

1 回答 1

3

操作码被编码为 0x62 P0 P1 P2 ...见此处第 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字段。

于 2016-07-14T17:48:46.060 回答