Whole-register loads and stores
vl1r.v–vl8r.v / vs1r.v–vs8r.v move 1/2/4/8 whole registers
(power-of-two counts, aligned bases) between memory and the register
file — ignoring vl and vtype, with evl = NFIELDS·VLEN/EEW.
They exist for exactly the moments when you can’t know the
configuration: compiler spills, vector calling conventions,
interrupt handlers, context switches (vlenb sizes the save area).
Loads carry EEW variants (vl1re8/16/32/64) purely as hints for
internally-rearranging implementations — the byte layout is identical
regardless — while stores need no hint and come in EEW=8 flavor only.
Alignment faults may be judged against max(EEW, SEWmin) bytes.
Alignment & the memory model
| Rule | |
|---|---|
| Misalignment | Per element: transfer succeeds or that element raises address-misaligned — vector misalignment support is INDEPENDENT of scalar support (its own PMA suggested). |
| Instruction-level ordering | Vector memory instructions appear to execute in program order on the hart; RVWMO at instruction level (RVTSO with Ztso — which does NOT strengthen intra-instruction order). |
| Element-level ordering | Unordered within an instruction — except indexed-ORDERED loads/stores, which access memory in element order (RVWMO at element level). |
| vl and masks are CONTROL dependencies | Not data dependencies. |
Arithmetic formats (§31.10)
OP-V’s funct3 selects the operand pattern: OPIVV/OPFVV/OPMVV (vector-vector), OPIVI (5-bit immediate, sign-extended to SEW), OPIVX/OPMVX (x-register scalar: low SEW bits if XLEN > SEW, sign-extended if narrower), OPFVF (f-register scalar, NaN-box checked → canonical NaN on failure), OPCFG (the vsetvl group). funct6 picks the operation. Two global FP rules: everything uses the dynamic frm — and an invalid frm makes every vector FP instruction reserved, even non-rounding ones, even at vl=0; and any FP operand EEW that isn’t a supported FP width is reserved.
Hardware Designer Notes
Context-switch cost preview for your OS team: 32 × VLEN bits via vl8r/vs8r in four instruction pairs, plus seven CSRs. At VLEN=256 that’s a 1 KiB save area — mstatus.VS’s dirty tracking is what makes lazy switching worth it.
Minimal Linux-boot hart MUST
- Implement whole-register ops as vtype-independent moves with their own evl and the modified vstart rule (reserved iff vstart ≥ evl)
- Keep indexed-ordered scatters/gathers element-ordered; leave everything else free-running
- Apply the NaN-box check on OPFVF scalars and the sign-extension rules on OPIVX/OPIVI scalars exactly
MAY simplify / trap-and-emulate
- Use the load-EEW hint to pre-scramble destination registers for their next access width
- Exploit the control-dependency classification: launch masked loads speculatively without recovery machinery
Check yourself — whole-register ops & memory model
1.Why do vl1r/vl2r/vl4r/vl8r ignore vtype and vl entirely?
2.Whole-register LOADS come in EEW variants (vl1re8/16/32/64) but stores only as vs1r/vs2r/vs4r/vs8r. Why?
3.Why does treating vl and the mask as CONTROL dependencies (not data) matter microarchitecturally?
4.An f-register scalar feeds vfadd.vf with FLEN=64, SEW=32. What value do the lanes see?