(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, the only problem being that typical Vector ISAs have quite comprehensive mask-based instructions: set-before-first, popcount and much more. In fact many Vector ISAs can use Vectors *as* masks, consequently the entire Vector ISA is usually available for use in creating masks (one exception being AVX512 which
18 has a dedicated Mask regfile and opcodes).
19 Duplication of such operations (popcount etc) is not practical for SV given
20 the strategy of leveraging pre-existing Scalar instructions in a minimalist way.
21
22 With the scalar OpenPOWER v3.0B ISA having already popcnt, cntlz and others normally seen in Vector Mask operations it makes sense to allow *both* scalar integers *and* CR-Vectors to be predicate masks. That in turn means that much more comprehensive interaction between CRs and scalar Integers is required, because with the CR Predication Modes designating CR *Fields*
23 (not CR bits) as Predicate Elements, fast transfers between CR *Fields* and
24 the Integer Register File is needed.
25
26 The opportunity is therefore taken to also augment CR logical arithmetic as well, using a mask-based paradigm that takes into consideration multiple bits of each CR Field (eq/lt/gt/ov). By contrast
27 v3.0B Scalar CR instructions (crand, crxor) only allow a single bit calculation, and both mtcr and mfcr are CR-orientated rather than CR *Field*
28 orientated.
29
30 Also strangely there is no v3.0 instruction for directly moving CR Fields,
31 only CR *bits*,
32 so that is corrected here with `mcrfm`. The opportunity is taken
33 to allow inversion of CR Field bits, when copied.
34
35 Basic concept:
36
37 * CR-based instructions that perform simple AND/OR/XOR from any four bits
38 of a CR field to create a single bit value (0/1) in an integer register
39 * Inverse of the same, taking a single bit value (0/1) from an integer
40 register to selectively target any four bits of a given CR Field
41 * CR-to-CR version of the same, allowing multiple bits to be AND/OR/XORed
42 in one hit.
43 * Optional Vectorisation of the same when SVP64 is implemented
44
45 Purpose:
46
47 * To provide a merged version of what is currently a multi-sequence of
48 CR operations (crand, cror, crxor) with mfcr and mtcrf, reducing
49 instruction count.
50 * To provide a vectorised version of the same, suitable for advanced
51 predication
52
53 Side-effects:
54
55 * mtcrweird when RA=0 is a means to set or clear arbitrary CR bits
56 using immediates embedded within the instruction.
57
58 (Twin) Predication interactions:
59
60 * INT twin predication with zeroing is a way to copy an integer into CRs without necessarily needing the INT register (RA). if it is, it is effectively ANDed (or negate-and-ANDed) with the INT Predicate
61 * CR twin predication with zeroing is likewise a way to interact with the incoming integer
62
63 this gets particularly powerful if data-dependent predication is also enabled. further explanation is below.
64
65 # Bit ordering.
66
67 Please see [[svp64/appendix]] regarding CR bit ordering and for
68 the definition of `CR{n}`
69
70 # Instruction form and pseudocode
71
72 **DRAFT** Instruction format (use of MAJOR 19 not approved by
73 OPF ISA WG):
74
75 |0-5|6-10 |11|12-15|16-18|19-20|21-25 |26-30 |31|name |
76 |---|---- |--|-----|-----|-----|----- |----- |--|---- |
77 |19 |RT | |mask |BFA | |XO[0:4]|XO[5:9]|/ | |
78 |19 |RT |M |mask |BFA | 0 0 |XO[0:4]|0 mode |Rc|crrweird |
79 |19 |RA |M |mask |BF | 0 1 |XO[0:4]|0 mode |/ |mtcrweird |
80 |19 |BT |M |mask |BFA | 1 0 |XO[0:4]|0 mode |/ |crweirder |
81 |19 |BF //|M |mask |BFA | 1 1 |XO[0:4]|0 mode |0 |crweird |
82 |19 |BF //|M |mask |BFA | 1 1 |XO[0:4]|0 mode |1 |mcrfm |
83
84 **crrweird**
85
86 mode is encoded in XO and is 4 bits
87
88 bit 19=0, bit 20=0
89
90 crrweird: RT, BFA, M, mask.mode
91
92 creg = CR{BFA}
93 n0 = mask[0] & (mode[0] == creg[0])
94 n1 = mask[1] & (mode[1] == creg[1])
95 n2 = mask[2] & (mode[2] == creg[2])
96 n3 = mask[3] & (mode[3] == creg[3])
97 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
98 RT[63] = result # MSB0 numbering, 63 is LSB
99 If Rc:
100 CR0 = analyse(RT)
101
102 When used with SVP64 Prefixing this is a [[openpower/sv/normal]] SVP64 type operation and as
103 such can use Rc=1 and RC1 Data-dependent Mode capability
104
105 **mtcrweird**
106
107 bit 19=0, bit 20=1
108
109 mtcrweird: BF, RA, M, mask.mode
110
111 reg = (RA|0)
112 lsb = reg[63] # MSB0 numbering
113 n0 = mask[0] & (mode[0] == lsb)
114 n1 = mask[1] & (mode[1] == lsb)
115 n2 = mask[2] & (mode[2] == lsb)
116 n3 = mask[3] & (mode[3] == lsb)
117 result = n0 || n1 || n2 || n3
118 if M:
119 result |= CR{BF} & ~mask
120 CR{BF} = result
121
122 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
123 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
124 M=1. Correspondingly when M=0 this operation is an overwrite: no read
125 of BF is required because the masked-out bits of the BF CR Field are
126 set to zero.
127
128 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
129 3-bit Data-dependent and 3-bit Predicate-result capability
130 (BF is 3 bits)
131
132 **crweird**
133
134 bit 19=1, bit 20=0, Rc=0
135
136 crweird: BF, BFA, M, mask.mode
137
138 creg = CR{BFA}
139 n0 = mask[0] & (mode[0] == creg[0])
140 n1 = mask[1] & (mode[1] == creg[1])
141 n2 = mask[2] & (mode[2] == creg[2])
142 n3 = mask[3] & (mode[3] == creg[3])
143 result = n0 || n1 || n2 || n3
144 if M:
145 result |= CR{BF} & ~mask
146 CR{BF} = result
147
148 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
149 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
150 M=1. Correspondingly when M=0 this operation is an overwrite: no read
151 of BF is required because the masked-out bits of the BF CR Field are
152 set to zero.
153
154 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
155 3-bit Data-dependent and 3-bit Predicate-result capability
156 (BF is 3 bits)
157
158 **mcrfm** - Move CR Field, masked.
159
160 bit 19=1, bit 20=0, Rc=1
161
162 mcrfm: BF, BFA, M, mask.mode
163
164 result = mask & CR{BFA}
165 if M:
166 result |= CR{BF} & ~mask
167 result ^= mode
168 CR{BF} = result
169
170 Note that when M=1 this operation is a Read-Modify-Write on the CR Field
171 BF. Masked-out bits of the 4-bit CR Field BF will not be changed when
172 M=1. Correspondingly when M=0 this operation is an overwrite: no read
173 of BF is required because the masked-out bits of the BF CR Field are
174 set to zero.
175
176 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
177 3-bit Data-dependent and 3-bit Predicate-result capability
178 (BF is 3 bits)
179
180 *Programmer's note: `mode` being XORed onto the result provides considerable
181 flexibility. individual bits of BFA may be copied inverted to BF by
182 ensuring that `mask` and `mode` have the same bit set. Also, individual
183 bits in BF may be set to 1 by ensuring that the required bit of `mask`
184 is set to zero and the same bit in `mode` is set to 1*
185
186 **crweirder**
187
188 bit 19=1, bit 20=1
189
190 crweirder: BT, BFA, mask.mode
191
192 creg = CR{BFA}
193 n0 = mask[0] & (mode[0] == creg[0])
194 n1 = mask[1] & (mode[1] == creg[1])
195 n2 = mask[2] & (mode[2] == creg[2])
196 n3 = mask[3] & (mode[3] == creg[3])
197 BF = BT[2:4] # select CR
198 bit = BT[0:1] # select bit of CR
199 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
200 CR{BF}[bit] = result
201
202 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
203 5-bit Data-dependent and 5-bit Predicate-result capability
204 (BFT is 5 bits)
205
206 **Example Pseudo-ops:**
207
208 mtcri BF, mode mtcrweird BF, r0, 0, 0b1111.~mode
209 mtcrset BF, mask mtcrweird BF, r0, 1, mask.0b0000
210 mtcrclr BF, mask mtcrweird BF, r0, 1, mask.0b1111
211
212 # Vectorised versions
213
214 The name "weird" refers to a minor violation of SV rules when it comes to deriving the Vectorised versions of these instructions.
215
216 Normally the progression of the SV for-loop would move on to the next register.
217 Instead however in the scalar case these instructions **remain in the same register** and insert or transfer between **bits** of the scalar integer source or destination.
218
219 Further useful violation of the normal SV Elwidth override rules allows
220 for packing (or unpacking) of multiple CR test results into
221 (or out of) an Integer Element. Note
222 that the CR (source operand) elwidth field is utilised to determine the bit-
223 packing size (1/2/4/8 with remaining bits within the Integer element
224 set to zero) whilst the INT (dest operand) elwidth field still sets
225 the Integer element size as usual (8/16/32/default)
226
227 crrweird: RT, BB, mask.mode
228
229 for i in range(VL):
230 if BB.isvec:
231 creg = CR{BB+i}
232 else:
233 creg = CR{BB}
234 n0 = mask[0] & (mode[0] == creg[0])
235 n1 = mask[1] & (mode[1] == creg[1])
236 n2 = mask[2] & (mode[2] == creg[2])
237 n3 = mask[3] & (mode[3] == creg[3])
238 # OR or AND to a single bit
239 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
240 if RT.isvec:
241 # TODO: RT.elwidth override to be also added here
242 # note, yes, really, the CR's elwidth field determines
243 # the bit-packing into the INT!
244 if BB.elwidth == 0b00:
245 # pack 1 result into 64-bit registers
246 iregs[RT+i][0..62] = 0
247 iregs[RT+i][63] = result # sets LSB to result
248 if BB.elwidth == 0b01:
249 # pack 2 results sequentially into INT registers
250 iregs[RT+i//2][0..61] = 0
251 iregs[RT+i//2][63-(i%2)] = result
252 if BB.elwidth == 0b10:
253 # pack 4 results sequentially into INT registers
254 iregs[RT+i//4][0..59] = 0
255 iregs[RT+i//4][63-(i%4)] = result
256 if BB.elwidth == 0b11:
257 # pack 8 results sequentially into INT registers
258 iregs[RT+i//8][0..55] = 0
259 iregs[RT+i//8][63-(i%8)] = result
260 else:
261 iregs[RT][63-i] = result # results also in scalar INT
262
263 Note that:
264
265 * in the scalar case the CR-Vector assessment
266 is stored bit-wise starting at the LSB of the
267 destination scalar INT
268 * in the INT-vector case the results are packed into LSBs
269 of the INT Elements, the packing arrangement depending on both
270 elwidth override settings.
271
272 # v3.1 setbc instructions
273
274 there are additional setb conditional instructions in v3.1 (p129)
275
276 RT = (CR[BI] == 1) ? 1 : 0
277
278 which also negate that, and also return -1 / 0. these are similar to crweird but not the same purpose. most notable is that crweird acts on CR fields rather than the entire 32 bit CR.
279
280 # Predication Examples
281
282 Take the following example:
283
284 r10 = 0b00010
285 sv.mtcrweird/dm=r10/dz cr8.v, 0, 0b0011.0000
286
287 Here, RA is zero, so the source input is zero. The destination
288 is CR Field 8, and the destination predicate mask indicates
289 to target the first two elements. Destination predicate zeroing is
290 enabled, and the destination predicate is only set in the 2nd bit.
291 mask is 0b0011, mode is all zeros.
292
293 Let us first consider what should go into element 0 (CR Field 8):
294
295 * The destination predicate bit is zero, and zeroing is enabled.
296 * Therefore, what is in the source is irrelevant: the result must
297 be zero.
298 * Therefore all four bits of CR Field 8 are therefore set to zero.
299
300 Now the second element, CR Field 9 (CR9):
301
302 * Bit 2 of the destination predicate, r10, is 1. Therefore the computation
303 of the result is relevant.
304 * RA is zero therefore bit 2 is zero. mask is 0b0011 and mode is 0b0000
305 * When calculating n0 thru n3 we get n0=1, n1=2, n2=0, n3=0
306 * Therefore, CR9 is set (using LSB0 ordering) to 0b0011, i.e. to mask.
307
308 It should be clear that this instruction uses bits of the integer
309 predicate to decide whether to set CR Fields to `(mask & ~mode)`
310 or to zero. Thus, in effect, it is the integer predicate that has
311 been copied into the CR Fields.
312
313 By using twin predication, zeroing, and inversion (sm=~r3, dm=r10) for example, it becomes possible to combine two Integers together in
314 order to set bits in CR Fields.
315 Likewise there are dozens of ways that CR Predicates can be used, on the
316 same sv.mtcrweird instruction.