3 # New instructions for CR/INT predication
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>
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 premise to minimise adding of instructions.
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.
21 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
22 v3.0B Scalar CR instructions (crand, crxor) only allow a single bit calculation.
26 * CR-based instructions that perform simple AND/OR/XOR from any four bits
27 of a CR field to create a single bit value (0/1) in an integer register
28 * Inverse of the same, taking a single bit value (0/1) from an integer
29 register to selectively target any four bits of a given CR Field
30 * CR-to-CR version of the same, allowing multiple bits to be AND/OR/XORed
32 * Optional Vectorisation of the same when SVP64 is implemented
36 * To provide a merged version of what is currently a multi-sequence of
37 CR operations (crand, cror, crxor) with mfcr and mtcrf, reducing
39 * To provide a vectorised version of the same, suitable for advanced
44 * mtcrweird when RA=0 is a means to set or clear arbitrary CR bits
45 using immediates embedded within the instruction.
47 (Twin) Predication interactions:
49 * 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
50 * CR twin predication with zeroing is likewise a way to interact with the incoming integer
52 this gets particularly powerful if data-dependent predication is also enabled. further explanation is below.
56 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
57 numbers is not clearly defined. To make it clear we define a new
59 `CR{n}` refers to `CR0` when `n=0` and consequently, for CR0-7, is defined, in v3.0B pseudocode, as:
61 CR{7-n} = CR[32+n*4:35+n*4]
63 Also note that for SVP64 the relationship for the sequential
64 numbering of elements is to the CR **fields** within
65 the CR Register, not to individual bits within the CR register.
67 # Instruction form and pseudocode
69 **DRAFT** Instruction format (use of MAJOR 19 not approved by
72 |0-5|6-10 |11|12-15|16-18|19-20|21-25 |26-30 |31|name |
73 |---|---- |--|-----|-----|-----|----- |----- |--|---- |
74 |19 |RT | |mask |BFA | |XO[0:4]|XO[5:9]|/ | |
75 |19 |RT |M |mask |BFA | 0 0 |XO[0:4]|0 mode |Rc|crrweird |
76 |19 |RA |/ |mask |BF | 0 1 |XO[0:4]|0 mode |/ |mtcrweird |
77 |19 |BFT//|M |mask |BFA | 1 0 |XO[0:4]|0 mode |/ |crweird |
78 |19 |BF |/ |mask |BFA | 1 1 |XO[0:4]|0 mode |/ |crweirder |
82 mode is encoded in XO and is 4 bits
86 crrweird: RT, BFA, mask.mode
89 n0 = mask[0] & (mode[0] == creg[0])
90 n1 = mask[1] & (mode[1] == creg[1])
91 n2 = mask[2] & (mode[2] == creg[2])
92 n3 = mask[3] & (mode[3] == creg[3])
93 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
94 RT[63] = result # MSB0 numbering, 63 is LSB
98 When used with SVP64 Prefixing this is a [[openpower/sv/normal]] SVP64 type operation and as
99 such can use Rc=1 and RC1 Data-dependent Mode capability
105 mtcrweird: BF, RA, mask.mode
108 lsb = reg[63] # MSB0 numbering
109 n0 = mask[0] & (mode[0] == lsb)
110 n1 = mask[1] & (mode[1] == lsb)
111 n2 = mask[2] & (mode[2] == lsb)
112 n3 = mask[3] & (mode[3] == lsb)
113 CR{BF} = n0 || n1 || n2 || n3
115 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
116 3-bit Data-dependent and 3-bit Predicate-result capability
123 crweird: BF, BFA, mask.mode
126 n0 = mask[0] & (mode[0] == creg[0])
127 n1 = mask[1] & (mode[1] == creg[1])
128 n2 = mask[2] & (mode[2] == creg[2])
129 n3 = mask[3] & (mode[3] == creg[3])
130 CR{BF} = n0 || n1 || n2 || n3
132 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
133 3-bit Data-dependent and 3-bit Predicate-result capability
140 crweirder: BT, BFA, mask.mode
143 n0 = mask[0] & (mode[0] == creg[0])
144 n1 = mask[1] & (mode[1] == creg[1])
145 n2 = mask[2] & (mode[2] == creg[2])
146 n3 = mask[3] & (mode[3] == creg[3])
147 BF = BT[2:4] # select CR
148 bit = BT[0:1] # select bit of CR
149 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
152 When used with SVP64 Prefixing this is a [[openpower/sv/cr_ops]] SVP64 type operation that has
153 5-bit Data-dependent and 5-bit Predicate-result capability
156 **Example Pseudo-ops:**
158 mtcri BFA, mode mtcrweird r0, BFA, 0b1111.~mode
159 mtcrset BFA, mask mtcrweird r0, BFA, mask.0b0000
160 mtcrclr BFA, mask mtcrweird r0, BFA, mask.0b1111
162 # Vectorised versions
164 The name "weird" refers to a minor violation of SV rules when it comes to deriving the Vectorised versions of these instructions.
166 Normally the progression of the SV for-loop would move on to the next register.
167 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.
169 Further useful violation of the normal SV Elwidth override rules allows
170 for packing of multiple CR test results into an Integer Element. Note
171 that the CR (source operand) elwidth field is utilised to determine the bit-
172 packing size (1/2/4/8 with remaining bits within the Integer element
173 set to zero) whilst the INT (dest operand) elwidth field still sets
174 the Integer element size as usual (8/16/32/default)
176 crrweird: RT, BB, mask.mode
183 n0 = mask[0] & (mode[0] == creg[0])
184 n1 = mask[1] & (mode[1] == creg[1])
185 n2 = mask[2] & (mode[2] == creg[2])
186 n3 = mask[3] & (mode[3] == creg[3])
187 # OR or AND to a single bit
188 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
190 # TODO: RT.elwidth override to be also added here
191 # note, yes, really, the CR's elwidth field determines
192 # the bit-packing into the INT!
193 if BB.elwidth == 0b00:
194 # pack 1 result into 64-bit registers
195 iregs[RT+i][0..62] = 0
196 iregs[RT+i][63] = result # sets LSB to result
197 if BB.elwidth == 0b01:
198 # pack 2 results sequentially into INT registers
199 iregs[RT+i//2][0..61] = 0
200 iregs[RT+i//2][63-(i%2)] = result
201 if BB.elwidth == 0b10:
202 # pack 4 results sequentially into INT registers
203 iregs[RT+i//4][0..59] = 0
204 iregs[RT+i//4][63-(i%4)] = result
205 if BB.elwidth == 0b11:
206 # pack 8 results sequentially into INT registers
207 iregs[RT+i//8][0..55] = 0
208 iregs[RT+i//8][63-(i%8)] = result
210 iregs[RT][63-i] = result # results also in scalar INT
214 * in the scalar case the CR-Vector assessment
215 is stored bit-wise starting at the LSB of the
216 destination scalar INT
217 * in the INT-vector case the results are packed into LSBs
218 of the INT Elements, the packing arrangement depending on both
219 elwidth override settings.
221 # v3.1 setbc instructions
223 there are additional setb conditional instructions in v3.1 (p129)
225 RT = (CR[BI] == 1) ? 1 : 0
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.
229 # Predication Examples
231 Take the following example:
234 sv.mtcrweird/dm=r10/dz cr8.v, 0, 0b0011.0000
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.
242 Let us first consider what should go into element 0 (CR Field 8):
244 * The destination predicate bit is zero, and zeroing is enabled.
245 * Therefore, what is in the source is irrelevant: the result must
247 * Therefore all four bits of CR Field 8 are therefore set to zero.
249 Now the second element, CR Field 9 (CR9):
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.
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.
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.