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 = xmm
和 2 = zmm
。如果设置了b
,则L'L
被重新解释为静态舍入模式,长度假定为zmm(512位)。
NDISASM 没有正确解释 EVEX.B 位,因此 EVEX.L'L
字段也没有正确解释。
我正在尝试了解特定的 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 = xmm
和 2 = zmm
。如果设置了b
,则L'L
被重新解释为静态舍入模式,长度假定为zmm(512位)。
NDISASM 没有正确解释 EVEX.B 位,因此 EVEX.L'L
字段也没有正确解释。