Skip to content

ADDPD:打包双精度浮点加法

ADDPD(Add Packed Double-Precision Floating-Point Values)是 SSE2 指令。 它把两个 128 位操作数分别看成两个 IEEE 754 双精度浮点数,对相同位置的元素执行加法,再将两项结果写回目标 XMM 寄存器。

操作码
66 0F 58 /r
指令集
SSE2
英文全称
Add Packed Double-Precision Floating-Point Values
参考资料
INTEL SDM
页码
137
01ADDPD02xmm003xmm1/m128
01
指令助记符ADDPDmnemonic

Add Packed Double-Precision Floating-Point Values,对两个打包的双精度浮点元素执行加法。

02
目标与第一源操作数xmm0destination

保存第一个 128 位操作数;运算完成后,其原值被两个结果覆盖。

03
第二源操作数xmm1/m128source

可以是 XMM 寄存器,也可以是包含两个 float64 元素的 128 位内存操作数。

ADDPD · PACKED REGISTER OPERATION · 128 BITS2 × FLOAT64
xmm0(原值)128 BITS / XMM REGISTER
xmm0[127:0]
xmm0[1]2FLOAT64
xmm0[0]1FLOAT64
xmm1(源)128 BITS / XMM REGISTER
xmm1[127:0]
xmm1[1]4FLOAT64
xmm1[0]3FLOAT64
xmm0(结果)128 BITS / XMM REGISTER
xmm0[127:0]
xmm0[1]6FLOAT64
xmm0[0]4FLOAT64
每个圆球代表一个 FLOAT64 元素强调背景:加法结果图中高索引在左、低索引在右

其等价操作是:

text
DEST[63:0]   = DEST[63:0]   + SRC[63:0]
DEST[127:64] = DEST[127:64] + SRC[127:64]

注意点

lane独立性

对应位置是两个 64 位元素(lane),而不是把 128 个二进制位分别相加。 每条 lane 内部执行一次完整的浮点加法,符号位、指数位和尾数位会按 IEEE 754 规则共同参与结果计算。 两条 lane 彼此独立,不会发生跨 lane 的进位。

内存对齐

addpd如果使用内存操作数,必须是16字节对齐,否则会触发异常。 但是 vaddpd 的内存操作数不需要对齐!

数据可能未对齐时,可先用 MOVUPD 载入 XMM 寄存器,再执行寄存器形式的 ADDPD

标志位

只会更新 MXCSR。 浮点指令不会更新 RFLAGS 标志位。

衍生指令

指令前缀指令名指令集特点
VEXVADDPDAVX256 位,支持三个独立操作数
EVEXVADDPDAVX512F512位,支持掩码和64位广播

一个可运行的例子

下面使用 Intel 语法。内存中的低地址元素进入 XMM 寄存器的低 64 位:

asm
section .data
align 16
a: dq 1.5, 10.0
b: dq 2.25, -4.0

section .text
movapd xmm0, [a]       ; xmm0 = { 10.0, 1.5 }
addpd  xmm0, [b]       ; xmm0 = {  6.0, 3.75 }

花括号在注释中按“高位在左、低位在右”书写;内存却按低地址到高地址依次存放 1.510.0。 阅读 SIMD 代码时,这两种观察顺序很容易混淆。

SIGNAL MAINTAINED · BUILT FROM MARKDOWN