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