Home/Instructions/Fused Multiply-Sub Double
FMSUB.D

RISC-V FMSUB.D Instruction Details

Instruction ManualR4-type

double-precision fused multiply-subtract: rd = (rs1 * rs2) - rs3, with one final rounding according to rm.

Instruction Syntax

fmsub.d rd, rs1, rs2, rs3[, rm]
Operand Breakdown
rd, rs1, rs2, rs3: FP registers f0–f31 or their ABI names; f0 is writable, and overlapping sources use one initial value before writeback.
Optional lowercase rm defaults to dyn; rm=111 uses frm. Static 101/110 and dynamic frm=101–111 have reserved behavior.
DFloating-Point Arithmetic

Instruction Behavior

FMSUB.D uses the R4 four-register format for double-precision fused multiply-subtract. The rs1*rs2 product is not rounded or written as an intermediate result; it is combined with rs3 as one fused expression, rounded once according to rm, and written to rd.

FMSUB.D Decode And Execute Animation

Shows the D-extension double-precision R4 fused multiply-subtract flow: decode fields, read FP operands, perform FMSUB semantics, then write rd.

rd
rs1
rs2
rs3
rm
fmsub.d
,
,
,
,

Leave rm empty to use the assembly default dyn encoding and fcsr.frm below.

Execution Context
FLEN>=64 / fmt=D (01)
rounding: RNE nearest-even
fflags: initial 0
31..27
26..25
24..20
19..15
14..12
11..7
6..0
01101
rs3
01
fmt=D
01100
rs2
01011
rs1
000
rm
01010
rd
1000111
MSUB
Execution Data Path
instruction
0x6AC58547
opcode
1000111 -> MSUB
rs3/fmt
fa3(f13) + D(01) -> R4 FMSUB
rm
000 -> RNE nearest-even
rd/rs
fa0(f10) / fa1(f11) / fa2(f12) / fa3(f13)
read
Source registers not read yet
fused op
Awaiting Execute
write
Not written yet; initial fflags=0
Current Step

Fetch: show the 32-bit R4 encoding

The word is split as an R4-type instruction; FMSUB.D uses its dedicated major opcode 1000111, not the ordinary OP-FP opcode.

encoding: 0x6AC58547
syntax : fmsub.d fa0(f10), fa1(f11), fa2(f12), fa3(f13), rne
result : Not written yet; initial fflags=0

The default example (1.5 * 2.0) - 1.0 = 2.0 is exactly checkable; the fused operation rounds once at the end, so example fflags remains 0.

Double-precision Calculation
rs1
fa1(f11) = 1.5
rs2
fa2(f12) = 2.0
rs3
fa3(f13) = 1.0
result
Awaiting Execute

The default example (1.5 * 2.0) - 1.0 = 2.0 is exactly checkable; the fused operation rounds once at the end, so example fflags remains 0.

Assumes the extension is available, FS enabled, correctly NaN-boxed inputs, and initial fflags=0. Only nonzero finite exact whitelisted inputs and nonzero whitelisted results are accepted; zero and rounding/exception boundaries are outside this animation. One source register must have one initial value; rd may overlap a source, and f0 accepts writeback. Steps are teaching views.

This animation shows only D-extension ISA-visible R4 encoding, example numeric results, and fflags relationship; it does not model FPU pipelines, latency, every IEEE 754 corner case, or microarchitecture.

Quick Understanding & Search Notes

FMSUB.D's key points are R4 encoding and fused semantics: rs3 is a real third source register, and the product plus/minus term forms one exact intermediate expression that is rounded only once.

RV32/RV64 D (which depends on F), with FP state enabled; the 32-bit R4 encoding has opcode=1000111 and fmt=01 for 64-bit double precision.
The encoded field order is rs3 | fmt | rs2 | rs1 | rm | rd | opcode; this differs from ordinary OP-FP R-type instructions.
The semantic expression is rd = (rs1 * rs2) - rs3, and the fused operation is rounded once at the end according to rm/frm; behavior for reserved static or dynamic rm/frm encodings must not be assumed.
The optional assembly rm operand must be lowercase and defaults to dyn. With FLEN>64, malformed source NaN boxes are treated as canonical NaN; narrower results get upper ones. The animation executes only nonzero finite exact whitelisted inputs and nonzero whitelisted results; see static text for exceptions and rounding boundaries.

Common Usage Scenarios

Fused Floating Point

Assume RV32/RV64 D, FP state enabled, double-precision f1=1.5, f2=2, f3=1 (validly NaN-boxed for wider FLEN), and initial fflags=0: fmsub.d f0, f1, f2, f3, rne writes the exact result f0=(1.5×2)-1=2; fflags remains 0.

Numerical Computing

Assume RV32/RV64 D, FP state enabled, double-precision f1=1.5, f2=2, f3=1 (validly NaN-boxed for wider FLEN), and initial fflags=0: fmsub.d f0, f1, f2, f3, rne writes the exact result f0=(1.5×2)-1=2; fflags remains 0.

Pre-Use Checklist

Syntax Check
  • rd, rs1, rs2, rs3: FP registers f0–f31 or their ABI names; f0 is writable, and overlapping sources use one initial value before writeback.
  • Optional lowercase rm defaults to dyn; rm=111 uses frm. Static 101/110 and dynamic frm=101–111 have reserved behavior.
Semantic Check
  • Confirm rs3 participates in the fused operation and the result is rounded only once at the end.
  • Confirm the sign rules for FNMADD/FNMSUB match the intended operation.

Pitfalls / Common Confusions

FMSUB.D is a fused operation, not the same as FMUL followed by FADD/FSUB with two roundings.
In the R4 encoding, bits 31..27 are the rs3 field; do not decode them as an ordinary OP-FP R-type funct5 field.
rm controls the single final rounding; behavior is reserved for rm=101 or 110, and for rm=111 with frm=101..111, so those encodings are not fixed rounding modes.
FMA must set NV for infinity-times-zero multiplicands, even if rs3 is quiet NaN. Applicable flags NV, OF, UF, and NX accrue in fflags; setting them does not itself trap. NaN results follow the general canonical-NaN rule.
The FNMSUB/FNMADD sign rules are easy to confuse: FNMSUB is -(rs1*rs2)+rs3, while FNMADD is -(rs1*rs2)-rs3.

FAQ

How is FMSUB.D different from FMUL plus add/subtract?

FMSUB.D is fused: the product is not first rounded into an intermediate FP result; the whole expression is rounded once at the end according to rm.

Why is FMSUB.D R4-type?

It needs rd, rs1, rs2, rs3, and rm fields; bits 31..27 hold rs3, not an ordinary R-type funct5 field.

Can FMSUB.D set fflags?

It can set FP exception flags under the official FP rules, such as inexact, overflow, underflow, or invalid operation; the default animation uses exact finite values, so it shows fflags remaining 0.