(This unit also includes vfrec7.v — the reciprocal estimate twin
of vfrsqrt7, same architecturally-exact-table discipline.)
| Semantics & notes | |
|---|---|
| vfrec7.v | ~7-bit reciprocal estimate from the specified lookup table — the Newton-Raphson seed for divisions you refuse to serialize. |
| vfmin / vfmax | minimumNumber/maximumNumber semantics per F v2.2 (NaN loses to a number; both-NaN → canonical NaN). |
| vfsgnj / vfsgnjn / vfsgnjx | Sign injection; gives the pseudoinstructions vfneg.v (sgnjn self) and vfabs.v (sgnjx self). |
| vmfeq / vmfne / vmflt / vmfle / vmfgt.vf / vmfge.vf | Mask-producing compares with scalar semantics: eq/ne invalid only on sNaN; ordered compares invalid on ANY NaN; vmfne alone writes 1 on NaN inputs. |
| vfmerge.vfm | vd[i] = v0.mask[i] ? f[rs1] : vs2[i], all body elements (vm=0 encoding, mask as data). |
| vfmv.v.f | Scalar splat — vfmerge’s vm=1 face with vs2 pinned to v0. |
| vfcvt.{x,xu}.f / .f.{x,xu} (+ rtz variants) | Same-width FP↔int converts; dynamic frm except the rtz statics, which bake in truncation for C/Java casts (no frm swap dance). |
| vfwcvt.* (+ .f.f.v) | Widening converts to 2·SEW — int→double-width-float and float→double-width-float are always EXACT; multi-step widening chains lose nothing. |
| vfncvt.* (+ rod.f.f.w) | Narrowing from 2·SEW; the round-to-odd f→f variant enables multi-step narrowing WITHOUT double-rounding error (BF16’s emulation chains rely on exactly this). |
The C99 quiet-compare recipe
# isgreater(va, vb) — quiet: no invalid on qNaN inputs
vmfeq.vv v0, va, va # lanes where A is not NaN
vmfeq.vv v1, vb, vb # lanes where B is not NaN
vmand.mm v0, v0, v1 # ordered lanes only
vmfgt.vv v0, va, vb, v0.t # signaling compare, masked to ordered
Hardware Designer Notes
Compare-and-mask is the vector unit’s branch unit: vmf* feeding
masked ops is how every if inside a vectorized loop executes. Make
mask-producing compares single-cycle and forwarding-friendly into
the mask port — it’s the latency chain of conditional kernels.
Minimal Linux-boot hart MUST
- Match scalar F flag behavior exactly per lane, including the eq/ne-vs-ordered invalid distinction and vmfne’s writes-1-on-NaN
- Implement vfrec7/vfrsqrt7 from the normative tables, bit-exact
- Route rtz converts around frm without disturbing it
MAY simplify / trap-and-emulate
- Share one convert datapath for same-width/widening/narrowing with a shift-and-round stage parameterized by direction
- Fuse the quiet-compare 4-sequence if your decoder recognizes it — flags must still come out IEEE-correct
Check yourself — FP compares & converts
1.Why can't the four-instruction isgreater() sequence be shortened by masking the second vmfeq?
2.vmfne sees a NaN in one operand. What does it write, and how does that differ from the other compares?
3.Why do the rtz convert variants exist when frm can be set to RTZ?
4.vfmerge.vfm vs vfmv.v.f — what's the encoding relationship?