94df7128bd9f1a93815a14a7c67a8c846d6f6627
[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 // 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
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, source from SPR
49 VL = SPR[SV_VL]
50 }
51
52 // set MVL (or not).
53 // 2 options: from SPR, from immed
54 if ms {
55 MVL = vlimmed
56 } else {
57 MVL = SPR[SV_MVL]
58 }
59
60 // calculate (limit) VL
61 VL = min(VL, MVL)
62
63 // store VL, MVL
64 SPR[SV_VL] = VL
65 SPR[SV_MVL] = MVL
66
67 // write rd
68 if rt != 0 {
69 // rt is not zero
70 regs[rt] = VL;
71 }
72 // write CR?
73 if Rc {
74 // update CR from VL (not rt)
75 CR0 = ....
76 }
77
78 # Examples
79
80 ## Core concept loop
81
82 loop:
83 setvl a3, a0, MVL=8 # update a3 with vl
84 # (# of elements this iteration)
85 # set MVL to 8
86 # do vector operations at up to 8 length (MVL=8)
87 # ...
88 sub a0, a0, a3 # Decrement count by vl
89 bnez a0, loop # Any more?
90
91 ## Loop using Rc=1
92
93 my_fn:
94 li r3, 1000
95 b test
96 loop:
97 sub r3, r3, r4
98 ...
99 test:
100 setvl. r4, r3, 64
101 bne cr0, loop
102 end:
103 blr