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