Home/Instructions/VFWNMSAC-VV
VFWNMSAC.VV

RISC-V VFWNMSAC.VV Instruction Details

Instruction ManualOPFVV

widening negate multiply-subtract-accumulator: vs1[i] and vs2[i] are SEW-wide multipliers, while wide vd[i] is the 2*SEW addend and result; -(vs1[i] * vs2[i]) + vd[i].

Instruction Syntax

vfwnmsac.vv vd, vs1, vs2, vm
Operand Breakdown
vd: destination vector register group.
vs2/vs1 or scalar source: selected by suffixes such as .vv, .vx, .vi, or .vf.
vm: when present, vm=0 uses v0 as the execution mask and vm=1 is unmasked.
VVector Multiply-AddFloating-Point

Instruction Behavior

VFWNMSAC.VV overwrites the wide addend under the official RVV semantics: vs1[i] and vs2[i] are SEW-wide multipliers, while vd[i] is both the 2*SEW-wide input and result. Each active element evaluates -(vs1[i] * vs2[i]) + vd[i] with one fused rounding to the wide result format. With vm=0, v0.t controls lane execution; this page's interactive example fixes a checkable SEW=32-to-binary64 path.

VFWNMSAC.VV Decode And Execute Animation

Decode the OP-V encoding and execute widening fused multiply-add lane by lane: two SEW=32 multipliers and the 2*SEW=64 wide vd[i] produce one binary64 fused result; the second multiplier is same-lane vs1.

Instruction input
vfwnmsac.vv
Execution context
LMULm1fixed register-group multiplier
VLEN4096fixed vector-register length (bits)
VLMAX128maximum element count at m1
vstart0prestart elements are outside this animation
frmRNEfinite teaching context fixed at RNE; the architectural instruction uses dynamic frm
FP stateFS enabledFS=Off raises illegal instruction; this animation fixes the architectural state to FS enabled
acc/dest EEW64vd is the FP64 wide addend and result
vta/vmata, matail/inactive policy
opcode1010111OP-V major opcode
Encoding fields
0xfc861257
31..26
25
24..20
19..15
14..12
11..7
6..0
111111
funct6
0
vm
01000
vs2
01100
vs1
001
funct3
00100
vd
1010111
OP-V
Execution data path

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

This lane follows the current-step highlight; the remaining lane results appear below.

Step 1 / 15
Read OP-V encoding fields

V-extension FP instructions use the OP-V major opcode, with funct6, source registers, vm, funct3, vd, and opcode fields.

Lane results
Long vectors scroll inside this module without page overflow.
i=0active
fma(-(1 * 0.5), +0.5)
0
i=1active
fma(-(1.5 * 1), +-1)
-2.5
i=2skip
v0.t=0, not executed
--
i=3active
fma(-(2.5 * 2), +-2.5)
-7.5
i=4active
fma(-(-3 * 2.5), +4)
11.5
i=5active
fma(-(3.5 * 3), +-4.5)
-15
i=6skip
v0.t=0, not executed
--
i=7active
fma(-(4.5 * 4), +-8.5)
-26.5
In the fixed VLEN=4096, LMUL=m1, vstart=0 teaching context, vs1[i] or f[rs1] and vs2[i] are read as SEW=32 / binary32, while vd[i] is read and written as 2*SEW=64 / binary64. Each active lane evaluates -(vs1 * vs2) + vd exactly, then rounds once to binary64 under RNE; BigInt intermediates prevent an incorrect double-rounding model. The architectural instruction uses dynamic frm, reserved frm encodings cannot execute, and FS=Off raises illegal instruction. Finite inputs are interactively checkable; NaNs, infinities, and exception flags remain governed by the official RVV FP rules.

Quick Understanding & Search Notes

Read vs1[i] and vs2[i] as SEW-wide multipliers, then fuse them with wide vd[i] as -(vs1[i] * vs2[i]) + vd[i]; vd[i] is overwritten by the result.

The official widening FMA definition overwrites the wide addend: multiplier inputs are SEW, while the vd addend and destination elements are 2*SEW.
This instruction's per-element formula is vd[i] = -(vs1[i] * vs2[i]) + vd[i].
The encoding is opcode=1010111 (OP-V), funct3=001 (OPFVV), funct6=111111.
Only active elements within vl execute; with vm=0, v0.t decides whether a lane executes.
FP arithmetic uses frm; this interactive animation shows an exact fused calculation for finite binary32-to-binary64 inputs under RNE.

Vector Execution Context

When reading VFWNMSAC.VV, do not stop at the mnemonic. Official V-extension semantics also depend on the current vl, vtype, and mask state. .vv: two vector sources participate element by element.

Check vl first

The current vl determines the number of body elements. Typical code executes vsetvli, vsetivli, or vsetvl before this instruction.

Then check vtype

The current vtype supplies SEW, LMUL, tail policy, and mask policy; these affect element width, register-group size, and inactive/tail destination elements.

Then check vm/v0

For ordinary vector instructions with vm, vm=0 uses v0 as the execution mask and vm=1 is unmasked. A few forms such as VMERGE use v0 as data-selection input.

Official source: RISC-V V Standard Extension for Vector Operations

Common Usage Scenarios

Alternating Add/Sub

Understand this scenario with real code like «vsetvli t0, a0, e32, m1, ta, ma vfwnmsac.vv v4, v8, v12 # vd[i] = -(v12[i] * v8[i]) + vd[i]».

Pre-Use Checklist

Syntax Check
  • Confirm the current instruction format is OPFVV.
  • Confirm the operand order matches the example.
Semantic Check
  • Ensure the destination register usage is compatible with the calling convention.
  • Confirm this is not the lower-level form of a pseudo-instruction expansion.

Pitfalls / Common Confusions

The official formula is vd[i] = -(vs1[i] * vs2[i]) + vd[i]; vd is the wide addend overwritten by the result.
The two multipliers are SEW wide and vd is 2*SEW wide; do not treat this as scalar-width FMA or plain VFWMUL.
FMA rounds only at the final wide result; do not model it as a rounded product followed by addition.

FAQ

Is vd output-only?

No. In the official definition, vd is the 2*SEW-wide addend and is overwritten by the final result; the animation exposes it as an editable accumulator input.