(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 (Twin) Predication interactions:
69
70 * INT twin predication with zeroing is a way to copy an integer into
71 CRs without necessarily needing the INT register (RA). if it is, it is
72 effectively ANDed (or negate-and-ANDed) with the INT Predicate
73 * CR twin predication with zeroing is likewise a way to interact with
74 the incoming integer
75
76 this gets particularly powerful if data-dependent predication is also
77 enabled. further explanation is below.
78
79 # Bit ordering.
80
81 Please see [[svp64/appendix]] regarding CR bit ordering and for
82 the definition of `CR{n}`
83
84 # Instruction form and pseudocode
85
86 **DRAFT** Instruction format (use of MAJOR 19 not approved by
87 OPF ISA WG):
88
89 |0-5|6-10 |11|12-15|16-18|19-20|21-25 |26-30 |31|name |
90 |---|---- |--|-----|-----|-----|----- |----- |--|---- |
91 |19 |RT | |mask |BFA | |XO[0:4]|XO[5:9]|/ | |
92 |19 | | | | | |1 //// |00011 | |rsvd |
93 |19 |RT |M |mask |BFA | 0 0 |1 mode |00011 |Rc|crrweird |
94 |19 |RT |M |mask |BFA | 0 1 |1 mode |00011 |Rc|mfcrweird |
95 |19 |RA |M |mask |BF | 0 0 |0 mode |00011 |1 |mtcrrweird |
96 |19 |RA |M |mask |BF | 0 1 |0 mode |00011 |0 |mtcrweird |
97 |19 |BT |M |mask |BFA | 0 1 |0 mode |00011 |1 |crweirder |
98 |19 |BF //|M |mask |BFA | 1 1 |0 mode |00011 |0 |crweird |
99 |19 |BF //|M |mask |BFA | 1 1 |0 mode |00011 |1 |mcrfm |
100
101 **crrweird**
102
103 mode is encoded in XO and is 4 bits
104
105 bit 19=0, bit 20=0
106
107 crrweird: RT, BFA, M, mask.mode
108
109 creg = CR{BFA}
110 n0 = mask[0] & (mode[0] == creg[0])
111 n1 = mask[1] & (mode[1] == creg[1])
112 n2 = mask[2] & (mode[2] == creg[2])
113 n3 = mask[3] & (mode[3] == creg[3])
114 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
115 RT[63] = result # MSB0 numbering, 63 is LSB
116 If Rc:
117 CR0 = analyse(RT)
118
119 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
120 SVP64 type operation and as such can use Rc=1 and RC1 Data-dependent
121 Mode capability
122
123 Also as noted below, element-width override bits normally used
124 on the source is instead used to allow multiple results to be packed
125 sequentially into the destination. *Destination elwidth overrides still apply*.
126
127 **mfcrrweird**
128
129 mode is encoded in XO and is 4 bits
130
131 bit 19=0, bit 20=0
132
133 mfcrrweird: RT, BFA, mask.mode
134
135 creg = CR{BFA}
136 n0 = mask[0] & (mode[0] == creg[0])
137 n1 = mask[1] & (mode[1] == creg[1])
138 n2 = mask[2] & (mode[2] == creg[2])
139 n3 = mask[3] & (mode[3] == creg[3])
140 result = n0||n1||n2||n3
141 RT[60:63] = result # MSB0 numbering, 63 is LSB
142 If Rc:
143 CR0 = analyse(RT)
144
145 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
146 SVP64 type operation and as such can use Rc=1 and RC1 Data-dependent
147 Mode capability.
148
149 Also as noted below, element-width override bits normally used
150 on the source is instead used to allow multiple results to be packed
151 into the destination. *Destination elwidth overrides still apply*
152
153 **mtcrrweird**
154
155 mode is encoded in XO and is 4 bits
156
157 bit 19=0, bit 20=0
158
159 mtcrrweird: BF, RA, M, mask.mode
160
161 n0 = mask[0] & (mode[0] == RA[63])
162 n1 = mask[1] & (mode[1] == RA[62])
163 n2 = mask[2] & (mode[2] == RA[61])
164 n3 = mask[3] & (mode[3] == RA[60])
165 result = n0 || n1 || n2 || n3
166 if M:
167 result |= CR{BF} & ~mask
168 CR{BF} = result
169
170 When used with SVP64 Prefixing this is a [[openpower/sv/normal]]
171 SVP64 type operation and as such can use RC1 Data-dependent
172 Mode capability
173
174 **mtcrweird**
175
176 bit 19=0, bit 20=1
177
178 mtcrweird: BF, RA, M, mask.mode
179
180 reg = (RA|0)
181 lsb = reg[63] # MSB0 numbering
182 n0 = mask[0] & (mode[0] == lsb)
183 n1 = mask[1] & (mode[1] == lsb)
184 n2 = mask[2] & (mode[2] == lsb)
185 n3 = mask[3] & (mode[3] == lsb)
186 result = n0 || n1 || n2 || n3
187 if M:
188 result |= CR{BF} & ~mask
189 CR{BF} = result
190
191 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
192 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
193 M=1. Correspondingly when M=0 this operation is an overwrite: no read
194 of BF is required because the masked-out bits of the BF CR Field are
195 set to zero.
196
197 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
198 type operation that has 3-bit Data-dependent and 3-bit Predicate-result
199 capability (BF is 3 bits)
200
201 **crweird**
202
203 bit 19=1, bit 20=0, bit 30=0
204
205 crweird: BF, BFA, M, mask.mode
206
207 creg = CR{BFA}
208 n0 = mask[0] & (mode[0] == creg[0])
209 n1 = mask[1] & (mode[1] == creg[1])
210 n2 = mask[2] & (mode[2] == creg[2])
211 n3 = mask[3] & (mode[3] == creg[3])
212 result = n0 || n1 || n2 || n3
213 if M:
214 result |= CR{BF} & ~mask
215 CR{BF} = result
216
217 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
218 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
219 M=1. Correspondingly when M=0 this operation is an overwrite: no read
220 of BF is required because the masked-out bits of the BF CR Field are
221 set to zero.
222
223 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
224 type operation that has 3-bit Data-dependent and 3-bit Predicate-result
225 capability (BF is 3 bits)
226
227 **mcrfm** - Move CR Field, masked.
228
229 bit 19=1, bit 20=0, bit 30=1
230
231 mcrfm: BF, BFA, M, mask.mode
232
233 result = mask & CR{BFA}
234 if M:
235 result |= CR{BF} & ~mask
236 result ^= mode
237 CR{BF} = result
238
239 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
240 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
241 M=1. Correspondingly when M=0 this operation is an overwrite: no read
242 of BF is required because the masked-out bits of the BF CR Field are
243 set to zero.
244
245 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
246 type operation that has 3-bit Data-dependent and 3-bit Predicate-result
247 capability (BF is 3 bits)
248
249 *Programmer's note: `mode` being XORed onto the result provides
250 considerable flexibility. individual bits of BFA may be copied inverted
251 to BF by ensuring that `mask` and `mode` have the same bit set. Also,
252 individual bits in BF may be set to 1 by ensuring that the required bit of
253 `mask` is set to zero and the same bit in `mode` is set to 1*
254
255 **crweirder**
256
257 bit 19=1, bit 20=1
258
259 crweirder: BT, BFA, mask.mode
260
261 creg = CR{BFA}
262 n0 = mask[0] & (mode[0] == creg[0])
263 n1 = mask[1] & (mode[1] == creg[1])
264 n2 = mask[2] & (mode[2] == creg[2])
265 n3 = mask[3] & (mode[3] == creg[3])
266 BF = BT[2:4] # select CR
267 bit = BT[0:1] # select bit of CR
268 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
269 CR{BF}[bit] = result
270
271 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64
272 type operation that has 5-bit Data-dependent and 5-bit Predicate-result
273 capability (BFT is 5 bits)
274
275 **Example Pseudo-ops:**
276
277 mtcri BF, mode mtcrweird BF, r0, 0, 0b1111.~mode
278 mtcrset BF, mask mtcrweird BF, r0, 1, mask.0b0000
279 mtcrclr BF, mask mtcrweird BF, r0, 1, mask.0b1111
280
281 # Vectorised versions
282
283 The name "weird" refers to a minor violation of SV rules when it comes
284 to deriving the Vectorised versions of these instructions.
285
286 Normally the progression of the SV for-loop would move on to the
287 next register. Instead however in the scalar case these instructions
288 **remain in the same register** and insert or transfer between **bits**
289 of the scalar integer source or destination.
290
291 Further useful violation of the normal SV Elwidth override rules allows
292 for packing (or unpacking) of multiple CR test results into (or out of)
293 an Integer Element. Note that the CR (source operand) elwidth field is
294 utilised to determine the bit- packing size (1/2/4/8 with remaining
295 bits within the Integer element set to zero) whilst the INT (dest
296 operand) elwidth field still sets the Integer element size as usual
297 (8/16/32/default)
298
299 **crrweird: RT, BB, mask.mode**
300
301 for i in range(VL):
302 if BB.isvec:
303 creg = CR{BB+i}
304 else:
305 creg = CR{BB}
306 n0 = mask[0] & (mode[0] == creg[0])
307 n1 = mask[1] & (mode[1] == creg[1])
308 n2 = mask[2] & (mode[2] == creg[2])
309 n3 = mask[3] & (mode[3] == creg[3])
310 # OR or AND to a single bit
311 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
312 if RT.isvec:
313 # TODO: RT.elwidth override to be also added here
314 # note, yes, really, the CR's elwidth field determines
315 # the bit-packing into the INT!
316 if BB.elwidth == 0b00:
317 # pack 1 result into 64-bit registers
318 iregs[RT+i][0..62] = 0
319 iregs[RT+i][63] = result # sets LSB to result
320 if BB.elwidth == 0b01:
321 # pack 2 results sequentially into INT registers
322 iregs[RT+i//2][0..61] = 0
323 iregs[RT+i//2][63-(i%2)] = result
324 if BB.elwidth == 0b10:
325 # pack 4 results sequentially into INT registers
326 iregs[RT+i//4][0..59] = 0
327 iregs[RT+i//4][63-(i%4)] = result
328 if BB.elwidth == 0b11:
329 # pack 8 results sequentially into INT registers
330 iregs[RT+i//8][0..55] = 0
331 iregs[RT+i//8][63-(i%8)] = result
332 else:
333 iregs[RT][63-i] = result # results also in scalar INT
334
335 Note that:
336
337 * in the scalar case the CR-Vector assessment
338 is stored bit-wise starting at the LSB of the
339 destination scalar INT
340 * in the INT-vector case the results are packed into LSBs
341 of the INT Elements, the packing arrangement depending on both
342 elwidth override settings.
343
344 **mfcrrweird: RT, BFA, mask.mode**
345
346 Unlike `crrweird` the results are 4-bit wide, so the packing
347 will begin to spill over to other destination elements. 8 results per
348 destination at 4-bits each still fits into destination elwidth at 32-bit,
349 but for 16-bit and 8-bit obviously this does not fit, and must split
350 across to the next element
351
352 When for example destination elwidth is 16-bit (0b10) the following packing
353 occurs:
354
355 - SVRM bits 6:7 equal to 0b00 - one 4-bit result element packed into the
356 first 4-bits of the 16-bit destination element (in the first 4 LSBs)
357 - SVRM bits 6:7 equal to 0b01 - two 4-bit result elements packed into the
358 first 8-bits of the 16-bit destination element (in the first 8 LSBs)
359 - SVRM bits 6:7 equal to 0b10 - four 4-bit result elements packed into each
360 16-bit destination element
361 - SVRM bits 6:7 equal to 0b11 - eight 4-bit result elements, the first four
362 of which are packed into the first 16-bit destination element, the
363 second four of which are packed into the second 16-bit destination element.
364
365 Pseudocode example (dest elwidth overrides not included):
366
367 for i in range(VL):
368 if BB.isvec:
369 creg = CR{BB+i}
370 else:
371 creg = CR{BB}
372 n0 = mask[0] & (mode[0] == creg[0])
373 n1 = mask[1] & (mode[1] == creg[1])
374 n2 = mask[2] & (mode[2] == creg[2])
375 n3 = mask[3] & (mode[3] == creg[3])
376 result = n0||n1||n2||n3 # 4-bit result
377 if RT.isvec:
378 # TODO: RT.elwidth override to be also added here
379 # yes, really, the CR's elwidth field determines
380 # the bit-packing into the INT!
381 if BB.elwidth == 0b00:
382 # pack 1 result into 64-bit registers
383 idx, boff = i, 0
384 if BB.elwidth == 0b01:
385 # pack 2 results sequentially into INT registers
386 idx, boff = i//2, i%2
387 if BB.elwidth == 0b10:
388 # pack 4 results sequentially into INT registers
389 idx, boff = i//t4, i%t4
390 if BB.elwidth == 0b11:
391 # pack 8 results sequentially into INT registers
392 idx, boff = i//t8, i%t8
393 else:
394 # exceeding VL=16 is UNDEFINED
395 idx, boff = 0, i
396 iregs[RT+idx][60-boff*4:63-boff*4] = result
397
398
399
400 # v3.1 setbc instructions
401
402 There are additional setb conditional instructions in v3.1 (p129)
403
404 RT = (CR[BI] == 1) ? 1 : 0
405
406 which also negate that, and also return -1 / 0. these are similar to
407 crweird but not the same purpose. most notable is that crweird acts on
408 CR fields rather than the entire 32 bit CR.
409
410 # Predication Examples
411
412 Take the following example:
413
414 r10 = 0b00010
415 sv.mtcrweird/dm=r10/dz cr8.v, 0, 0b0011.0000
416
417 Here, RA is zero, so the source input is zero. The destination is CR Field
418 8, and the destination predicate mask indicates to target the first two
419 elements. Destination predicate zeroing is enabled, and the destination
420 predicate is only set in the 2nd bit. mask is 0b0011, mode is all zeros.
421
422 Let us first consider what should go into element 0 (CR Field 8):
423
424 * The destination predicate bit is zero, and zeroing is enabled.
425 * Therefore, what is in the source is irrelevant: the result must
426 be zero.
427 * Therefore all four bits of CR Field 8 are therefore set to zero.
428
429 Now the second element, CR Field 9 (CR9):
430
431 * Bit 2 of the destination predicate, r10, is 1. Therefore the computation
432 of the result is relevant.
433 * RA is zero therefore bit 2 is zero. mask is 0b0011 and mode is 0b0000
434 * When calculating n0 thru n3 we get n0=1, n1=2, n2=0, n3=0
435 * Therefore, CR9 is set (using LSB0 ordering) to 0b0011, i.e. to mask.
436
437 It should be clear that this instruction uses bits of the integer
438 predicate to decide whether to set CR Fields to `(mask & ~mode)` or
439 to zero. Thus, in effect, it is the integer predicate that has been
440 copied into the CR Fields.
441
442 By using twin predication, zeroing, and inversion (sm=~r3, dm=r10) for
443 example, it becomes possible to combine two Integers together in order
444 to set bits in CR Fields. Likewise there are dozens of ways that CR
445 Predicates can be used, on the same sv.mtcrweird instruction.