1 # OpenPOWER SV setvl/setvli
5 * <http://lists.libre-soc.org/pipermail/libre-soc-dev/2020-November/001366.html>
6 * <https://bugs.libre-soc.org/show_bug.cgi?id=535>
7 * <https://github.com/riscv/riscv-v-spec/blob/master/v-spec.adoc#vsetvlivsetvl-instructions>
9 Use of setvl results in changes to the MVL, VL and STATE SPRs. see [[sv/sprs]]♧
13 | 0.5|6.10|11.15|16.20| 21..24..25 | 26...30 |31| name |
14 |----|----|-----|-----|-------------|---------|--|---------|
15 | 19 | RT | RA | | XO[0:4] | XO[5:9] |Rc| XL-Form |
16 | 19 | RT | RA |imm | i // vs ms | NNNNN |Rc| setvl |
18 Note that imm spans 7 bits (16 to 22), and that bit 22 is reserved and must be zero. Setting bit 22 causes an illegal exception.
20 Note that VL and MVL start from **one** i.e. that an immediate value of zero will result in VL/MVL being set to 1. 0b111111 results in VL/MVL being set to 64. This is because setting VL/MVL to 1 results in "scalar identity" behaviour, where setting VL/MVL to 0 would result in all Vector operations becoming nop. If this is truly desired (nop behaviour) then setting VL and MVL to zero be done via the [[SV SPRs|sv/sprs]]
22 Note that setmvli is a pseudo-op, based on RA/RT=0, and setvli likewise
24 * setvli VL=8 : setvl r5, r0, VL=8
25 * setmvli MVL=8 : setvl r0, r0, MVL=8
29 // instruction fields:
30 rd = get_rt_field(); // bits 6..10
31 ra = get_ra_field(); // bits 11..15
32 // add one. MVL/VL=1..64 not 0..63
33 vlimmed = get_immed_field()+1; // 16..22
34 vs = get_vs_field(); // bit 24
35 ms = get_ms_field(); // bit 25
36 Rc = get_Rc_field(); // bit 31
39 // 3 options: from SPR, from immed, from ra
41 // VL to be sourced from fields/regs
48 // VL not to change, source from SPR
53 // 2 options: from SPR, from immed
60 // calculate (limit) VL
74 // update CR from VL (not rt)
83 setvl a3, a0, MVL=8 # update a3 with vl
84 # (# of elements this iteration)
86 # do vector operations at up to 8 length (MVL=8)
88 sub a0, a0, a3 # Decrement count by vl
89 bnez a0, loop # Any more?