我正在尝试了解特定的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。
英特尔指令集参考手册有以下说明:
转换十六个打包的单精度浮点值 源操作数到十六个无符号双字整数 目的地操作数。
当转换不准确时,返回的值将被舍入 到MXCSR寄存器或嵌入式中的舍入控制位 舍入控制位。如果转换后的结果无法表示 目标格式,浮点无效异常是 如果屏蔽了这个异常,则整数值为2w - 1 返回,其中w表示目标中的位数 格式。
源操作数是ZMM / YMM / XMM寄存器,512 / 256/128位内存 位置,或从32位存储器广播的512/256/128位向量 地点。目标操作数是ZMM / YMM / XMM寄存器 使用writemask k1有条件地更新。
答案 0 :(得分:2)
操作码编码为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 = xmm
和2 = zmm
。如果设置了b
,则将L'L
重新解释为静态舍入模式,并假设长度为zmm(512位)。
NDISASM没有正确解释EVEX.B位,因此也没有解释EVEX.L'L
字段。