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