42ce6e15672e8c2062f8cb72bd776db26739db52
[libreriscv.git] / openpower / sv / setvl.mdwn
1 # OpenPOWER SV setvl/setvli
2
3 See links:
4
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>
8
9 Use of setvl results in changes to the MVL, VL and STATE SPRs. see [[sv/sprs]]♧
10
11 # Format
12
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 |
17
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.
19
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]]
21
22 Note that setmvli is a pseudo-op, based on RA/RT=0, and setvli likewise
23
24 * setvli VL=8 : setvl r5, r0, VL=8
25 * setmvli MVL=8 : setvl r0, r0, MVL=8
26
27 # Pseudocode
28
29 // instruction fields:
30 rd = get_rt_field(); // bits 6..10
31 ra = get_ra_field(); // bits 11..15
32 vs = get_vs_field(); // bit 24
33 ms = get_ms_field(); // bit 25
34 Rc = get_Rc_field(); // bit 31
35 // add one. MVL/VL=1..64 not 0..63
36 vlimmed = get_immed_field()+1; // 16..22
37
38 // set VL (or not).
39 // 3 options: from SPR, from immed, from ra
40 if vs {
41 // VL to be sourced from fields/regs
42 if ra != 0 {
43 VL = GPR[ra]
44 } else {
45 VL = vlimmed
46 }
47 } else {
48 // VL not to change (except if MVL is reduced)
49 // read from SPRs
50 VL = SPR[SV_VL]
51 }
52
53 // set MVL (or not).
54 // 2 options: from SPR, from immed
55 if ms {
56 MVL = vlimmed
57 } else {
58 // MVL not to change, read from SPRs
59 MVL = SPR[SV_MVL]
60 }
61
62 // calculate (limit) VL
63 VL = min(VL, MVL)
64
65 // store VL, MVL
66 SPR[SV_VL] = VL
67 SPR[SV_MVL] = MVL
68
69 // write rd
70 if rt != 0 {
71 // rt is not zero
72 regs[rt] = VL;
73 }
74 // write CR?
75 if Rc {
76 // update CR from VL (not rt)
77 CR0.eq = (VL == 0)
78 ...
79 ...
80 }
81
82 # Examples
83
84 ## Core concept loop
85
86 loop:
87 setvl a3, a0, MVL=8 # update a3 with vl
88 # (# of elements this iteration)
89 # set MVL to 8
90 # do vector operations at up to 8 length (MVL=8)
91 # ...
92 sub a0, a0, a3 # Decrement count by vl
93 bnez a0, loop # Any more?
94
95 ## Loop using Rc=1
96
97 my_fn:
98 li r3, 1000
99 b test
100 loop:
101 sub r3, r3, r4
102 ...
103 test:
104 setvl. r4, r3, 64
105 bne cr0, loop
106 end:
107 blr