首页/指令库/VFWMACC-VV
VFWMACC.VV

RISC-V VFWMACC.VV 指令详解

指令手册OPFVV

拓宽融合乘加:vs1[i] 与 vs2[i] 为 SEW 宽乘数,宽 vd[i] 为 2*SEW 加数和结果;(vs1[i] * vs2[i]) + vd[i]。

指令语法

vfwmacc.vv vd, vs1, vs2, vm
操作数说明
语法 vfwmacc.vv vd, vs1, vs2[, v0.t];32 位 OP-V:opcode=1010111、funct3=001、funct6=111100。先读取旧 vd 宽加数,再覆盖它。
窄向量源 EEW=SEW、EMUL=LMUL;vd 的 EEW=2×SEW、EMUL=2×LMUL。EMUL=2/4/8 的组起点按组大小对齐,EMUL>8 保留。vd 同时是宽源,因此窄乘数不能与宽 vd 组共享寄存器;同名窄源必须读取相同初值。
逐活动元素计算 (vs1[i] * vs2[i]) + old vd[i],乘积不先舍入,只在最终宽结果按动态 frm 舍入。两个窄乘数都是向量源。
省略 v0.t 为 vm=1;写出为 vm=0。活动元素满足 vstart≤i<vl 且掩码允许,仅活动元素异常累积到 fflags。masked 目标不得含 v0;同一寄存器不能同时作为不同 EEW 的数据源和掩码源读取。
prestart 不更新也不产生异常;vl=0 或 vstart≥vl 时所有目标元素包括 tail 均不更新。其余 inactive/tail 按 vma/vta 处理,ta/ma 不保证清零;成功执行复位 vstart=0。
V 1.0 可用于 RV32/RV64,依赖 F/D;须支持所需格式、合法 vtype、VS/FS 已启用。H 且虚拟化 V=1 时 vsstatus.VS/FS 也须启用。所有向量浮点指令要求有效 frm,即使不按其舍入或 vl=0;无效 frm 使用保留,vxrm 不参与。动画固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、ta/ma 和有限输入,非完整浮点模拟器。
V向量乘法/乘加浮点

指令行为说明

VFWMACC.VV 按官方 RVV 语义覆盖宽加数:vs1[i] 与 vs2[i] 是 SEW 宽乘数,vd[i] 同时是 2*SEW 宽输入和结果。每个活动元素执行 (vs1[i] * vs2[i]) + vd[i],以一次融合浮点运算舍入到宽结果格式。vm=0 时 v0.t 控制元素是否执行;本页面的可交互示例固定展示 SEW=32 到 binary64 的可核验路径。

VFWMACC.VV 指令解析与执行动画

从 OP-V 编码解码到逐元素拓宽融合乘加:两个 SEW=32 乘数与 2*SEW=64 的宽 vd[i] 在一次 binary64 融合运算中生成结果;第二乘数来自 same-lane vs1。

输入的指令
vfwmacc.vv
执行环境
LMULm1本动画固定的寄存器组倍数
VLEN4096固定向量寄存器长度(bits)
VLMAX128m1 下的最大元素数
vstart0本动画不展示 prestart 元素
frmRNE固定 RNE 的有限教学环境;真实指令使用动态 frm
FP stateFS enabledFS=Off 会触发非法指令;本动画固定展示 FS 已启用的架构路径
acc/dest EEW64vd 是 FP64 宽加数和结果
vta/vmata, ma尾部/非活动元素策略
opcode1010111OP-V 主操作码
编码字段
0xf0861257
31..26
25
24..20
19..15
14..12
11..7
6..0
111100
funct6
0
vm
01000
vs2
01100
vs1
001
funct3
00100
vd
1010111
OP-V
执行数据路径

lane 0: fma(1, 0.5, 0.5) -> 1

显示的 lane 与当前步骤高亮同步;其余逐元素结果位于下方。

步骤 1 / 15
读取 OP-V 编码字段

V 扩展浮点指令使用 OP-V 主操作码,字段包含 funct6、源寄存器、vm、funct3、vd 和 opcode。

逐元素结果
长向量在模块内部横向滚动,不造成页面溢出。
i=0活动
fma(1, 0.5, 0.5)
1
i=1活动
fma(1.5, 1, -1)
0.5
i=2跳过
v0.t=0,不执行
--
i=3活动
fma(2.5, 2, -2.5)
2.5
i=4活动
fma(-3, 2.5, 4)
-3.5
i=5活动
fma(3.5, 3, -4.5)
6
i=6跳过
v0.t=0,不执行
--
i=7活动
fma(4.5, 4, -8.5)
9.5
本模型固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、合法 vtype、VS/FS 已启用及 ta/ma。窄乘数先表示为 binary32,旧 vd 为 binary64;融合运算只在最终 binary64 结果舍入一次(RNE)。同名窄源必须有相同初始位模式。宽 vd 源组不能与窄乘数共享寄存器。非活动与尾部元素不显示确定值;VL=0 不更新任何目标元素。NaN、无穷、fflags 和微架构周期不在模型范围;真实指令仍按官方浮点规则处理这些条件。

快速理解与检索要点

先把 vs1[i] 与 vs2[i] 作为 SEW 宽乘数读取,再与宽 vd[i] 按 (vs1[i] * vs2[i]) + vd[i] 融合;vd[i] 被结果覆盖。

官方将所有 widening FMA 定义为覆盖宽加数:乘数输入为 SEW,vd 加数和目的元素为 2*SEW。
本条的每元素公式为 vd[i] = (vs1[i] * vs2[i]) + vd[i]。
编码为 opcode=1010111 (OP-V)、funct3=001 (OPFVV)、funct6=111100。
只执行 vl 中的活动元素;vm=0 时由 v0.t 决定元素是否执行。
浮点算术采用 frm;本交互动画以 RNE 展示有限 binary32 到 binary64 的精确融合计算。

向量执行上下文

语法 vfwmacc.vv vd, vs1, vs2[, v0.t];32 位 OP-V:opcode=1010111、funct3=001、funct6=111100。先读取旧 vd 宽加数,再覆盖它。

窄向量源 EEW=SEW、EMUL=LMUL;vd 的 EEW=2×SEW、EMUL=2×LMUL。EMUL=2/4/8 的组起点按组大小对齐,EMUL>8 保留。vd 同时是宽源,因此窄乘数不能与宽 vd 组共享寄存器;同名窄源必须读取相同初值。

逐活动元素计算 (vs1[i] * vs2[i]) + old vd[i],乘积不先舍入,只在最终宽结果按动态 frm 舍入。两个窄乘数都是向量源。

省略 v0.t 为 vm=1;写出为 vm=0。活动元素满足 vstart≤i<vl 且掩码允许,仅活动元素异常累积到 fflags。masked 目标不得含 v0;同一寄存器不能同时作为不同 EEW 的数据源和掩码源读取。

prestart 不更新也不产生异常;vl=0 或 vstart≥vl 时所有目标元素包括 tail 均不更新。其余 inactive/tail 按 vma/vta 处理,ta/ma 不保证清零;成功执行复位 vstart=0。

V 1.0 可用于 RV32/RV64,依赖 F/D;须支持所需格式、合法 vtype、VS/FS 已启用。H 且虚拟化 V=1 时 vsstatus.VS/FS 也须启用。所有向量浮点指令要求有效 frm,即使不按其舍入或 vl=0;无效 frm 使用保留,vxrm 不参与。动画固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、ta/ma 和有限输入,非完整浮点模拟器。

The RISC-V Instruction Set Manual, Volume I: Unprivileged Architecture — Version 20260120, Chapter 31

常见使用场景

SEW 乘数与 2*SEW 宽加数

假定 V/VS/FS 已启用、合法 e32,m1、所需格式受支持、frm=RNE、VLMAX≥4、a0=4;vsetvli 后 vl=4、vstart=0。省略 v0.t,未掩码:old v4/v5(binary64)=[1,2,-3,4], v8=[3,-1,2,5], v12=[2,4,-2,0] → v4/v5=[7,-2,-7,4]。tail 按 ta 处理,不保证清零。

活动元素融合乘加

假定 V/VS/FS 已启用、合法 e32,m1、所需格式受支持、frm=RNE、VLMAX≥4、a0=4;vsetvli 后 vl=4、vstart=0。省略 v0.t,未掩码:old v4/v5(binary64)=[1,2,-3,4], v8=[3,-1,2,5], v12=[2,4,-2,0] → v4/v5=[7,-2,-7,4]。tail 按 ta 处理,不保证清零。

使用前检查清单

语法检查
  • 语法 vfwmacc.vv vd, vs1, vs2[, v0.t];32 位 OP-V:opcode=1010111、funct3=001、funct6=111100。先读取旧 vd 宽加数,再覆盖它。
  • 窄向量源 EEW=SEW、EMUL=LMUL;vd 的 EEW=2×SEW、EMUL=2×LMUL。EMUL=2/4/8 的组起点按组大小对齐,EMUL>8 保留。vd 同时是宽源,因此窄乘数不能与宽 vd 组共享寄存器;同名窄源必须读取相同初值。
语义检查
  • 逐活动元素计算 (vs1[i] * vs2[i]) + old vd[i],乘积不先舍入,只在最终宽结果按动态 frm 舍入。两个窄乘数都是向量源。
  • 省略 v0.t 为 vm=1;写出为 vm=0。活动元素满足 vstart≤i<vl 且掩码允许,仅活动元素异常累积到 fflags。masked 目标不得含 v0;同一寄存器不能同时作为不同 EEW 的数据源和掩码源读取。
  • prestart 不更新也不产生异常;vl=0 或 vstart≥vl 时所有目标元素包括 tail 均不更新。其余 inactive/tail 按 vma/vta 处理,ta/ma 不保证清零;成功执行复位 vstart=0。
  • V 1.0 可用于 RV32/RV64,依赖 F/D;须支持所需格式、合法 vtype、VS/FS 已启用。H 且虚拟化 V=1 时 vsstatus.VS/FS 也须启用。所有向量浮点指令要求有效 frm,即使不按其舍入或 vl=0;无效 frm 使用保留,vxrm 不参与。动画固定 SEW=32、LMUL=m1、VLEN=4096、vstart=0、ta/ma 和有限输入,非完整浮点模拟器。

容易混淆 / 常见误区

官方公式是 vd[i] = (vs1[i] * vs2[i]) + vd[i];vd 是宽加数且被结果覆盖。
两个乘数为 SEW 宽,vd 为 2*SEW 宽;不要把本指令当作普通单宽 FMA 或纯 VFWMUL。
融合乘加只在最终宽结果处舍入,不应拆成先舍入乘积再相加的两步模型。
vd 也是宽源;窄乘数不得与宽 vd 组共享寄存器,否则会在同一指令中以不同 EEW 读取该寄存器。

常见问题

vd 是仅输出寄存器吗?

不是。官方定义中 vd 是 2*SEW 宽加数,也会被最终结果覆盖;动画将它作为可编辑的累加器输入显示。