Skip to content

VADDPD:向量双精度浮点加法

VADDPDADDPD 的非破坏性向量形式。VEX 编码提供 128/256 位运算;EVEX 编码进一步提供 512 位向量、写掩码、零化、广播和嵌入舍入。

操作码
EVEX.512 · 66 0F 58 /r
指令集
AVX-512F
英文全称
Vector Add Packed Double-Precision Floating-Point Values
参考资料
INTEL SDM
页码
137
01VADDPD02zmm003{k1}04{z}05zmm106zmm2/m512/m64bcst07{er}
01
向量加法VADDPDmnemonic

对对应位置的双精度浮点元素执行加法,使用独立的目标操作数。

02
目标操作数zmm0destination

保存 8 个 float64 结果;采用合并掩码时,还提供被屏蔽元素的旧值。

03
写掩码{k1}writemask

k1 的低 8 位分别控制 8 个目标元素是否写入。

04
零化策略{z}modifier

未选中的元素写零;省略 {z} 时保留目标寄存器中的旧值。

05
第一源操作数zmm1source

提供第一组 8 个双精度浮点元素。

06
第二源操作数zmm2/m512/m64bcstsource

可以是向量寄存器、512 位内存向量,或广播到所有 lane 的单个 64 位内存值。

07
嵌入舍入{er}modifier

寄存器源的 EVEX.512 形式可覆盖 MXCSR 舍入模式并抑制精度异常。

AVX-512VL 只用于 128/256 位 EVEX 形式;512 位 ZMM 形式只要求 AVX-512F。不带掩码的 128/256 位 VEX 形式属于 AVX。

指令形式

编码语法元素数指令集
VEX.128vaddpd xmm1, xmm2, xmm3/m1282AVX
VEX.256vaddpd ymm1, ymm2, ymm3/m2564AVX
EVEX.128vaddpd xmm1 {k1}{z}, xmm2, xmm3/m128/m64bcst2AVX-512F + AVX-512VL
EVEX.256vaddpd ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst4AVX-512F + AVX-512VL
EVEX.512vaddpd zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst {er}8AVX-512F

所有 VEX/EVEX 形式都有三个显式操作数,因此 DEST 不必覆盖 SRC1

text
DEST[i] = SRC1[i] + SRC2[i]

与传统 SSE 编码不同,写入 XMM 或 YMM 目标时,对应 ZMM 寄存器中高于当前向量长度的位会被清零。

写掩码

EVEX 形式以 64 位元素 为掩码粒度。k1[j] 控制第 jfloat64 结果;XMM、YMM、ZMM 分别只使用掩码的低 2、4、8 位。

下图以圆球表示完整的 64 位元素,并在圆球内标注寄存器元素名与位范围。点击 k1 的各位可以启用或屏蔽对应 lane,并可切换合并与 {z} 零化策略。

MASKED VADDPD · 8 × FLOAT64
k1
zmm1 · SRC1
zmm1[511:0]
zmm1[7]8FLOAT64
zmm1[6]7FLOAT64
zmm1[5]6FLOAT64
zmm1[4]5FLOAT64
zmm1[3]4FLOAT64
zmm1[2]3FLOAT64
zmm1[1]2FLOAT64
zmm1[0]1FLOAT64
zmm2 · SRC2
zmm2[511:0]
zmm2[7]16FLOAT64
zmm2[6]15FLOAT64
zmm2[5]14FLOAT64
zmm2[4]13FLOAT64
zmm2[3]12FLOAT64
zmm2[2]11FLOAT64
zmm2[1]10FLOAT64
zmm2[0]9FLOAT64
zmm0 · DEST
zmm0[511:0]
zmm0[7]24FLOAT64
ADD
zmm0[6]23FLOAT64
MERGE
zmm0[5]20FLOAT64
ADD
zmm0[4]21FLOAT64
MERGE
zmm0[3]20FLOAT64
MERGE
zmm0[2]14FLOAT64
ADD
zmm0[1]18FLOAT64
MERGE
zmm0[0]10FLOAT64
ADD

点击 k1 位选择 lane;切换 merge / {z} 可观察被屏蔽结果的差异。每个圆球表示一个 FLOAT64 元素。

VADDPD · REGISTER OPERATIONX86 · ARITHMETIC
元素数量向量宽度 ÷ 元素宽度8
vs2 · zmm1第一来源
zmm1[511:0]
vs2[7]864 bits
vs2[6]764 bits
vs2[5]664 bits
vs2[4]564 bits
vs2[3]464 bits
vs2[2]364 bits
vs2[1]264 bits
vs2[0]164 bits
vs1 · zmm2第二来源
zmm2[511:0]
vs1[7]1664 bits
vs1[6]1564 bits
vs1[5]1464 bits
vs1[4]1364 bits
vs1[3]1264 bits
vs1[2]1164 bits
vs1[1]1064 bits
vs1[0]964 bits
vd · zmm0(结果)arithmetic
zmm0[511:0]
vd[7]24arithmetic
vd[6]22arithmetic
vd[5]20arithmetic
vd[4]18arithmetic
vd[3]16arithmetic
vd[2]14arithmetic
vd[1]12arithmetic
vd[0]10arithmetic
每个圆球代表一个完整元素强调背景:目标写入高索引在左、低索引在右
text
for j = 0 .. element_count - 1:
    if k1[j] == 1:
        DEST[j] = SRC1[j] + SRC2[j]
    else if {z}:
        DEST[j] = 0.0
    else:
        DEST[j] = OLD_DEST[j]

假设从低 lane 到高 lane:

text
zmm1     = [10, 20, 30, 40, 50, 60, 70, 80]
zmm2     = [ 1,  2,  3,  4,  5,  6,  7,  8]
旧 zmm0  = [99, 99, 99, 99, 99, 99, 99, 99]
k1       = 1010_0101b
lanek1[j]加法结果合并掩码结果{z} 结果
01111111
1022990
21333333
3044990
4055990
51666666
6077990
71888888
asm
vaddpd zmm0 {k1},    zmm1, zmm2   ; merge:屏蔽位置保留旧 zmm0
vaddpd zmm0 {k1}{z}, zmm1, zmm2   ; zero:屏蔽位置写入 +0.0

编码中不选择写掩码时,所有 lane 都会写入。k0 表示这种“无掩码”编码状态,通常不能在该语法位置显式写成 {k0}

广播与舍入

m64bcst 从内存读取一个 float64,复制到所有 lane 后再相加:

asm
vaddpd zmm0 {k1}{z}, zmm1, [scalar] {1to8}

EVEX.512 的寄存器源形式可以使用 {rn-sae}{rd-sae}{ru-sae}{rz-sae}。它们分别指定就近、向下、向上和向零舍入,并启用 SAE;内存源使用广播时,EVEX.b 已承担广播含义,不能同时表示嵌入舍入。

标志位

浮点异常和舍入默认由 MXCSR 控制,EFLAGS 不受影响。

参考

SIGNAL MAINTAINED · BUILT FROM MARKDOWN