(no commit message)
[libreriscv.git] / simple_v_extension / specification / sv.setvl / discussion.mdwn
1 # SV setvl exploration
2
3 Formats for Vector Configuration Instructions under OP-V major opcode:
4
5 | 31|30 25|24 20|19 15|14 12|11 7|6 0| name |
6 |---|------------------------|----------|-------|---------|-------|---------|
7 | 0 | imm[10:6] |imm[4:0] | rs1 | 1 1 1 | rd |1010111| vsetvli |
8 | 1 | 000000 | rs2 | rs1 | 1 1 1 | rd |1010111| vsetvl |
9 | 1 | 6 | 5 | 5 | 3 | 5 | 7 | |
10
11 Requirement: fit MVL into this format.
12
13 | 31|30 25|24 20|19 15|14 12|11 7|6 0| name |
14 |---|-------------|----------|----------|-------|---------|-------|---------|
15 | 0 | imm[10:6] |imm[4:0] | rs1 | 1 1 1 | rd |1010111| vsetvli |
16 | 1 | imm[5:0] | rs2 | rs1 | 1 1 1 | rd |1010111| vsetvl |
17 | 1 | 6 | 5 | 5 | 3 | 5 | 7 | |
18
19 where:
20
21 * when bit 31==0, both MVL and VL are set to imm(10:6) - plus one to
22 get it out of the "NOP" scenario.
23 * when bit 31==1, MVL is set to imm(5:0) plus one.
24
25 hang on... no, that's a 4-argument setvl! what about this?
26
27
28 | 31|30 25|24 20|19 15|14 12|11 7|6 0| name | variant# |
29 |---|-------------|----------|----------|-------|---------|-------|---------|------------|
30 | 0 | imm[5:0] | 0b00000 | rs1 | 1 1 1 | rd |1010111| vsetvli | 1 |
31 | 0 | imm[5:0] | 0b00000 | 0b00000 | 1 1 1 | rd |1010111| vsetvli | 2 |
32 | 0 | imm[5:0] | rs2!=x0 | rs1 | 1 1 1 | rd |1010111| vsetvli | 3 |
33 | 0 | imm[5:0] | rs2!=x0 | 0b00000 | 1 1 1 | rd |1010111| vsetvli | 4 |
34 | 1 | imm[5:0] | 0b00000 | rs1 | 1 1 1 | rd |1010111| vsetvl | 5 |
35 | 1 | imm[5:0] | 0b00000 | 0b00000 | 1 1 1 | rd |1010111| vsetvl | 6 |
36 | 1 | imm[5:0] | rs2!=x0 | rs1 | 1 1 1 | rd |1010111| vsetvl | 7 |
37 | 1 | imm[5:0] | rs2!=x0 | 0b00000 | 1 1 1 | rd |1010111| vsetvl | 8 |
38 | 1 | 6 | 5 | 5 | 3 | 5 | 7 | | |
39
40 i think those are the 8 permutations: what can those be used for? some of them for actual
41 instructions (brownfield encodings).
42
43 | name | variant# - | purpose |
44 |---------|------------|------------------------------------------------|
45 | vsetvli | 1 | vl = min(rf[rs1], VLMAX), if (!rd) rf[rd]=rd |
46 | vsetvli | 2 | vl = VLMAX immed , if (!rd) rf[rd]=rd |
47 | vsetvli | 3 | TBD |
48 | vsetvli | 4 | TBD |
49 | vsetvl | 5 | TBD |
50 | vsetvl | 6 | TBD |
51 | vsetvl | 7 | TBD |
52 | vsetvl | 8 | TBD |
53
54 notes:
55
56 * there's no behavioural difference between the vsetvl version and the
57 vsetvli version. that needs fixing (somehow, doing something)
58 * the above 4 fit into the "rs2 == x0" case, leaving "rs2 != x0" for
59 brownfield encodings.
60
61 # original encoding
62
63 Selected encoding for sv.setvl, see
64 <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-June/001898.html>
65
66 The encoding I (programmerjake) was planning on using is:
67
68 | 31|30 20|19 15|14 12|11 7|6 0| name |
69 |---|-------|--------|-------|----|-------|------------|
70 | 0 | VLMAX | rs1 | 1 1 1 | rd |1010111| sv.setvl |
71 | 0 | VLMAX | 0 (x0) | 1 1 1 | rd |1010111| sv.setvl |
72 | 1 | -- | -- | 1 1 1 | -- |1010111| *reserved* |
73
74 It leaves space for future expansion to RV128 and/or multi-register predicates.
75
76 > it's the opcode and funct7 that are actually used to determine the
77 > instruction for almost all RISC-V instructions, therefore, I think we
78 > should use the lower bits of the immediate in I-type to encode MAXVL.
79 > This also has the benefit of simple extension of VL/MAXVL since the
80 > bits immediately above the MAXVL field aren't used. If a new
81 > instruction wants to be able to use rs2, it simply uses the encoding
82 > with bit 31 set, which already indicates that rs2 is wanted in the V
83 > extension.
84
85 >> yep, good logic.
86
87 # pseudocode
88
89 regs = [0u64; 128];
90 vl = 0;
91
92 // instruction fields:
93 rd = get_rd_field();
94 rs1 = get_rs1_field();
95 vlmax = get_immed_field();
96
97 // handle illegal instruction decoding
98 if vlmax > XLEN {
99 trap()
100 }
101
102 // calculate VL
103 if rs1 == 0 { // rs1 is x0
104 vl = vlmax
105 } else {
106 vl = min(regs[rs1], vlmax)
107 }
108
109 // write rd
110 if rd != 0 {
111 // rd is not x0
112 regs[rd] = vl
113 }
114
115 # questions <a name="questions"></>
116
117 <https://libre-riscv.org/simple_v_extension/appendix/#strncpy>
118
119 GETVL add1 SETVL is a pain. 3 operations because VL is a CSR it is not
120 possible to perform arithmetic on it.
121
122 What about actually marking one of the registers *as* VL? this would
123 save a *lot* of instructions.
124
125 <https://groups.google.com/a/groups.riscv.org/d/msg/isa-dev/7lt9YNCR_bI/8Hh2-UY6AAAJ>
126
127 > (2) as it is the only one, VL may be hardware-cached, i.e. the
128 > fact that it points to a scalar register, well, that's only 5 bits:
129 > that's not very much to pass round and through pipelines.
130 >
131 > (3) if it's not very much to pass around, then the possibility
132 > exists to *rewrite* a CSRR VL instruction to become a MV operation,
133 > *at execution time*!
134 >
135 > yes, really: at instruction *decode* time, with there being
136 > only the 5 bits to check "if VL-cache-register is non-zero and
137 > CSR register == VL", it's really not that much extra logic
138 > to *directly* substitute the CSRR instruction with "MV rd,
139 > VL-where-VL-is-actually-the-contents-of-the-VL-cache"
140 >
141 > that would then allow the substituted-instruction to go directly
142 > into dependency-tracking *on the scalar register*, nipping in the
143 > bud the need for special CSR-related dependency logic, and no longer
144 > requiring the sub-par "stall" solution, either.
145
146 Hang on - CSRR rd, VL needs to return the register number, not the contents of tgat register number. So it's ok.
147
148 ----
149
150 Setting VL from an immed without altering MVL is not possible in the
151 above pseudocode. It is covered by VLtyp and the VL block in VBLOCK,
152 however is that enough?
153
154 # links
155
156 * <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-June/001881.html>
157 * <https://groups.google.com/d/msg/comp.arch/MLfqE8Rm-X4/zHLCHg6UAQAJ>