我试图了解特定的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。

英特尔指令集参考手册具有以下描述:


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

如果转换不精确,则返回的值将根据
到MXCSR寄存器或嵌入式中的舍入控制位
舍入控制位。如果转换结果不能表示为
目标格式,浮点无效异常为
引发,并且如果屏蔽了此异常,则整数值2w – 1为
返回,其中w表示目标中的位数
格式。

源操作数是ZMM / YMM / XMM寄存器,512/256/128位存储器
位置,或从32位存储器广播的512/256/128位向量
位置。目标操作数是ZMM / YMM / XMM寄存器
有条件地使用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字段。

关于assembly - AVX512舍入模式如何工作(或者NDISASM只是感到困惑)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38376860/

10-11 15:32