(no commit message)
[libreriscv.git] / openpower / sv / cr_int_predication.mdwn
1 [[!tag standards]]
2
3 # New instructions for CR/INT predication
4
5 **DRAFT STATUS**
6
7 See:
8
9 * main bugreport for crweirds
10 <https://bugs.libre-soc.org/show_bug.cgi?id=533>
11 * <https://bugs.libre-soc.org/show_bug.cgi?id=527>
12 * <https://bugs.libre-soc.org/show_bug.cgi?id=569>
13 * <https://bugs.libre-soc.org/show_bug.cgi?id=558#c47>
14
15 Rationale:
16
17 Condition Registers are conceptually perfect for use as predicate masks,
18 the only problem being that typical Vector ISAs have quite comprehensive
19 mask-based instructions: set-before-first, popcount and much more.
20 In fact many Vector ISAs can use Vectors *as* masks, consequently the
21 entire Vector ISA is usually available for use in creating masks (one
22 exception being AVX512 which has a dedicated Mask regfile and opcodes).
23 Duplication of such operations (popcount etc) is not practical for SV
24 given the strategy of leveraging pre-existing Scalar instructions in a
25 minimalist way.
26
27 With the scalar OpenPOWER v3.0B ISA having already popcnt, cntlz and
28 others normally seen in Vector Mask operations it makes sense to allow
29 *both* scalar integers *and* CR-Vectors to be predicate masks. That in
30 turn means that much more comprehensive interaction between CRs and scalar
31 Integers is required, because with the CR Predication Modes designating
32 CR *Fields* (not CR bits) as Predicate Elements, fast transfers between
33 CR *Fields* and the Integer Register File is needed.
34
35 The opportunity is therefore taken to also augment CR logical arithmetic
36 as well, using a mask-based paradigm that takes into consideration
37 multiple bits of each CR Field (eq/lt/gt/ov). By contrast v3.0B Scalar
38 CR instructions (crand, crxor) only allow a single bit calculation, and
39 both mtcr and mfcr are CR-orientated rather than CR *Field* orientated.
40
41 Also strangely there is no v3.0 instruction for directly moving CR Fields,
42 only CR *bits*, so that is corrected here with `mcrfm`. The opportunity
43 is taken to allow inversion of CR Field bits, when copied.
44
45 Basic concept:
46
47 * CR-based instructions that perform simple AND/OR from any four bits
48 of a CR field to create a single bit value (0/1) in an integer register
49 * Inverse of the same, taking a single bit value (0/1) from an integer
50 register to selectively target any four bits of a given CR Field
51 * CR-to-CR version of the same, allowing multiple bits to be AND/OR/XORed
52 in one hit.
53 * Optional Vectorisation of the same when SVP64 is implemented
54
55 Purpose:
56
57 * To provide a merged version of what is currently a multi-sequence of
58 CR operations (crand, cror, crxor) with mfcr and mtcrf, reducing
59 instruction count.
60 * To provide a vectorised version of the same, suitable for advanced
61 predication
62
63 Side-effects:
64
65 * mtcrweird when RA=0 is a means to set or clear arbitrary CR bits
66 using immediates embedded within the instruction.
67
68 # Bit ordering.
69
70 Please see [[svp64/appendix]] regarding CR bit ordering and for
71 the definition of `CR{n}`
72
73 # Instruction form and pseudocode
74
75 **DRAFT** Instruction format (use of MAJOR 19 not approved by
76 OPF ISA WG):
77
78 |0-5|6-10 |11|12-15|16-18|19-20|21-25 |26-30 |31|name |
79 |---|---- |--|-----|-----|-----|----- |----- |--|---- |
80 |19 |RT | |mask |BFA | |XO[0:4]|XO[5:9]|/ | |
81 |19 | | | | | |1 //// |00011 | |rsvd |
82 |19 |RT |M |mask |BFA | 0 0 |0 mode |00011 |Rc|crrweird |
83 |19 |RT |M |mask |BFA | 0 1 |0 mode |00011 |Rc|mfcrweird |
84 |19 |RA |M |mask |BF | 1 0 |0 mode |00011 |0 |mtcrrweird |
85 |19 |RA |M |mask |BF | 1 0 |0 mode |00011 |1 |mtcrweird |
86 |19 |BT |M |mask |BFA | 1 1 |0 mode |00011 |0 |crweirder |
87 |19 |BF //|M |mask |BFA | 1 1 |0 mode |00011 |1 |mcrfm |
88
89 **crrweird**
90
91 mode is encoded in XO and is 4 bits
92
93 crrweird: RT,BFA,M,mask,mode
94
95 creg = CR{BFA}
96 n0 = mask[0] & (mode[0] == creg[0])
97 n1 = mask[1] & (mode[1] == creg[1])
98 n2 = mask[2] & (mode[2] == creg[2])
99 n3 = mask[3] & (mode[3] == creg[3])
100 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
101 RT[63] = result # MSB0 numbering, 63 is LSB
102 If Rc:
103 CR0 = analyse(RT)
104
105 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
106 SVP64 type operation and as such can use Rc=1 and RC1 Data-dependent
107 Mode capability
108
109 Also as noted below, element-width override bits normally used
110 on the source is instead used to allow multiple results to be packed
111 sequentially into the destination. *Destination elwidth overrides still apply*.
112
113 **mfcrrweird**
114
115 mode is encoded in XO and is 4 bits
116
117 mfcrrweird: RT,BFA,mask,mode
118
119 creg = CR{BFA}
120 n0 = mask[0] & (mode[0] == creg[0])
121 n1 = mask[1] & (mode[1] == creg[1])
122 n2 = mask[2] & (mode[2] == creg[2])
123 n3 = mask[3] & (mode[3] == creg[3])
124 result = n0||n1||n2||n3
125 RT[60:63] = result # MSB0 numbering, 63 is LSB
126 If Rc:
127 CR0 = analyse(RT)
128
129 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
130 SVP64 type operation and as such can use Rc=1 and RC1 Data-dependent
131 Mode capability.
132
133 Also as noted below, element-width override bits normally used
134 on the source is instead used to allow multiple results to be packed
135 into the destination. *Destination elwidth overrides still apply*
136
137 **mtcrrweird**
138
139 mode is encoded in XO and is 4 bits
140
141 mtcrrweird: BF,RA,M,mask,mode
142
143 a = (RA|0)
144 n0 = mask[0] & (mode[0] == a[63])
145 n1 = mask[1] & (mode[1] == a[62])
146 n2 = mask[2] & (mode[2] == a[61])
147 n3 = mask[3] & (mode[3] == a[60])
148 result = n0 || n1 || n2 || n3
149 if M:
150 result |= CR{BF} & ~mask
151 CR{BF} = result
152
153 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
154 SVP64 type operation and as such can use RC1 Data-dependent
155 Mode capability
156
157 **mtcrweird**
158
159 mtcrweird: BF,RA,M,mask,mode
160
161 reg = (RA|0)
162 lsb = reg[63] # MSB0 numbering
163 n0 = mask[0] & (mode[0] == lsb)
164 n1 = mask[1] & (mode[1] == lsb)
165 n2 = mask[2] & (mode[2] == lsb)
166 n3 = mask[3] & (mode[3] == lsb)
167 result = n0 || n1 || n2 || n3
168 if M:
169 result |= CR{BF} & ~mask
170 CR{BF} = result
171
172 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
173 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
174 M=1. Correspondingly when M=0 this operation is an overwrite: no read
175 of BF is required because the masked-out bits of the BF CR Field are
176 set to zero.
177
178 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
179 type operation that has 3-bit Data-dependent and 3-bit Predicate-result
180 capability (BF is 3 bits)
181
182 **mcrfm** - Move CR Field, masked.
183
184 This instruction copies, sets, or inverts parts of a CR Field
185 into another CR Field. `mcrf` copies only one bit of the CR
186 from any arbitrary bit to any other arbitrary bit, whereas
187 `mcrfm` copies an entire 4-bit CR Field (or masked parts thereof).
188 Unlike `mcrf` the bits of the CR Field may not change position:
189 the EQ bit from the source may only go into the EQ bit of the
190 destination (optionally inverted, set, or cleared).
191
192 mcrfm: BF,BFA,M,mask,mode
193
194 result = mask & CR{BFA}
195 if M:
196 result |= CR{BF} & ~mask
197 result ^= mode
198 CR{BF} = result
199
200 When M=1 this operation is a Read-Modify-Write on the CR Field
201 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
202 M=1. Correspondingly when M=0 this operation is an overwrite: no read
203 of BF is required because the masked-out bits of the BF CR Field are
204 set to zero.
205
206 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
207 type operation that has 3-bit Data-dependent and 3-bit Predicate-result
208 capability (BF is 3 bits)
209
210 *Programmer's note: `mode` being XORed onto the result provides
211 considerable flexibility. individual bits of BFA may be copied inverted
212 to BF by ensuring that `mask` and `mode` have the same bit set. Also,
213 individual bits in BF may be set to 1 by ensuring that the required bit of
214 `mask` is set to zero and the same bit in `mode` is set to 1*
215
216 **crweirder**
217
218 crweirder: BT,BFA,mask,mode
219
220 creg = CR{BFA}
221 n0 = mask[0] & (mode[0] == creg[0])
222 n1 = mask[1] & (mode[1] == creg[1])
223 n2 = mask[2] & (mode[2] == creg[2])
224 n3 = mask[3] & (mode[3] == creg[3])
225 BF = BT[2:4] # select CR
226 bit = BT[0:1] # select bit of CR
227 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
228 CR{BF}[bit] = result
229
230 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
231 type operation that has 5-bit Data-dependent and 5-bit Predicate-result
232 capability (BFT is 5 bits)
233
234 **Example Pseudo-ops:**
235
236 mtcri BF, mode mtcrweird BF, r0, 0, 0b1111,~mode
237 mtcrset BF, mask mtcrweird BF, r0, 1, mask,0b0000
238 mtcrclr BF, mask mtcrweird BF, r0, 1, mask,0b1111
239
240 # Vectorised versions involving GPRs
241
242 The name "weird" refers to a minor violation of SV rules when it comes
243 to deriving the Vectorised versions of these instructions.
244
245 Normally the progression of the SV for-loop would move on to the
246 next register. Instead however in the scalar case these instructions
247 **remain in the same register** and insert or transfer between **bits**
248 of the scalar integer source or destination. The reason is that when
249 using CR Fields as predicate masks and there is a need to transfer
250 into a GPR, again for use as a predicate mask, the CR Field bits
251 need to be efficiently packed into that one GPR (r3, r10 or r31).
252
253 Further useful violation of the normal SV Elwidth override rules allows
254 for packing (or unpacking) of multiple CR test results into (or out of)
255 an Integer Element. Note that the CR (source operand) elwidth field is
256 utilised to determine the bit- packing size (1/2/4/8 with remaining
257 bits within the Integer element set to zero) whilst the INT (dest
258 operand) elwidth field still sets the Integer element size as usual
259 (8/16/32/default)
260
261 **crrweird: RT, BB, mask.mode**
262
263 for i in range(VL):
264 if BB.isvec:
265 creg = CR{BB+i}
266 else:
267 creg = CR{BB}
268 n0 = mask[0] & (mode[0] == creg[0])
269 n1 = mask[1] & (mode[1] == creg[1])
270 n2 = mask[2] & (mode[2] == creg[2])
271 n3 = mask[3] & (mode[3] == creg[3])
272 # OR or AND to a single bit
273 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
274 if RT.isvec:
275 # TODO: RT.elwidth override to be also added here
276 # note, yes, really, the CR's elwidth field determines
277 # the bit-packing into the INT!
278 if BB.elwidth == 0b00:
279 # pack 1 result into 64-bit registers
280 iregs[RT+i][0..62] = 0
281 iregs[RT+i][63] = result # sets LSB to result
282 if BB.elwidth == 0b01:
283 # pack 2 results sequentially into INT registers
284 iregs[RT+i//2][0..61] = 0
285 iregs[RT+i//2][63-(i%2)] = result
286 if BB.elwidth == 0b10:
287 # pack 4 results sequentially into INT registers
288 iregs[RT+i//4][0..59] = 0
289 iregs[RT+i//4][63-(i%4)] = result
290 if BB.elwidth == 0b11:
291 # pack 8 results sequentially into INT registers
292 iregs[RT+i//8][0..55] = 0
293 iregs[RT+i//8][63-(i%8)] = result
294 else:
295 iregs[RT][63-i] = result # results also in scalar INT
296
297 Note that:
298
299 * in the scalar case the CR-Vector assessment
300 is stored bit-wise starting at the LSB of the
301 destination scalar INT
302 * in the INT-vector case the results are packed into LSBs
303 of the INT Elements, the packing arrangement depending on both
304 elwidth override settings.
305
306 **mfcrrweird: RT, BFA, mask.mode**
307
308 Unlike `crrweird` the results are 4-bit wide, so the packing
309 will begin to spill over to other destination elements. 8 results per
310 destination at 4-bits each still fits into destination elwidth at 32-bit,
311 but for 16-bit and 8-bit obviously this does not fit, and must split
312 across to the next element
313
314 When for example destination elwidth is 16-bit (0b10) the following packing
315 occurs:
316
317 - SVRM bits 6:7 equal to 0b00 - one 4-bit result element packed into the
318 first 4-bits of the 16-bit destination element (in the first 4 LSBs)
319 - SVRM bits 6:7 equal to 0b01 - two 4-bit result elements packed into the
320 first 8-bits of the 16-bit destination element (in the first 8 LSBs)
321 - SVRM bits 6:7 equal to 0b10 - four 4-bit result elements packed into each
322 16-bit destination element
323 - SVRM bits 6:7 equal to 0b11 - eight 4-bit result elements, the first four
324 of which are packed into the first 16-bit destination element, the
325 second four of which are packed into the second 16-bit destination element.
326
327 Pseudocode example: note that dest elwidth overrides affect the
328 packing of results. BB.elwidth in effect requests how many 4-bit
329 result elements would like to be packed, but RT.elwidth determines
330 the limit. Any parts of the destination elements not containing
331 results are set to zero.
332
333 for i in range(VL):
334 if BB.isvec:
335 creg = CR{BB+i}
336 else:
337 creg = CR{BB}
338 n0 = mask[0] & (mode[0] == creg[0])
339 n1 = mask[1] & (mode[1] == creg[1])
340 n2 = mask[2] & (mode[2] == creg[2])
341 n3 = mask[3] & (mode[3] == creg[3])
342 result = n0||n1||n2||n3 # 4-bit result
343 if RT.isvec:
344 # RT.elwidth override can affect the packing
345 bwid = {0b00:64, 0b01:8, 0b10:16, 0b11:32}[RT.elwidth]
346 t4, t8 = min(4, bwid//2), min(8, bwid//2)
347 # yes, really, the CR's elwidth field determines
348 # the bit-packing into the INT!
349 if BB.elwidth == 0b00:
350 # pack 1 result into 64-bit registers
351 idx, boff = i, 0
352 if BB.elwidth == 0b01:
353 # pack 2 results sequentially into INT registers
354 idx, boff = i//2, i%2
355 if BB.elwidth == 0b10:
356 # pack 4 results sequentially into INT registers
357 idx, boff = i//t4, i%t4
358 if BB.elwidth == 0b11:
359 # pack 8 results sequentially into INT registers
360 idx, boff = i//t8, i%t8
361 else:
362 # exceeding VL=16 is UNDEFINED
363 idx, boff = 0, i
364 iregs[RT+idx][60-boff*4:63-boff*4] = result
365
366
367
368 # v3.1 setbc instructions
369
370 There are additional setb conditional instructions in v3.1 (p129)
371
372 RT = (CR[BI] == 1) ? 1 : 0
373
374 which also negate that, and also return -1 / 0. these are similar to
375 crweird but not the same purpose. most notable is that crweird acts on
376 CR fields rather than the entire 32 bit CR.
377
378 # Predication Examples
379
380 Take the following example:
381
382 r10 = 0b00010
383 sv.mtcrweird/dm=r10/dz cr8.v, 0, 0b0011.0000
384
385 Here, RA is zero, so the source input is zero. The destination is CR Field
386 8, and the destination predicate mask indicates to target the first two
387 elements. Destination predicate zeroing is enabled, and the destination
388 predicate is only set in the 2nd bit. mask is 0b0011, mode is all zeros.
389
390 Let us first consider what should go into element 0 (CR Field 8):
391
392 * The destination predicate bit is zero, and zeroing is enabled.
393 * Therefore, what is in the source is irrelevant: the result must
394 be zero.
395 * Therefore all four bits of CR Field 8 are therefore set to zero.
396
397 Now the second element, CR Field 9 (CR9):
398
399 * Bit 2 of the destination predicate, r10, is 1. Therefore the computation
400 of the result is relevant.
401 * RA is zero therefore bit 2 is zero. mask is 0b0011 and mode is 0b0000
402 * When calculating n0 thru n3 we get n0=1, n1=2, n2=0, n3=0
403 * Therefore, CR9 is set (using LSB0 ordering) to 0b0011, i.e. to mask.
404
405 It should be clear that this instruction uses bits of the integer
406 predicate to decide whether to set CR Fields to `(mask & ~mode)` or
407 to zero. Thus, in effect, it is the integer predicate that has been
408 copied into the CR Fields.
409
410 By using twin predication, zeroing, and inversion (sm=~r3, dm=r10) for
411 example, it becomes possible to combine two Integers together in order
412 to set bits in CR Fields. Likewise there are dozens of ways that CR
413 Predicates can be used, on the same sv.mtcrweird instruction.