31.11.3-10V VIII: Integer Arithmetic — Extension to Multiply

Part III Linux boot: recommended Vol. I (Unprivileged) pp. 321–328 · ~2 min read

The integer core of the vector ISA. (Single-width add/sub and the widening adds precede these in §31.11.1-2: vadd/vsub/vrsub and vwadd[u]/vwsub[u] with their .wv/.wx two-operand-width forms.)

Integer arithmetic §31.11.3-10 (all masked-capable .vv/.vx/.vi forms unless noted)
Semantics & rules
vzext/vsext .vf2/.vf4/.vf8In-register width extension: source EEW = SEW/2/4/8 (EMUL scaled), destination SEW. Exists to avoid a loads×datatypes cross-product — load narrow, extend when no widening arithmetic op fits. Unsupported source EEW/EMUL → reserved.
vadc/vsbc .vvm/.vxm/.vimSum/difference PLUS carry/borrow from v0’s mask bits, written full-width to vd. Encoded vm=0 but operating on ALL body elements; vm=1 encodings reserved; vd=v0 reserved.
vmadc/vmsbc (.vvm/.vxm/.vim and carry-less .vv/.vx/.vi)The carry/borrow OUT, as a mask value to any legal vd. Multi-word add: vmadc first (temp), vadc second, move temp to v0 — destructive accumulation needs the extra move. Borrow = 1 iff untruncated difference < 0. Always tail-agnostic (mask producers).
vand/vor/vxorBitwise logical; vnot.v is vxor.vi vd, vs2, -1.
vsll/vsrl/vsraShifts by vs1/rs1/uimm, amount taken mod SEW (low log2(SEW) bits).
vnsrl/vnsra .wv/.wx/.wiNARROWING right shifts: 2·SEW source down to SEW destination — the second half of every widen-compute-narrow pipeline.
vmseq/vmsne/vmslt[u]/vmsle[u]/vmsgt[u]Compares producing MASK results (bit per element) — the vector branch. Missing forms (vmsge.vx etc.) synthesize per the spec’s recipes.
vmin[u]/vmax[u]Signed/unsigned select of smaller/larger — clamps without masks.
vmul / vmulh / vmulhu / vmulhsuLow half / high half (ss, uu, su) of the 2·SEW product at same width — full-precision multiply without register-group growth (the widening vwmul family is the alternative).
Dotted-underlined cells have explanations — click one.

Hardware Designer Notes

The lane datapath for this page is a scalar RV integer ALU with a few vector-isms: mod-SEW shift masking, mask-bit insertion for carries, and the compare-to-bit path. Verification leverage: run your scalar ALU vectors across every SEW × LMUL combination.

Minimal Linux-boot hart MUST

  • Implement vadc/vsbc as all-body-elements operations despite vm=0 encoding — the mask is DATA here, not predication
  • Keep compare/carry-out writers on the mask-layout path with forced tail-agnostic behavior
  • Scale source EMUL for the extension instructions and trap the reserved narrow-EEW cases

MAY simplify / trap-and-emulate

  • Share the scalar ALU design per lane: these ops are exactly the scalar integer set replicated, with SEW-parameterized width gating
  • Implement vmulh via the existing widening multiplier array, selecting the high half at writeback

Check yourself — vector integer arithmetic

1.Why does multi-word vector addition need BOTH vadc and vmadc — and in what order?

2.What do vzext.vf4 / vsext.vf4 do, and why do they exist when widening loads could?

3.How do vector integer compares (vmseq, vmslt, …) deliver results?

4.What distinguishes vmulh/vmulhu/vmulhsu from vmul?

4 questions