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