f9ee085902f4f3fa1c375011c73fb4edf9ae5701
[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). v3.0B Scalar CR instructions (crand, crxor) only allow a single bit calculation.
20
21 Basic concept:
22
23 * CR-based instructions that perform simple AND/OR/XOR from all four bits
24 of a CR to create a single bit value (0/1) in an integer register
25 * Inverse of the same, taking a single bit value (0/1) from an integer
26 register to selectively target all four bits of a given CR
27 * CR-to-CR version of the same, allowing multiple bits to be AND/OR/XORed
28 in one hit.
29 * Vectorisation of the same
30
31 Purpose:
32
33 * To provide a merged version of what is currently a multi-sequence of
34 CR operations (crand, cror, crxor) with mfcr and mtcrf, reducing
35 instruction count.
36 * To provide a vectorised version of the same, suitable for advanced
37 predication
38
39 Side-effects:
40
41 * mtcrweird when RA=0 is a means to set or clear arbitrary CR bits
42 using immediates embedded within the instruction.
43
44 (Twin) Predication interactions:
45
46 * 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
47 * CR twin predication with zeroing is likewise a way to interact with the incoming integer
48
49 this gets particularly powerful if data-dependent predication is also enabled.
50
51 # Bit ordering.
52
53 IBM chose MSB0 for the OpenPOWER v3.0B specification. This makes things slightly hair-raising. Our desire initially is therefore to follow the logical progression from the defined behaviour of `mtcr` and `mfcr` etc.
54 In [[isa/sprset]] we see the pseudocode for `mtcrf` for example:
55
56 mtcrf FXM,RS
57
58 do n = 0 to 7
59 if FXM[n] = 1 then
60 CR[4*n+32:4*n+35] <- (RS)[4*n+32:4*n+35]
61
62 This places (according to a mask schedule) `CR0` into MSB0-numbered bits 32-35 of the target Integer register `RS`, these bits of `RS` being the 31st down to the 28th. Unfortunately, even when not Vectorised, this inserts CR numbering inversions on each batch of 8 CRs, massively complicating matters. Predication when using CRs would have to be morphed to this (unacceptably complex) behaviour:
63
64 for i in range(VL):
65 if INTpredmode:
66 predbit = (r3)[63-i] # IBM MSB0 spec sigh
67 else:
68 # completely incomprehensible vertical numbering
69 n = (7-(i%8)) | (i & ~0x7) # total mess
70 CRpredicate = CR{n} # select CR0, CR1, ....
71 predbit = CRpredicate[offs] # select eq..ov bit
72
73 Which is nowhere close to matching the straightforward obvious case:
74
75 for i in range(VL):
76 if INTpredmode:
77 predbit = (r3)[63-i] # IBM MSB0 spec sigh
78 else:
79 CRpredicate = CR{i} # start at CR0, work up
80 predbit = CRpredicate[offs]
81
82 In other words unless we do something about this, when we transfer bits from an Integer Predicate into a Vector of CRs, our numbering of CRs, when enumerating them in a CR Vector, would be **CR7** CR6 CR5.... CR0 **CR15** CR14 CR13... CR8 **CR23** CR22 etc. **not** the more natural and obvious CR0 CR1 ... CR23.
83
84 Therefore the instructions below need to **redefine** the relationship so that CR numbers (CR0, CR1) sequentially match the arithmetically-ordered bits of Integer registers. By `arithmetic` this is deduced from the fact that the instruction `addi r3, r0, 1` will result in the **LSB** (numbered 63 in IBM MSB0 order) of r3 being set to 1 and all other bits set to zero. We therefore refer, below, to this LSB as "Arithmetic bit 0", and it is this bit which is used - defined - as being the first bit used in Integer predication (on element 0).
85
86 Below is some pseudocode that, given a CR offset `offs` to represent `CR.eq` thru to `CR.ov` respectively, will copy the INT predicate bits in the correct order into the first 8 CRs:
87
88 do n = 0 to 7
89 CR[4*n+32+offs] <- (RS)[63-n]
90
91 Assuming that `offs` is set to `CR.eq` this results in:
92
93 * Arithmetic bit 0 (the LSB, numbered 63 in IBM MSB0 terminology)
94 of RS being inserted into CR0.eq
95 * Arithmetic bit 1 of RS being inserted into CR1.eq
96 * ...
97 * Arithmetic bit 7 of RS being inserted into CR7.eq
98
99 To clarify, then: all instructions below do **NOT** follow the IBM convention, they follow the natural sequence CR0 CR1 instead, using `CR{fieldnum}` to refer to the individual CR Fields. However it is critically important to note that the offsets **in** a CR field
100 (`CR.eq` for example) continue to follow the v3.0B definition and convention.
101
102
103 # Instruction form and pseudocode
104
105 Note that `CR{n}` refers to `CR0` when `n=0` and consequently, for CR0-7, is defined, in v3.0B pseudocode, as:
106
107 CR{7-n} = CR[32+n*4:35+n*4]
108
109 Instruction format:
110
111 | 0-5 | 6-10 | 11 | 12-15 | 16-18 | 19-20 | 21-25 | 26-30 | 31 |
112 | --- | ---- | -- | ----- | ----- | ----- | ----- | ----- | -- |
113 | 19 | RT | | mask | BB | | XO[0:4] | XO[5:9] | / |
114 | 19 | RT | 0 | mask | BB | 0 M | XO[0:4] | 0 mode | Rc |
115 | 19 | RA | 1 | mask | BB | 0 / | XO[0:4] | 0 mode | / |
116 | 19 | BT // | 0 | mask | BB | 1 / | XO[0:4] | 0 mode | / |
117 | 19 | BFT | 1 | mask | BB | 1 M | XO[0:4] | 0 mode | / |
118
119 mode is encoded in XO and is 4 bits
120
121 bit 11=0, bit 19=0
122
123 crrweird: RT, BB, mask.mode
124
125 creg = CR{BB}
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 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
131 RT[63] = result # MSB0 numbering, 63 is LSB
132 If Rc:
133 CR1 = analyse(RT)
134
135 bit 11=1, bit 19=0
136
137 mtcrweird: RA, BB, mask.mode
138
139 reg = (RA|0)
140 lsb = reg[63] # MSB0 numbering
141 n0 = mask[0] & (mode[0] == lsb)
142 n1 = mask[1] & (mode[1] == lsb)
143 n2 = mask[2] & (mode[2] == lsb)
144 n3 = mask[3] & (mode[3] == lsb)
145 CR{BB} = n0 || n1 || n2 || n3
146
147 bit 11=0, bit 19=1
148
149 crweird: BT, BB, mask.mode
150
151 creg = CR{BB}
152 n0 = mask[0] & (mode[0] == creg[0])
153 n1 = mask[1] & (mode[1] == creg[1])
154 n2 = mask[2] & (mode[2] == creg[2])
155 n3 = mask[3] & (mode[3] == creg[3])
156 CR{BT} = n0 || n1 || n2 || n3
157
158 bit 11=1, bit 19=1
159
160 crweirder: BFT, BB, mask.mode
161
162 creg = CR{BB}
163 n0 = mask[0] & (mode[0] == creg[0])
164 n1 = mask[1] & (mode[1] == creg[1])
165 n2 = mask[2] & (mode[2] == creg[2])
166 n3 = mask[3] & (mode[3] == creg[3])
167 BF = BFT[2:4] # select CR
168 bit = BFT[0:1] # select bit of CR
169 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
170 CR{BF}[bit] = result
171
172 Pseudo-op:
173
174 mtcri BB, mode mtcrweird r0, BB, 0b1111.~mode
175 mtcrset BB, mask mtcrweird r0, BB, mask.0b0000
176 mtcrclr BB, mask mtcrweird r0, BB, mask.0b1111
177
178 # Vectorised versions
179
180 The name "weird" refers to a minor violation of SV rules when it comes to deriving the Vectorised versions of these instructions.
181
182 Normally the progression of the SV for-loop would move on to the next register.
183 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.
184
185 crrweird: RT, BB, mask.mode
186
187 for i in range(VL):
188 if BB.isvec:
189 creg = CR{BB+i}
190 else:
191 creg = CR{BB}
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 # OR or AND to a single bit
197 result = n0|n1|n2|n3 if M else n0&n1&n2&n3
198 if RT.isvec:
199 if RT.elwidth == 0b00:
200 # pack 1 result into 64-bit registers
201 iregs[RT+i][0..62] = 0
202 iregs[RT+i][63] = result # sets LSB to result
203 if RT.elwidth == 0b01:
204 # pack 2 results sequentially into INT registers
205 iregs[RT+i//2][0..61] = 0
206 iregs[RT+i//2][63-(i%2)] = result
207 if RT.elwidth == 0b10:
208 # pack 4 results sequentially into INT registers
209 iregs[RT+i//4][0..59] = 0
210 iregs[RT+i//4][63-(i%4)] = result
211 if RT.elwidth == 0b11:
212 # pack 8 results sequentially into INT registers
213 iregs[RT+i//8][0..55] = 0
214 iregs[RT+i//8][63-(i%8)] = result
215 else:
216 iregs[RT][63-i] = result # results also in scalar INT
217
218 Note that:
219
220 * in the scalar case the CR-Vector assessment
221 is stored bit-wise starting at the LSB of the
222 destination scalar INT
223 * in the INT-vector case the result is stored in the
224 LSB of each element in the result vector
225
226 Note that element width overrides are respected on the INT src or destination register (but that elwidth overrides on CRs are meaningless)
227
228 # v3.1 setbc instructions
229
230 there are additional setb conditional instructions in v3.1 (p129)
231
232 RT = (CR[BI] == 1) ? 1 : 0
233
234 which also negate that, and also return -1 / 0. these are similar yo crweird but not the same purpose. most notable is that crweird acts on CR fields rather than the entire 32 bit CR.
235
236