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