(no commit message)
[libreriscv.git] / openpower / sv / rfc / ls010.mdwn
1 # RFC ls010 SVP64 Zero-Overhead Loop Prefix Subsystem
2
3 Credits and acknowledgements:
4
5 * Luke Leighton
6 * Jacob Lifshay
7 * Hendrik Boom
8 * Richard Wilbur
9 * Alexandre Oliva
10 * Cesar Strauss
11 * NLnet Foundation, for funding
12 * OpenPOWER Foundation
13 * Paul Mackerras
14 * Toshaan Bharvani
15 * IBM for the Power ISA itself
16
17 Links:
18
19 * <https://bugs.libre-soc.org/show_bug.cgi?id=1045>
20
21 # Introduction
22
23 Simple-V is a type of Vectorisation best described as a "Prefix Loop
24 Subsystem" similar to the 5 decades-old Zilog Z80 `LDIR` instruction and
25 to the 8086 `REP` Prefix instruction. More advanced features are similar
26 to the Z80 `CPIR` instruction. If viewed one-dimensionally as an actual
27 Vector ISA it introduces over 1.5 million 64-bit Vector instructions.
28 SVP64, the instruction format used by Simple-V, is therefore best viewed
29 as an orthogonal RISC-paradigm "Prefixing" subsystem instead.
30
31 Except where explicitly stated all bit numbers remain as in the rest of
32 the Power ISA: in MSB0 form (the bits are numbered from 0 at the MSB on
33 the left and counting up as you move rightwards to the LSB end). All bit
34 ranges are inclusive (so `4:6` means bits 4, 5, and 6, in MSB0 order).
35 **All register numbering and element numbering however is LSB0 ordering**
36 which is a different convention from that used elsewhere in the Power ISA.
37
38 The SVP64 prefix always comes before the suffix in PC order and must be
39 considered an independent "Defined word" that augments the behaviour of
40 the following instruction, but does **not** change the actual Decoding
41 of that following instruction. **All prefixed instructions retain their
42 non-prefixed encoding and definition**.
43
44 Two apparent exceptions to the above hard rule exist: SV Branch-Conditional
45 operations and LD/ST-update "Post-Increment" Mode. Post-Increment
46 was considered sufficiently high priority (significantly reducing hot-loop
47 instruction count) that one bit in the Prefix is reserved for it.
48 Vectorised Branch-Conditional operations "embed" the original Scalar
49 Branch-Conditional behaviour into a much more advanced variant that
50 is highly suited to High-Performance Computation (HPC), Supercomputing,
51 and parallel GPU Workloads.
52
53 *Architectural Resource Allocation note: it is prohibited to accept RFCs
54 which fundamentally violate this hard requirement. Under no circumstances
55 must the Suffix space have an alternate instruction encoding allocated
56 within SVP64 that is entirely different from the non-prefixed Defined
57 Word. Hardware Implementors critically rely on this inviolate guarantee
58 to implement High-Performance Multi-Issue micro-architectures that can
59 sustain 100% throughput*
60
61 Subset implementations in hardware are permitted, as long as certain
62 rules are followed, allowing for full soft-emulation including future
63 revisions. Compliancy Subsets exist to ensure minimum levels of binary
64 interoperability expectations within certain environments.
65
66 ## SVP64 encoding features
67
68 A number of features need to be compacted into a very small space of
69 only 24 bits:
70
71 * Independent per-register Scalar/Vector tagging and range extension on
72 every register
73 * Element width overrides on both source and destination
74 * Predication on both source and destination
75 * Two different sources of predication: INT and CR Fields
76 * SV Modes including saturation (for Audio, Video and DSP), mapreduce,
77 fail-first and predicate-result mode.
78
79 Different classes of operations require different formats. The earlier
80 sections cover the common formats and the four separate modes follow:
81 CR operations (crops), Arithmetic/Logical (termed "normal"), Load/Store
82 and Branch-Conditional.
83
84 ## Definition of Reserved in this spec.
85
86 For the new fields added in SVP64, instructions that have any of their
87 fields set to a reserved value must cause an illegal instruction trap,
88 to allow emulation of future instruction sets, or for subsets of SVP64 to
89 be implemented in hardware and the rest emulated. This includes SVP64
90 SPRs: reading or writing values which are not supported in hardware
91 must also raise illegal instruction traps in order to allow emulation.
92 Unless otherwise stated, reserved values are always all zeros.
93
94 This is unlike OpenPower ISA v3.1, which in many instances does not
95 require a trap if reserved fields are nonzero. Where the standard Power
96 ISA definition is intended the red keyword `RESERVED` is used.
97
98 ## Definition of "UnVectoriseable"
99
100 Any operation that inherently makes no sense if repeated is termed
101 "UnVectoriseable" or "UnVectorised". Examples include `sc` or `sync`
102 which have no registers. `mtmsr` is also classed as UnVectoriseable
103 because there is only one `MSR`.
104
105 ## Register files, elements, and Element-width Overrides
106
107 In the Upper Compliancy Levels of SVP64 the size of the GPR and FPR
108 Register files are expanded from 32 to 128 entries, and the number of
109 CR Fields expanded from CR0-CR7 to CR0-CR127. (Note: A future version
110 of SVP64 is anticipated to extend the VSR register file).
111
112 Memory access remains exactly the same: the effects of `MSR.LE` remain
113 exactly the same, affecting as they already do and remain **only**
114 on the Load and Store memory-register operation byte-order, and having
115 nothing to do with the ordering of the contents of register files or
116 register-register operations.
117
118 To be absolutely clear:
119
120 ```
121 There are no conceptual arithmetic ordering or other changes over the
122 Scalar Power ISA definitions to registers or register files or to
123 arithmetic or Logical Operations beyond element-width subdivision
124 ```
125
126 Element offset
127 numbering is naturally **LSB0-sequentially-incrementing from zero, not
128 MSB0-incrementing** including when element-width overrides are used,
129 at which point the elements progress through each register
130 sequentially from the LSB end
131 (confusingly numbered the highest in MSB0 ordering) and progress
132 incrementally to the MSB end (confusingly numbered the lowest in
133 MSB0 ordering).
134
135 When exclusively using MSB0-numbering, SVP64
136 becomes unnecessarily complex to both express and subsequently understand:
137 the required conditional subtractions from 63,
138 31, 15 and 7 needed to express the fact that elements are LSB0-sequential
139 unfortunately become a hostile minefield, obscuring both
140 intent and meaning. Therefore for the
141 purposes of this section the more natural **LSB0 numbering is assumed**
142 and it is left to the reader to translate to MSB0 numbering.
143
144 The Canonical specification for how element-sequential numbering and
145 element-width overrides is defined is expressed in the following c
146 structure, assuming a Little-Endian system, and naturally using LSB0
147 numbering everywhere because the ANSI c specification is inherently LSB0.
148 Note the deliberate similarity to how VSX register elements are defined:
149
150 ```
151 #pragma pack
152 typedef union {
153 uint8_t bytes[]; // elwidth 8
154 uint16_t hwords[]; // elwidth 16
155 uint32_t words[]; // elwidth 32
156 uint64_t dwords[]; // elwidth 64
157 uint8_t actual_bytes[8];
158 } el_reg_t;
159
160 elreg_t int_regfile[128];
161
162 void get_register_element(el_reg_t* el, int gpr, int element, int width) {
163 switch (width) {
164 case 64: el->dwords = int_regfile[gpr].dwords[element];
165 case 32: el->words = int_regfile[gpr].words[element];
166 case 16: el->hwords = int_regfile[gpr].hwords[element];
167 case 8 : el->bytes = int_regfile[gpr].bytes[element];
168 }
169 }
170 void set_register_element(el_reg_t* el, int gpr, int element, int width) {
171 switch (width) {
172 case 64: int_regfile[gpr].dwords[element] = el->dwords;
173 case 32: int_regfile[gpr].words[element] = el->words;
174 case 16: int_regfile[gpr].hwords[element] = el->hwords;
175 case 8 : int_regfile[gpr].bytes[element] = el->bytes;
176 }
177 }
178 ```
179
180 Example Vector-looped add operation implementation when elwidths are 64-bit:
181
182 ```
183 # vector-add RT, RA,RB using the "uint64_t" union member, "l"
184 for i in range(VL):
185 int_regfile[RT].l[i] = int_regfile[RA].l[i] + int_regfile[RB].l[i]
186 ```
187
188 However if elwidth overrides are set to 16 for both source and destination:
189
190 ```
191 # vector-add RT, RA, RB using the "uint64_t" union member "s"
192 for i in range(VL):
193 int_regfile[RT].s[i] = int_regfile[RA].s[i] + int_regfile[RB].s[i]
194 ```
195
196 Hardware Architectural note: to avoid a Read-Modify-Write at the register
197 file it is strongly recommended to implement byte-level write-enable lines
198 exactly as has been implemented in DRAM ICs for many decades. Additionally
199 the predicate mask bit is advised to be associated with the element
200 operation and alongside the result ultimately passed to the register file.
201 When element-width is set to 64-bit the relevant predicate mask bit
202 may be repeated eight times and pull all eight write-port byte-level
203 lines HIGH. Clearly when element-width is set to 8-bit the relevant
204 predicate mask bit corresponds directly with one single byte-level
205 write-enable line. It is up to the Hardware Architect to then amortise
206 (merge) elements together into both PredicatedSIMD Pipelines as well
207 as simultaneous non-overlapping Register File writes, to achieve High
208 Performance designs.
209
210 For a comparative data point the VSR Registers may be expressed in the
211 same fashion. The c code below is directly an expression of Figure 97 in
212 Power ISA Public v3.1 Book I Section 6.3 page 258, *after compensating for
213 MSB0 numbering and adapting in full to LSB0 numbering and obeying LE
214 ordering*.
215
216 **Crucial to understanding why the subtraction from 1,3,7,15 is present
217 is because VSX Registers number elements also in MSB0 order**. SVP64
218 very specifically numbers elements in **LSB0** order with the first
219 element being at the **LSB** end of the register, where VSX places
220 the numerically-lowest element at the **MSB** end of the register.
221
222 ```
223 #pragma pack
224 typedef union {
225 uint8_t bytes[16]; // elwidth 8, QTY 16 FIXED total
226 uint16_t hwords[8]; // elwidth 16, QTY 8 FIXED total
227 uint32_t words[4]; // elwidth 32, QTY 8 FIXED total
228 uint64_t dwords[2]; // elwidth 64, QTY 2 FIXED total
229 uint8_t actual_bytes[16]; // totals 128-bit
230 } el_reg_t;
231
232 elreg_t VSR_regfile[64];
233
234 static void check_num_elements(int elt, int width) {
235 switch (width) {
236 case 64: assert elt < 2;
237 case 32: assert elt < 4;
238 case 16: assert elt < 8;
239 case 8 : assert elt < 16;
240 }
241 }
242 void get_VSR_element(el_reg_t* el, int gpr, int elt, int width) {
243 check_num_elements(elt, width);
244 switch (width) {
245 case 64: el->dwords[1-elt] = VSR_regfile[gpr].dwords[1-elt];
246 case 32: el->words[3-elt] = VSR_regfile[gpr].words[3-elt];
247 case 16: el->hwords[7-elt] = VSR_regfile[gpr].hwords[7-elt];
248 case 8 : el->bytes[15-elt] = VSR_regfile[gpr].bytes[15-elt];
249 }
250 }
251 void set_register_element(el_reg_t* el, int gpr, int elt, int width) {
252 check_num_elements(elt, width);
253 switch (width) {
254 case 64: VSR_regfile[gpr].dwords[elt] = el->dwords[1-elt];
255 case 32: VSR_regfile[gpr].words[3-elt] = el->words[3-elt];
256 case 16: VSR_regfile[gpr].hwords[7-elt] = el->hwords[7-elt];
257 case 8 : VSR_regfile[gpr].bytes[15-elt] = el->bytes[15-elt];
258 }
259 }
260 ```
261
262 For VSX Registers one key difference is that the overlay of different element
263 widths is clearly a *bounded quantity*, whereas for Simple-V the elements are
264 *unrestrained and permitted to flow into successive underlying Scalar registers*.
265 This difference is absolutely critical to a full understanding of the entire
266 Simple-V paradigm and why element-ordering, bit-numbering *and register numbering*
267 are all so strictly defined.
268
269 Implementations are not permitted to violate the Canonical definition: software
270 will be critically relying on the wrapped (overflow) behaviour inherently
271 implied from the unbounded c arrays.
272
273 ## Scalar Identity Behaviour
274
275 SVP64 is designed so that when the prefix is all zeros, and VL=1, no
276 effect or influence occurs (no augmentation) such that all standard Power
277 ISA v3.0/v3.1 instructions covered by the prefix are "unaltered". This
278 is termed `scalar identity behaviour` (based on the mathematical
279 definition for "identity", as in, "identity matrix" or better "identity
280 transformation").
281
282 Note that this is completely different from when VL=0. VL=0 turns all
283 operations under its influence into `nops` (regardless of the prefix)
284 whereas when VL=1 and the SV prefix is all zeros, the operation simply
285 acts as if SV had not been applied at all to the instruction (an
286 "identity transformation").
287
288 The fact that `VL` is dynamic and can be set to any value at runtime based
289 on program conditions and behaviour means very specifically that
290 `scalar identity behaviour` is **not** a redundant encoding. If the
291 only means by which VL could be set was by way of static-compiled
292 immediates then this assertion would be false. VL should not
293 be confused with MAXVL when understanding this key aspect of SimpleV.
294
295 ## Register Naming and size
296
297 As indicated above SV Registers are simply the GPR, FPR and CR
298 register files extended linearly to larger sizes; SV Vectorisation
299 iterates sequentially through these registers (LSB0 sequential ordering
300 from 0 to VL-1).
301
302 Where the integer regfile in standard scalar Power ISA v3.0B/v3.1B is
303 r0 to r31, SV extends this as r0 to r127. Likewise FP registers are
304 extended to 128 (fp0 to fp127), and CR Fields are extended to 128 entries,
305 CR0 thru CR127.
306
307 The names of the registers therefore reflects a simple linear extension
308 of the Power ISA v3.0B / v3.1B register naming, and in hardware this
309 would be reflected by a linear increase in the size of the underlying
310 SRAM used for the regfiles.
311
312 Note: when an EXTRA field (defined below) is zero, SV is deliberately
313 designed so that the register fields are identical to as if SV was not in
314 effect i.e. under these circumstances (EXTRA=0) the register field names
315 RA, RB etc. are interpreted and treated as v3.0B / v3.1B scalar registers.
316 This is part of `scalar identity behaviour` described above.
317
318 **Condition Register(s)**
319
320 The Scalar Power ISA Condition Register is a 64 bit register where the top
321 32 MSBs (numbered 0:31 in MSB0 numbering) are not used. This convention is
322 *preserved*
323 in SVP64 and an additional 15 Condition Registers provided in
324 order to store the new CR Fields, CR8-CR15, CR16-CR23 etc. sequentially.
325 The top 32 MSBs in each new SVP64 Condition Register are *also* not used:
326 only the bottom 32 bits (numbered 32:63 in MSB0 numbering).
327
328 *Programmer's note: using `sv.mfcr` without element-width overrides
329 to take into account the fact that the top 32 MSBs are zero and thus
330 effectively doubling the number of GPR registers required to hold all 128
331 CR Fields would seem the only option because normally elwidth overrides
332 would halve the capacity of the instruction. However in this case it
333 is possible to use destination element-width overrides (for `sv.mfcr`.
334 source overrides would be used on the GPR of `sv.mtocrf`), whereupon
335 truncation of the 64-bit Condition Register(s) occurs, throwing away
336 the zeros and storing the remaining (valid, desired) 32-bit values
337 sequentially into (LSB0-convention) lower-numbered and upper-numbered
338 halves of GPRs respectively. The programmer is expected to be aware
339 however that the full width of the entire 64-bit Condition Register
340 is considered to be "an element". This is **not** like any other
341 Condition-Register instructions because all other CR instructions,
342 on closer investigation, will be observed to all be CR-bit or CR-Field
343 related. Thus a `VL` of 16 must be used*
344
345 ## Future expansion.
346
347 With the way that EXTRA fields are defined and applied to register fields,
348 future versions of SV may involve 256 or greater registers. Backwards
349 binary compatibility may be achieved with a PCR bit (Program Compatibility
350 Register) or an MSR bit analogous to SF.
351 Further discussion is out of scope for this version of SVP64.
352
353 Additionally, a future variant of SVP64 will be applied to the Scalar
354 (Quad-precision and 128-bit) VSX instructions. Element-width overrides
355 are an opportunity to expand a future version of the Power ISA
356 to 256-bit, 512-bit and
357 1024-bit operations, as well as doubling or quadrupling the number
358 of VSX registers to 128 or 256. Again further discussion is out of
359 scope for this version of SVP64.
360
361 --------
362
363 \newpage{}
364
365 # New 64-bit Instruction Encoding spaces
366
367 The following seven new areas are defined within Primary Opcode 9 (EXT009)
368 as a new 64-bit encoding space, alongside EXT1xx.
369
370 | 0-5 | 6 | 7 | 8-31 | 32| Description |
371 |-----|---|---|-------|---|------------------------------------|
372 | PO | 0 | x | xxxx | 0 | `RESERVED2` (56-bit) |
373 | PO | 0 | 0 | !zero | 1 | SVP64Single:EXT232-263, or `RESERVED3` |
374 | PO | 0 | 0 | 0000 | 1 | Scalar EXT232-263 |
375 | PO | 0 | 1 | nnnn | 1 | SVP64:EXT232-263 |
376 | PO | 1 | 0 | 0000 | x | `RESERVED1` (32-bit) |
377 | PO | 1 | 0 | !zero | n | SVP64Single:EXT000-063 or `RESERVED4` |
378 | PO | 1 | 1 | nnnn | n | SVP64:EXT000-063 |
379
380 Note that for the future SVP64Single Encoding (currently RESERVED3 and 4)
381 it is prohibited to have bits 8-31 be zero, unlike for SVP64 Vector space,
382 for which bits 8-31 can be zero (termed `scalar identity behaviour`). This
383 prohibition allows SVP64Single to share its Encoding space with Scalar
384 Ext232-263 and Scalar EXT300-363.
385
386 Also that RESERVED1 and 2 are candidates for future Major opcode
387 areas EXT200-231 and EXT300-363 respectively, however as RESERVED areas
388 they may equally be allocated entirely differently.
389
390 *Architectural Resource Allocation Note: **under no circumstances** must
391 different Defined Words be allocated within any `EXT{z}` prefixed
392 or unprefixed space for a given value of `z`. Even if UnVectoriseable
393 an instruction Defined Word space must have the exact same Instruction
394 and exact same Instruction Encoding in all spaces (including
395 being RESERVED if UnVectoriseable) or not be allocated at all.
396 This is required as an inviolate hard rule governing Primary Opcode 9
397 that may not be revoked under any circumstances. A useful way to think
398 of this is that the Prefix Encoding is, like the 8086 REP instruction,
399 an independent 32-bit Defined Word. The only semi-exceptions are
400 the Post-Increment Mode of LD/ST-Update and Vectorised Branch-Conditional.*
401
402 Ecoding spaces and their potential are illustrated:
403
404 | Encoding | Available bits | Scalar | Vectoriseable | SVP64Single |
405 |----------|----------------|--------|---------------|--------------|
406 |EXT000-063| 32 | yes | yes |yes |
407 |EXT100-163| 64 (?) | yes | no |no |
408 |R3SERVED2 | 56 | N/A |not applicable |not applicable|
409 |EXT232-263| 32 | yes | yes |yes |
410 |RESERVED1 | 32 | N/A | no |no |
411
412 Prefixed-Prefixed (96-bit) instructions are prohibited. RESERVED2 presently
413 remains unallocated as of yet and therefore its potential is not yet defined
414 (Not Applicable). RESERVED1 is also unallocated at present, but it is
415 known in advance that the area is UnVectoriseable and also cannot be
416 Prefixed with SVP64Single.
417
418 # Remapped Encoding (`RM[0:23]`)
419
420 In the SVP64 Vector Prefix spaces, the 24 bits 8-31 are termed `RM`. Bits
421 32-37 are the Primary Opcode of the Suffix "Defined Word". 38-63 are the
422 remainder of the Defined Word. Note that the new EXT232-263 SVP64 area
423 it is obviously mandatory that bit 32 is required to be set to 1.
424
425 | 0-5 | 6 | 7 | 8-31 | 32-37 | 38-64 |Description |
426 |-----|---|---|----------|--------|----------|-----------------------|
427 | PO | 0 | 1 | RM[0:23] | 1nnnnn | xxxxxxxx | SVP64:EXT232-263 |
428 | PO | 1 | 1 | RM[0:23] | nnnnnn | xxxxxxxx | SVP64:EXT000-063 |
429
430 It is important to note that unlike v3.1 64-bit prefixed instructions
431 there is insufficient space in `RM` to provide identification of
432 any SVP64 Fields without first partially decoding the 32-bit suffix.
433 Similar to the "Forms" (X-Form, D-Form) the `RM` format is individually
434 associated with every instruction. However this still does not adversely
435 affect Multi-Issue Decoding because the identification of the *length*
436 of anything in the 64-bit space has been kept brutally simple (EXT009),
437 and further decoding of any number of 64-bit Encodings in parallel at
438 that point is fully independent.
439
440 Extreme caution and care must be taken when extending SVP64
441 in future, to not create unnecessary relationships between prefix and
442 suffix that could complicate decoding, adding latency.
443
444 ## Common RM fields
445
446 The following fields are common to all Remapped Encodings:
447
448 | Field Name | Field bits | Description |
449 |------------|------------|----------------------------------------|
450 | MASKMODE | `0` | Execution (predication) Mask Kind |
451 | MASK | `1:3` | Execution Mask |
452 | SUBVL | `8:9` | Sub-vector length |
453
454 The following fields are optional or encoded differently depending
455 on context after decoding of the Scalar suffix:
456
457 | Field Name | Field bits | Description |
458 |------------|------------|----------------------------------------|
459 | ELWIDTH | `4:5` | Element Width |
460 | ELWIDTH_SRC | `6:7` | Element Width for Source |
461 | EXTRA | `10:18` | Register Extra encoding |
462 | MODE | `19:23` | changes Vector behaviour |
463
464 * MODE changes the behaviour of the SV operation (result saturation,
465 mapreduce)
466 * SUBVL groups elements together into vec2, vec3, vec4 for use in 3D
467 and Audio/Video DSP work
468 * ELWIDTH and ELWIDTH_SRC overrides the instruction's destination and
469 source operand width
470 * MASK (and MASK_SRC) and MASKMODE provide predication (two types of
471 sources: scalar INT and Vector CR).
472 * Bits 10 to 18 (EXTRA) are further decoded depending on the RM category
473 for the instruction, which is determined only by decoding the Scalar 32
474 bit suffix.
475
476 Similar to Power ISA `X-Form` etc. EXTRA bits are given designations,
477 such as `RM-1P-3S1D` which indicates for this example that the operation
478 is to be single-predicated and that there are 3 source operand EXTRA
479 tags and one destination operand tag.
480
481 Note that if ELWIDTH != ELWIDTH_SRC this may result in reduced performance
482 or increased latency in some implementations due to lane-crossing.
483
484 ## Mode
485
486 Mode is an augmentation of SV behaviour. Different types of instructions
487 have different needs, similar to Power ISA v3.1 64 bit prefix 8LS and MTRR
488 formats apply to different instruction types. Modes include Reduction,
489 Iteration, arithmetic saturation, and Fail-First. More specific details
490 in each section and in the SVP64 appendix
491
492 * For condition register operations see [[sv/cr_ops]]
493 * For LD/ST Modes, see [[sv/ldst]].
494 * For Branch modes, see [[sv/branches]]
495 * For arithmetic and logical, see [[sv/normal]]
496
497 ## ELWIDTH Encoding
498
499 Default behaviour is set to 0b00 so that zeros follow the convention
500 of `scalar identity behaviour`. In this case it means that elwidth
501 overrides are not applicable. Thus if a 32 bit instruction operates
502 on 32 bit, `elwidth=0b00` specifies that this behaviour is unmodified.
503 Likewise when a processor is switched from 64 bit to 32 bit mode,
504 `elwidth=0b00` states that, again, the behaviour is not to be modified.
505
506 Only when elwidth is nonzero is the element width overridden to the
507 explicitly required value.
508
509 ### Elwidth for Integers:
510
511 | Value | Mnemonic | Description |
512 |-------|----------------|------------------------------------|
513 | 00 | DEFAULT | default behaviour for operation |
514 | 01 | `ELWIDTH=w` | Word: 32-bit integer |
515 | 10 | `ELWIDTH=h` | Halfword: 16-bit integer |
516 | 11 | `ELWIDTH=b` | Byte: 8-bit integer |
517
518 This encoding is chosen such that the byte width may be computed as
519 `8<<(3-ew)`
520
521 ### Elwidth for FP Registers:
522
523 | Value | Mnemonic | Description |
524 |-------|----------------|------------------------------------|
525 | 00 | DEFAULT | default behaviour for FP operation |
526 | 01 | `ELWIDTH=f32` | 32-bit IEEE 754 Single floating-point |
527 | 10 | `ELWIDTH=f16` | 16-bit IEEE 754 Half floating-point |
528 | 11 | `ELWIDTH=bf16` | Reserved for `bf16` |
529
530 Note:
531 [`bf16`](https://en.wikipedia.org/wiki/Bfloat16_floating-point_format)
532 is reserved for a future implementation of SV
533
534 Note that any IEEE754 FP operation in Power ISA ending in "s" (`fadds`)
535 shall perform its operation at **half** the ELWIDTH then padded back out
536 to ELWIDTH. `sv.fadds/ew=f32` shall perform an IEEE754 FP16 operation
537 that is then "padded" to fill out to an IEEE754 FP32. When ELWIDTH=DEFAULT
538 clearly the behaviour of `sv.fadds` is performed at 32-bit accuracy
539 then padded back out to fit in IEEE754 FP64, exactly as for Scalar
540 v3.0B "single" FP. Any FP operation ending in "s" where ELWIDTH=f16 or
541 ELWIDTH=bf16 is reserved and must raise an illegal instruction (IEEE754
542 FP8 or BF8 are not defined).
543
544 ### Elwidth for CRs (no meaning)
545
546 Element-width overrides for CR Fields has no meaning. The bits
547 are therefore used for other purposes, or when Rc=1, the Elwidth
548 applies to the result being tested (a GPR or FPR), but not to the
549 Vector of CR Fields.
550
551 ## SUBVL Encoding
552
553 The default for SUBVL is 1 and its encoding is 0b00 to indicate that
554 SUBVL is effectively disabled (a SUBVL for-loop of only one element). this
555 lines up in combination with all other "default is all zeros" behaviour.
556
557 | Value | Mnemonic | Subvec | Description |
558 |-------|-----------|---------|------------------------|
559 | 00 | `SUBVL=1` | single | Sub-vector length of 1 |
560 | 01 | `SUBVL=2` | vec2 | Sub-vector length of 2 |
561 | 10 | `SUBVL=3` | vec3 | Sub-vector length of 3 |
562 | 11 | `SUBVL=4` | vec4 | Sub-vector length of 4 |
563
564 The SUBVL encoding value may be thought of as an inclusive range of a
565 sub-vector. SUBVL=2 represents a vec2, its encoding is 0b01, therefore
566 this may be considered to be elements 0b00 to 0b01 inclusive.
567
568 ## MASK/MASK_SRC & MASKMODE Encoding
569
570 One bit (`MASKMODE`) indicates the mode: CR or Int predication. The two
571 types may not be mixed.
572
573 Special note: to disable predication this field must be set to zero in
574 combination with Integer Predication also being set to 0b000. this has the
575 effect of enabling "all 1s" in the predicate mask, which is equivalent to
576 "not having any predication at all" and consequently, in combination with
577 all other default zeros, fully disables SV (`scalar identity behaviour`).
578
579 `MASKMODE` may be set to one of 2 values:
580
581 | Value | Description |
582 |-----------|------------------------------------------------------|
583 | 0 | MASK/MASK_SRC are encoded using Integer Predication |
584 | 1 | MASK/MASK_SRC are encoded using CR-based Predication |
585
586 Integer Twin predication has a second set of 3 bits that uses the same
587 encoding thus allowing either the same register (r3, r10 or r31) to be
588 used for both src and dest, or different regs (one for src, one for dest).
589
590 Likewise CR based twin predication has a second set of 3 bits, allowing
591 a different test to be applied.
592
593 Note that it is assumed that Predicate Masks (whether INT or CR) are
594 read *before* the operations proceed. In practice (for CR Fields)
595 this creates an unnecessary block on parallelism. Therefore, it is up
596 to the programmer to ensure that the CR fields used as Predicate Masks
597 are not being written to by any parallel Vector Loop. Doing so results
598 in **UNDEFINED** behaviour, according to the definition outlined in the
599 Power ISA v3.0B Specification.
600
601 Hardware Implementations are therefore free and clear to delay reading
602 of individual CR fields until the actual predicated element operation
603 needs to take place, safe in the knowledge that no programmer will have
604 issued a Vector Instruction where previous elements could have overwritten
605 (destroyed) not-yet-executed CR-Predicated element operations.
606
607 ### Integer Predication (MASKMODE=0)
608
609 When the predicate mode bit is zero the 3 bits are interpreted as below.
610 Twin predication has an identical 3 bit field similarly encoded.
611
612 `MASK` and `MASK_SRC` may be set to one of 8 values, to provide the
613 following meaning:
614
615 | Value | Mnemonic | Element `i` enabled if: |
616 |-------|----------|------------------------------|
617 | 000 | ALWAYS | predicate effectively all 1s |
618 | 001 | 1 << R3 | `i == R3` |
619 | 010 | R3 | `R3 & (1 << i)` is non-zero |
620 | 011 | ~R3 | `R3 & (1 << i)` is zero |
621 | 100 | R10 | `R10 & (1 << i)` is non-zero |
622 | 101 | ~R10 | `R10 & (1 << i)` is zero |
623 | 110 | R30 | `R30 & (1 << i)` is non-zero |
624 | 111 | ~R30 | `R30 & (1 << i)` is zero |
625
626 r10 and r30 are at the high end of temporary and unused registers,
627 so as not to interfere with register allocation from ABIs.
628
629 ### CR-based Predication (MASKMODE=1)
630
631 When the predicate mode bit is one the 3 bits are interpreted as below.
632 Twin predication has an identical 3 bit field similarly encoded.
633
634 `MASK` and `MASK_SRC` may be set to one of 8 values, to provide the
635 following meaning:
636
637 | Value | Mnemonic | Element `i` is enabled if |
638 |-------|----------|--------------------------|
639 | 000 | lt | `CR[offs+i].LT` is set |
640 | 001 | nl/ge | `CR[offs+i].LT` is clear |
641 | 010 | gt | `CR[offs+i].GT` is set |
642 | 011 | ng/le | `CR[offs+i].GT` is clear |
643 | 100 | eq | `CR[offs+i].EQ` is set |
644 | 101 | ne | `CR[offs+i].EQ` is clear |
645 | 110 | so/un | `CR[offs+i].FU` is set |
646 | 111 | ns/nu | `CR[offs+i].FU` is clear |
647
648 `offs` is defined as CR32 (4x8) so as to mesh cleanly with Vectorised
649 Rc=1 operations (see below). Rc=1 operations start from CR8 (TBD).
650
651 The CR Predicates chosen must start on a boundary that Vectorised CR
652 operations can access cleanly, in full. With EXTRA2 restricting starting
653 points to multiples of 8 (CR0, CR8, CR16...) both Vectorised Rc=1 and
654 CR Predicate Masks have to be adapted to fit on these boundaries as well.
655
656 ## Extra Remapped Encoding <a name="extra_remap"> </a>
657
658 Shows all instruction-specific fields in the Remapped Encoding
659 `RM[10:18]` for all instruction variants. Note that due to the very
660 tight space, the encoding mode is *not* included in the prefix itself.
661 The mode is "applied", similar to Power ISA "Forms" (X-Form, D-Form)
662 on a per-instruction basis, and, like "Forms" are given a designation
663 (below) of the form `RM-nP-nSnD`. The full list of which instructions
664 use which remaps is here [[opcode_regs_deduped]].
665
666 **Please note the following**:
667
668 ```
669 Machine-readable CSV files have been provided which will make the task
670 of creating SV-aware ISA decoders, documentation, assembler tools
671 compiler tools Simulators documentation all aspects of SVP64 easier
672 and less prone to mistakes. Please avoid manual re-creation of
673 information from the written specification wording, and use the
674 CSV files or use the Canonical tool which creates the CSV files,
675 named sv_analysis.py. The information contained within sv_analysis.py
676 is considered to be part of this Specification, even encoded as it
677 is in python3.
678 ```
679
680 The mappings are part of the SVP64 Specification in exactly the same
681 way as X-Form, D-Form. New Scalar instructions added to the Power ISA
682 will need a corresponding SVP64 Mapping, which can be derived by-rote
683 from examining the Register "Profile" of the instruction.
684
685 There are two categories: Single and Twin Predication. Due to space
686 considerations further subdivision of Single Predication is based on
687 whether the number of src operands is 2 or 3. With only 9 bits available
688 some compromises have to be made.
689
690 * `RM-1P-3S1D` Single Predication dest/src1/2/3, applies to 4-operand
691 instructions (fmadd, isel, madd).
692 * `RM-1P-2S1D` Single Predication dest/src1/2 applies to 3-operand
693 instructions (src1 src2 dest)
694 * `RM-2P-1S1D` Twin Predication (src=1, dest=1)
695 * `RM-2P-2S1D` Twin Predication (src=2, dest=1) primarily for LDST (Indexed)
696 * `RM-2P-1S2D` Twin Predication (src=1, dest=2) primarily for LDST Update
697
698 ### RM-1P-3S1D
699
700 | Field Name | Field bits | Description |
701 |------------|------------|----------------------------------------|
702 | Rdest\_EXTRA2 | `10:11` | extends Rdest (R\*\_EXTRA2 Encoding) |
703 | Rsrc1\_EXTRA2 | `12:13` | extends Rsrc1 (R\*\_EXTRA2 Encoding) |
704 | Rsrc2\_EXTRA2 | `14:15` | extends Rsrc2 (R\*\_EXTRA2 Encoding) |
705 | Rsrc3\_EXTRA2 | `16:17` | extends Rsrc3 (R\*\_EXTRA2 Encoding) |
706 | EXTRA2_MODE | `18` | used by `divmod2du` and `maddedu` for RS |
707
708 These are for 3 operand in and either 1 or 2 out instructions.
709 3-in 1-out includes `madd RT,RA,RB,RC`. (DRAFT) instructions
710 such as `maddedu` have an implicit second destination, RS, the
711 selection of which is determined by bit 18.
712
713 ### RM-1P-2S1D
714
715 | Field Name | Field bits | Description |
716 |------------|------------|-------------------------------------------|
717 | Rdest\_EXTRA3 | `10:12` | extends Rdest |
718 | Rsrc1\_EXTRA3 | `13:15` | extends Rsrc1 |
719 | Rsrc2\_EXTRA3 | `16:18` | extends Rsrc3 |
720
721 These are for 2 operand 1 dest instructions, such as `add RT, RA,
722 RB`. However also included are unusual instructions with an implicit
723 dest that is identical to its src reg, such as `rlwinmi`.
724
725 Normally, with instructions such as `rlwinmi`, the scalar v3.0B ISA would
726 not have sufficient bit fields to allow an alternative destination.
727 With SV however this becomes possible. Therefore, the fact that the
728 dest is implicitly also a src should not mislead: due to the *prefix*
729 they are different SV regs.
730
731 * `rlwimi RA, RS, ...`
732 * Rsrc1_EXTRA3 applies to RS as the first src
733 * Rsrc2_EXTRA3 applies to RA as the secomd src
734 * Rdest_EXTRA3 applies to RA to create an **independent** dest.
735
736 With the addition of the EXTRA bits, the three registers
737 each may be *independently* made vector or scalar, and be independently
738 augmented to 7 bits in length.
739
740 ### RM-2P-1S1D/2S
741
742 | Field Name | Field bits | Description |
743 |------------|------------|----------------------------|
744 | Rdest_EXTRA3 | `10:12` | extends Rdest |
745 | Rsrc1_EXTRA3 | `13:15` | extends Rsrc1 |
746 | MASK_SRC | `16:18` | Execution Mask for Source |
747
748 `RM-2P-2S` is for `stw` etc. and is Rsrc1 Rsrc2.
749
750 ### RM-1P-2S1D
751
752 single-predicate, three registers (2 read, 1 write)
753
754 | Field Name | Field bits | Description |
755 |------------|------------|----------------------------|
756 | Rdest_EXTRA3 | `10:12` | extends Rdest |
757 | Rsrc1_EXTRA3 | `13:15` | extends Rsrc1 |
758 | Rsrc2_EXTRA3 | `16:18` | extends Rsrc2 |
759
760 ### RM-2P-2S1D/1S2D/3S
761
762 The primary purpose for this encoding is for Twin Predication on LOAD
763 and STORE operations. see [[sv/ldst]] for detailed anslysis.
764
765 **RM-2P-2S1D:**
766
767 | Field Name | Field bits | Description |
768 |------------|------------|----------------------------|
769 | Rdest_EXTRA2 | `10:11` | extends Rdest (R\*\_EXTRA2 Encoding) |
770 | Rsrc1_EXTRA2 | `12:13` | extends Rsrc1 (R\*\_EXTRA2 Encoding) |
771 | Rsrc2_EXTRA2 | `14:15` | extends Rsrc2 (R\*\_EXTRA2 Encoding) |
772 | MASK_SRC | `16:18` | Execution Mask for Source |
773
774 **RM-2P-1S2D:**
775
776 For RM-2P-1S2D the EXTRA2 dest and src names are switched (Rsrc_EXTRA2
777 is in bits 10:11, Rdest1_EXTRA2 in 12:13)
778
779 | Field Name | Field bits | Description |
780 |------------|------------|----------------------------|
781 | Rsrc2_EXTRA2 | `10:11` | extends Rsrc2 (R\*\_EXTRA2 Encoding) |
782 | Rsrc1_EXTRA2 | `12:13` | extends Rsrc1 (R\*\_EXTRA2 Encoding) |
783 | Rdest_EXTRA2 | `14:15` | extends Rdest (R\*\_EXTRA2 Encoding) |
784 | MASK_SRC | `16:18` | Execution Mask for Source |
785
786 **RM-2P-3S:**
787
788 Also that for RM-2P-3S (to cover `stdx` etc.) the names are switched to 3 src:
789 Rsrc1_EXTRA2, Rsrc2_EXTRA2, Rsrc3_EXTRA2.
790
791 | Field Name | Field bits | Description |
792 |------------|------------|----------------------------|
793 | Rsrc1_EXTRA2 | `10:11` | extends Rsrc1 (R\*\_EXTRA2 Encoding) |
794 | Rsrc2_EXTRA2 | `12:13` | extends Rsrc2 (R\*\_EXTRA2 Encoding) |
795 | Rsrc3_EXTRA2 | `14:15` | extends Rsrc3 (R\*\_EXTRA2 Encoding) |
796 | MASK_SRC | `16:18` | Execution Mask for Source |
797
798 Note also that LD with update indexed, which takes 2 src and
799 creates 2 dest registers (e.g. `lhaux RT,RA,RB`), does not have room
800 for 4 registers and also Twin Predication. Therefore these are treated as
801 RM-2P-2S1D and the src spec for RA is also used for the same RA as a dest.
802
803 Note that if ELWIDTH != ELWIDTH_SRC this may result in reduced performance
804 or increased latency in some implementations due to lane-crossing.
805
806 ## R\*\_EXTRA2/3
807
808 EXTRA is the means by which two things are achieved:
809
810 1. Registers are marked as either Vector *or Scalar*
811 2. Register field numbers (limited typically to 5 bit)
812 are extended in range, both for Scalar and Vector.
813
814 The register files are therefore extended:
815
816 * INT (GPR) is extended from r0-31 to r0-127
817 * FP (FPR) is extended from fp0-32 to fp0-fp127
818 * CR Fields are extended from CR0-7 to CR0-127
819
820 However due to pressure in `RM.EXTRA` not all these registers
821 are accessible by all instructions, particularly those with
822 a large number of operands (`madd`, `isel`).
823
824 In the following tables register numbers are constructed from the
825 standard v3.0B / v3.1B 32 bit register field (RA, FRA) and the EXTRA2 or
826 EXTRA3 field from the SV Prefix, determined by the specific RM-xx-yyyy
827 designation for a given instruction. The prefixing is arranged so that
828 interoperability between prefixing and nonprefixing of scalar registers
829 is direct and convenient (when the EXTRA field is all zeros).
830
831 A pseudocode algorithm explains the relationship, for INT/FP (see
832 SVP64 appendix for CRs)
833
834 ```
835 if extra3_mode:
836 spec = EXTRA3
837 else:
838 spec = EXTRA2 << 1 # same as EXTRA3, shifted
839 if spec[0]: # vector
840 return (RA << 2) | spec[1:2]
841 else: # scalar
842 return (spec[1:2] << 5) | RA
843 ```
844
845 Future versions may extend to 256 by shifting Vector numbering up.
846 Scalar will not be altered.
847
848 Note that in some cases the range of starting points for Vectors
849 is limited.
850
851 ### INT/FP EXTRA3
852
853 If EXTRA3 is zero, maps to "scalar identity" (scalar Power ISA field
854 naming).
855
856 Fields are as follows:
857
858 * Value: R_EXTRA3
859 * Mode: register is tagged as scalar or vector
860 * Range/Inc: the range of registers accessible from this EXTRA
861 encoding, and the "increment" (accessibility). "/4" means
862 that this EXTRA encoding may only give access (starting point)
863 every 4th register.
864 * MSB..LSB: the bit field showing how the register opcode field
865 combines with EXTRA to give (extend) the register number (GPR)
866
867 | Value | Mode | Range/Inc | 6..0 |
868 |-----------|-------|---------------|---------------------|
869 | 000 | Scalar | `r0-r31`/1 | `0b00 RA` |
870 | 001 | Scalar | `r32-r63`/1 | `0b01 RA` |
871 | 010 | Scalar | `r64-r95`/1 | `0b10 RA` |
872 | 011 | Scalar | `r96-r127`/1 | `0b11 RA` |
873 | 100 | Vector | `r0-r124`/4 | `RA 0b00` |
874 | 101 | Vector | `r1-r125`/4 | `RA 0b01` |
875 | 110 | Vector | `r2-r126`/4 | `RA 0b10` |
876 | 111 | Vector | `r3-r127`/4 | `RA 0b11` |
877
878 ### INT/FP EXTRA2
879
880 If EXTRA2 is zero will map to
881 "scalar identity behaviour" i.e Scalar Power ISA register naming:
882
883 | Value | Mode | Range/inc | 6..0 |
884 |----------|-------|---------------|-----------|
885 | 00 | Scalar | `r0-r31`/1 | `0b00 RA` |
886 | 01 | Scalar | `r32-r63`/1 | `0b01 RA` |
887 | 10 | Vector | `r0-r124`/4 | `RA 0b00` |
888 | 11 | Vector | `r2-r126`/4 | `RA 0b10` |
889
890 **Note that unlike in EXTRA3, in EXTRA2**:
891
892 * the GPR Vectors may only start from
893 `r0, r2, r4, r6, r8` and likewise FPR Vectors.
894 * the GPR Scalars may only go from `r0, r1, r2.. r63` and likewise FPR Scalars.
895
896 as there is insufficient bits to cover the full range.
897
898 ### CR Field EXTRA3
899
900 CR Field encoding is essentially the same but made more complex due to CRs
901 being bit-based, because the application of SVP64 element-numbering applies
902 to the CR *Field* numbering not the CR register *bit* numbering.
903 Note that Vectors may only start from `CR0, CR4, CR8, CR12, CR16, CR20`...
904 and Scalars may only go from `CR0, CR1, ... CR31`
905
906 Encoding shown MSB down to LSB
907
908 For a 5-bit operand (BA, BB, BT):
909
910 | Value | Mode | Range/Inc | 8..5 | 4..2 | 1..0 |
911 |-------|------|---------------|-----------| --------|---------|
912 | 000 | Scalar | `CR0-CR7`/1 | 0b0000 | BA[0:2] | BA[3:4] |
913 | 001 | Scalar | `CR8-CR15`/1 | 0b0001 | BA[0:2] | BA[3:4] |
914 | 010 | Scalar | `CR16-CR23`/1 | 0b0010 | BA[0:2] | BA[3:4] |
915 | 011 | Scalar | `CR24-CR31`/1 | 0b0011 | BA[0:2] | BA[3:4] |
916 | 100 | Vector | `CR0-CR112`/16 | BA[0:2] 0 | 0b000 | BA[3:4] |
917 | 101 | Vector | `CR4-CR116`/16 | BA[0:2] 0 | 0b100 | BA[3:4] |
918 | 110 | Vector | `CR8-CR120`/16 | BA[0:2] 1 | 0b000 | BA[3:4] |
919 | 111 | Vector | `CR12-CR124`/16 | BA[0:2] 1 | 0b100 | BA[3:4] |
920
921 For a 3-bit operand (e.g. BFA):
922
923 | Value | Mode | Range/Inc | 6..3 | 2..0 |
924 |-------|------|---------------|-----------| --------|
925 | 000 | Scalar | `CR0-CR7`/1 | 0b0000 | BFA |
926 | 001 | Scalar | `CR8-CR15`/1 | 0b0001 | BFA |
927 | 010 | Scalar | `CR16-CR23`/1 | 0b0010 | BFA |
928 | 011 | Scalar | `CR24-CR31`/1 | 0b0011 | BFA |
929 | 100 | Vector | `CR0-CR112`/16 | BFA 0 | 0b000 |
930 | 101 | Vector | `CR4-CR116`/16 | BFA 0 | 0b100 |
931 | 110 | Vector | `CR8-CR120`/16 | BFA 1 | 0b000 |
932 | 111 | Vector | `CR12-CR124`/16 | BFA 1 | 0b100 |
933
934 ### CR EXTRA2
935
936 CR encoding is essentially the same but made more complex due to CRs
937 being bit-based, because the application of SVP64 element-numbering applies
938 to the CR *Field* numbering not the CR register *bit* numbering.
939 See separate section for explanation and pseudocode.
940 Note that Vectors may only start from CR0, CR8, CR16, CR24, CR32...
941
942 Encoding shown MSB down to LSB
943
944 For a 5-bit operand (BA, BB, BC):
945
946 | Value | Mode | Range/Inc | 8..5 | 4..2 | 1..0 |
947 |-------|--------|----------------|---------|---------|---------|
948 | 00 | Scalar | `CR0-CR7`/1 | 0b0000 | BA[0:2] | BA[3:4] |
949 | 01 | Scalar | `CR8-CR15`/1 | 0b0001 | BA[0:2] | BA[3:4] |
950 | 10 | Vector | `CR0-CR112`/16 | BA[0:2] 0 | 0b000 | BA[3:4] |
951 | 11 | Vector | `CR8-CR120`/16 | BA[0:2] 1 | 0b000 | BA[3:4] |
952
953 For a 3-bit operand (e.g. BFA):
954
955 | Value | Mode | Range/Inc | 6..3 | 2..0 |
956 |-------|------|---------------|-----------| --------|
957 | 00 | Scalar | `CR0-CR7`/1 | 0b0000 | BFA |
958 | 01 | Scalar | `CR8-CR15`/1 | 0b0001 | BFA |
959 | 10 | Vector | `CR0-CR112`/16 | BFA 0 | 0b000 |
960 | 11 | Vector | `CR8-CR120`/16 | BFA 1 | 0b000 |
961
962 --------
963
964 \newpage{}
965
966
967 # Normal SVP64 Modes, for Arithmetic and Logical Operations
968
969 Normal SVP64 Mode covers Arithmetic and Logical operations
970 to provide suitable additional behaviour. The Mode
971 field is bits 19-23 of the [[svp64]] RM Field.
972
973 ## Mode
974
975 Mode is an augmentation of SV behaviour, providing additional
976 functionality. Some of these alterations are element-based (saturation),
977 others involve post-analysis (predicate result) and others are
978 Vector-based (mapreduce, fail-on-first).
979
980 [[sv/ldst]], [[sv/cr_ops]] and [[sv/branches]] are covered separately:
981 the following Modes apply to Arithmetic and Logical SVP64 operations:
982
983 * **simple** mode is straight vectorisation. no augmentations: the
984 vector comprises an array of independently created results.
985 * **ffirst** or data-dependent fail-on-first: see separate section.
986 the vector may be truncated depending on certain criteria.
987 *VL is altered as a result*.
988 * **sat mode** or saturation: clamps each element result to a min/max
989 rather than overflows / wraps. allows signed and unsigned clamping
990 for both INT and FP.
991 * **reduce mode**. if used correctly, a mapreduce (or a prefix sum)
992 is performed. see [[svp64/appendix]].
993 note that there are comprehensive caveats when using this mode.
994 * **pred-result** will test the result (CR testing selects a bit of CR
995 and inverts it, just like branch conditional testing) and if the
996 test fails it is as if the *destination* predicate bit was zero even
997 before starting the operation. When Rc=1 the CR element however is
998 still stored in the CR regfile, even if the test failed. See appendix
999 for details.
1000
1001 Note that ffirst and reduce modes are not anticipated to be
1002 high-performance in some implementations. ffirst due to interactions
1003 with VL, and reduce due to it requiring additional operations to produce
1004 a result. simple, saturate and pred-result are however inter-element
1005 independent and may easily be parallelised to give high performance,
1006 regardless of the value of VL.
1007
1008 The Mode table for Arithmetic and Logical operations is laid out as
1009 follows:
1010
1011 | 0-1 | 2 | 3 4 | description |
1012 | --- | --- |---------|-------------------------- |
1013 | 00 | 0 | dz sz | simple mode |
1014 | 00 | 1 | 0 RG | scalar reduce mode (mapreduce) |
1015 | 00 | 1 | 1 / | reserved |
1016 | 01 | inv | CR-bit | Rc=1: ffirst CR sel |
1017 | 01 | inv | VLi RC1 | Rc=0: ffirst z/nonz |
1018 | 10 | N | dz sz | sat mode: N=0/1 u/s |
1019 | 11 | inv | CR-bit | Rc=1: pred-result CR sel |
1020 | 11 | inv | zz RC1 | Rc=0: pred-result z/nonz |
1021
1022 Fields:
1023
1024 * **sz / dz** if predication is enabled will put zeros into the dest
1025 (or as src in the case of twin pred) when the predicate bit is zero.
1026 otherwise the element is ignored or skipped, depending on context.
1027 * **zz**: both sz and dz are set equal to this flag
1028 * **inv CR bit** just as in branches (BO) these bits allow testing of
1029 a CR bit and whether it is set (inv=0) or unset (inv=1)
1030 * **RG** inverts the Vector Loop order (VL-1 downto 0) rather
1031 than the normal 0..VL-1
1032 * **N** sets signed/unsigned saturation.
1033 * **RC1** as if Rc=1, enables access to `VLi`.
1034 * **VLi** VL inclusive: in fail-first mode, the truncation of
1035 VL *includes* the current element at the failure point rather
1036 than excludes it from the count.
1037
1038 For LD/ST Modes, see [[sv/ldst]]. For Condition Registers see
1039 [[sv/cr_ops]]. For Branch modes, see [[sv/branches]].
1040
1041 ## Rounding, clamp and saturate
1042
1043 To help ensure for example that audio quality is not compromised by
1044 overflow, "saturation" is provided, as well as a way to detect when
1045 saturation occurred if desired (Rc=1). When Rc=1 there will be a *vector*
1046 of CRs, one CR per element in the result (Note: this is different from
1047 VSX which has a single CR per block).
1048
1049 When N=0 the result is saturated to within the maximum range of an
1050 unsigned value. For integer ops this will be 0 to 2^elwidth-1. Similar
1051 logic applies to FP operations, with the result being saturated to
1052 maximum rather than returning INF, and the minimum to +0.0
1053
1054 When N=1 the same occurs except that the result is saturated to the min
1055 or max of a signed result, and for FP to the min and max value rather
1056 than returning +/- INF.
1057
1058 When Rc=1, the CR "overflow" bit is set on the CR associated with
1059 the element, to indicate whether saturation occurred. Note that
1060 due to the hugely detrimental effect it has on parallel processing,
1061 XER.SO is **ignored** completely and is **not** brought into play here.
1062 The CR overflow bit is therefore simply set to zero if saturation did
1063 not occur, and to one if it did. This behaviour (ignoring XER.SO) is
1064 actually optional in the SFFS Compliancy Subset: for SVP64 it is made
1065 mandatory *but only on Vectorised instructions*.
1066
1067 Note also that saturate on operations that set OE=1 must raise an Illegal
1068 Instruction due to the conflicting use of the CR.so bit for storing
1069 if saturation occurred. Vectorised Integer Operations that produce a
1070 Carry-Out (CA, CA32): these two bits will be `UNDEFINED` if saturation
1071 is also requested.
1072
1073 Note that the operation takes place at the maximum bitwidth (max of
1074 src and dest elwidth) and that truncation occurs to the range of the
1075 dest elwidth.
1076
1077 *Programmer's Note: Post-analysis of the Vector of CRs to find out if any
1078 given element hit saturation may be done using a mapreduced CR op (cror),
1079 or by using the new crrweird instruction with Rc=1, which will transfer
1080 the required CR bits to a scalar integer and update CR0, which will allow
1081 testing the scalar integer for nonzero. see [[sv/cr_int_predication]].
1082 Alternatively, a Data-Dependent Fail-First may be used to truncate the
1083 Vector Length to non-saturated elements, greatly increasing the productivity
1084 of parallelised inner hot-loops.*
1085
1086 ## Reduce mode
1087
1088 Reduction in SVP64 is similar in essence to other Vector Processing ISAs,
1089 but leverages the underlying scalar Base v3.0B operations. Thus it is
1090 more a convention that the programmer may utilise to give the appearance
1091 and effect of a Horizontal Vector Reduction. Due to the unusual decoupling
1092 it is also possible to perform prefix-sum (Fibonacci Series) in certain
1093 circumstances. Details are in the SVP64 appendix
1094
1095 Reduce Mode should not be confused with Parallel Reduction [[sv/remap]].
1096 As explained in the [[sv/appendix]] Reduce Mode switches off the check
1097 which would normally stop looping if the result register is scalar.
1098 Thus, the result scalar register, if also used as a source scalar,
1099 may be used to perform sequential accumulation. This *deliberately*
1100 sets up a chain of Register Hazard Dependencies, whereas Parallel Reduce
1101 [[sv/remap]] deliberately issues a Tree-Schedule of operations that may
1102 be parallelised.
1103
1104 ## Data-dependent Fail-on-first
1105
1106 Data-dependent fail-on-first is very different from LD/ST Fail-First
1107 (also known as Fault-First) and is actually CR-field-driven.
1108 Vector elements are required to appear
1109 to be executed in sequential Program Order. When REMAP is not active,
1110 element 0 would be the first.
1111
1112 Data-driven (CR-driven) fail-on-first activates when Rc=1 or other
1113 CR-creating operation produces a result (including cmp). Similar to
1114 branch, an analysis of the CR is performed and if the test fails, the
1115 vector operation terminates and discards all element operations **at and
1116 above the current one**, and VL is truncated to either the *previous*
1117 element or the current one, depending on whether VLi (VL "inclusive")
1118 is clear or set, respectively.
1119
1120 Thus the new VL comprises a contiguous vector of results, all of which
1121 pass the testing criteria (equal to zero, less than zero etc as defined
1122 by the CR-bit test).
1123
1124 *Note: when VLi is clear, the behaviour at first seems counter-intuitive.
1125 A result is calculated but if the test fails it is prohibited from being
1126 actually written. This becomes intuitive again when it is remembered
1127 that the length that VL is set to is the number of *written* elements, and
1128 only when VLI is set will the current element be included in that count.*
1129
1130 The CR-based data-driven fail-on-first is "new" and not found in ARM SVE
1131 or RVV. At the same time it is "old" because it is almost identical to
1132 a generalised form of Z80's `CPIR` instruction. It is extremely useful
1133 for reducing instruction count, however requires speculative execution
1134 involving modifications of VL to get high performance implementations.
1135 An additional mode (RC1=1) effectively turns what would otherwise be an
1136 arithmetic operation into a type of `cmp`. The CR is stored (and the
1137 CR.eq bit tested against the `inv` field). If the CR.eq bit is equal to
1138 `inv` then the Vector is truncated and the loop ends.
1139
1140 VLi is only available as an option when `Rc=0` (or for instructions
1141 which do not have Rc). When set, the current element is always also
1142 included in the count (the new length that VL will be set to). This may
1143 be useful in combination with "inv" to truncate the Vector to *exclude*
1144 elements that fail a test, or, in the case of implementations of strncpy,
1145 to include the terminating zero.
1146
1147 In CR-based data-driven fail-on-first there is only the option to select
1148 and test one bit of each CR (just as with branch BO). For more complex
1149 tests this may be insufficient. If that is the case, a vectorised crop
1150 such as crand, cror or [[sv/cr_int_predication]] crweirder may be used,
1151 and ffirst applied to the crop instead of to the arithmetic vector. Note
1152 that crops are covered by the [[sv/cr_ops]] Mode format.
1153
1154 Use of Fail-on-first with Vertical-First Mode is not prohibited but is
1155 not really recommended. The effect of truncating VL
1156 may have unintended and unexpected consequences on subsequent instructions.
1157 VLi set will be fine: it is when VLi is clear that problems may be faced.
1158
1159 *Programmer's note: `VLi` is only accessible in normal operations which in
1160 turn limits the CR field bit-testing to only `EQ/NE`. [[sv/cr_ops]] are
1161 not so limited. Thus it is possible to use for example `sv.cror/ff=gt/vli
1162 *0,*0,*0`, which is not a `nop` because it allows Fail-First Mode to
1163 perform a test and truncate VL.*
1164
1165 *Hardware implementor's note: effective Sequential Program Order must
1166 be preserved. Speculative Execution is perfectly permitted as long as
1167 the speculative elements are held back from writing to register files
1168 (kept in Resevation Stations), until such time as the relevant CR Field
1169 bit(s) has been analysed. All Speculative elements sequentially beyond
1170 the test-failure point **MUST** be cancelled. This is no different from
1171 standard Out-of-Order Execution and the modification effort to efficiently
1172 support Data-Dependent Fail-First within a pre-existing Multi-Issue
1173 Out-of-Order Engine is anticipated to be minimal. In-Order systems on
1174 the other hand are expected, unavoidably, to be low-performance*.
1175
1176 Two extremely important aspects of ffirst are:
1177
1178 * LDST ffirst may never set VL equal to zero. This because on the first
1179 element an exception must be raised "as normal".
1180 * CR-based data-dependent ffirst on the other hand **can** set VL equal
1181 to zero. This is the only means in the entirety of SV that VL may be set
1182 to zero (with the exception of via the SV.STATE SPR). When VL is set
1183 zero due to the first element failing the CR bit-test, all subsequent
1184 vectorised operations are effectively `nops` which is
1185 *precisely the desired and intended behaviour*.
1186
1187 The second crucial aspect, compared to LDST Ffirst:
1188
1189 * LD/ST Failfirst may (beyond the initial first element
1190 conditions) truncate VL for any architecturally suitable reason. Beyond
1191 the first element LD/ST Failfirst is arbitrarily speculative and 100%
1192 non-deterministic.
1193 * CR-based data-dependent first on the other hand MUST NOT truncate VL
1194 arbitrarily to a length decided by the hardware: VL MUST only be
1195 truncated based explicitly on whether a test fails. This because it is
1196 a precise Deterministic test on which algorithms can and will will rely.
1197
1198 **Floating-point Exceptions**
1199
1200 When Floating-point exceptions are enabled VL must be truncated at
1201 the point where the Exception appears not to have occurred. If `VLi`
1202 is set then VL must include the faulting element, and thus the faulting
1203 element will always raise its exception. If however `VLi` is clear then
1204 VL **excludes** the faulting element and thus the exception will **never**
1205 be raised.
1206
1207 Although very strongly discouraged the Exception Mode that permits
1208 Floating Point Exception notification to arrive too late to unwind
1209 is permitted (under protest, due it violating the otherwise 100%
1210 Deterministic nature of Data-dependent Fail-first) and is `UNDEFINED`
1211 behaviour.
1212
1213 **Use of lax FP Exception Notification Mode could result in parallel
1214 computations proceeding with invalid results that have to be explicitly
1215 detected, whereas with the strict FP Execption Mode enabled, FFirst
1216 truncates VL, allows subsequent parallel computation to avoid the
1217 exceptions entirely**
1218
1219 ## Data-dependent fail-first on CR operations (crand etc)
1220
1221 Operations that actually produce or alter CR Field as a result have
1222 their own SVP64 Mode, described in [[sv/cr_ops]].
1223
1224 ## pred-result mode
1225
1226 This mode merges common CR testing with predication, saving on instruction
1227 count. Below is the pseudocode excluding predicate zeroing and elwidth
1228 overrides. Note that the pseudocode for SVP64 CR-ops is slightly different.
1229
1230 ```
1231 for i in range(VL):
1232 # predication test, skip all masked out elements.
1233 if predicate_masked_out(i):
1234 continue
1235 result = op(iregs[RA+i], iregs[RB+i])
1236 CRnew = analyse(result) # calculates eq/lt/gt
1237 # Rc=1 always stores the CR field
1238 if Rc=1 or RC1:
1239 CR.field[offs+i] = CRnew
1240 # now test CR, similar to branch
1241 if RC1 or CR.field[BO[0:1]] != BO[2]:
1242 continue # test failed: cancel store
1243 # result optionally stored but CR always is
1244 iregs[RT+i] = result
1245 ```
1246
1247 The reason for allowing the CR element to be stored is so that
1248 post-analysis of the CR Vector may be carried out. For example:
1249 Saturation may have occurred (and been prevented from updating, by the
1250 test) but it is desirable to know *which* elements fail saturation.
1251
1252 Note that RC1 Mode basically turns all operations into `cmp`. The
1253 calculation is performed but it is only the CR that is written. The
1254 element result is *always* discarded, never written (just like `cmp`).
1255
1256 Note that predication is still respected: predicate zeroing is slightly
1257 different: elements that fail the CR test *or* are masked out are zero'd.
1258
1259 --------
1260
1261 \newpage{}
1262
1263 # SV Load and Store
1264
1265 **Rationale**
1266
1267 All Vector ISAs dating back fifty years have extensive and comprehensive
1268 Load and Store operations that go far beyond the capabilities of Scalar
1269 RISC and most CISC processors, yet at their heart on an individual element
1270 basis may be found to be no different from RISC Scalar equivalents.
1271
1272 The resource savings from Vector LD/ST are significant and stem
1273 from the fact that one single instruction can trigger a dozen (or in
1274 some microarchitectures such as Cray or NEC SX Aurora) hundreds of
1275 element-level Memory accesses.
1276
1277 Additionally, and simply: if the Arithmetic side of an ISA supports
1278 Vector Operations, then in order to keep the ALUs 100% occupied the
1279 Memory infrastructure (and the ISA itself) correspondingly needs Vector
1280 Memory Operations as well.
1281
1282 Vectorised Load and Store also presents an extra dimension (literally)
1283 which creates scenarios unique to Vector applications, that a Scalar (and
1284 even a SIMD) ISA simply never encounters. SVP64 endeavours to add the
1285 modes typically found in *all* Scalable Vector ISAs, without changing the
1286 behaviour of the underlying Base (Scalar) v3.0B operations in any way.
1287 (The sole apparent exception is Post-Increment Mode on LD/ST-update
1288 instructions)
1289
1290 ## Modes overview
1291
1292 Vectorisation of Load and Store requires creation, from scalar operations,
1293 a number of different modes:
1294
1295 * **fixed aka "unit" stride** - contiguous sequence with no gaps
1296 * **element strided** - sequential but regularly offset, with gaps
1297 * **vector indexed** - vector of base addresses and vector of offsets
1298 * **Speculative fail-first** - where it makes sense to do so
1299 * **Structure Packing** - covered in SV by [[sv/remap]] and Pack/Unpack Mode.
1300
1301 *Despite being constructed from Scalar LD/ST none of these Modes exist
1302 or make sense in any Scalar ISA. They **only** exist in Vector ISAs*
1303
1304 Also included in SVP64 LD/ST is both signed and unsigned Saturation,
1305 as well as Element-width overrides and Twin-Predication.
1306
1307 Note also that Indexed [[sv/remap]] mode may be applied to both v3.0
1308 LD/ST Immediate instructions *and* v3.0 LD/ST Indexed instructions.
1309 LD/ST-Indexed should not be conflated with Indexed REMAP mode:
1310 clarification is provided below.
1311
1312 **Determining the LD/ST Modes**
1313
1314 A minor complication (caused by the retro-fitting of modern Vector
1315 features to a Scalar ISA) is that certain features do not exactly make
1316 sense or are considered a security risk. Fail-first on Vector Indexed
1317 would allow attackers to probe large numbers of pages from userspace,
1318 where strided fail-first (by creating contiguous sequential LDs) does not.
1319
1320 In addition, reduce mode makes no sense. Realistically we need an
1321 alternative table definition for [[sv/svp64]] `RM.MODE`. The following
1322 modes make sense:
1323
1324 * saturation
1325 * predicate-result (mostly for cache-inhibited LD/ST)
1326 * simple (no augmentation)
1327 * fail-first (where Vector Indexed is banned)
1328 * Signed Effective Address computation (Vector Indexed only)
1329
1330 More than that however it is necessary to fit the usual Vector ISA
1331 capabilities onto both Power ISA LD/ST with immediate and to LD/ST
1332 Indexed. They present subtly different Mode tables, which, due to lack
1333 of space, have the following quirks:
1334
1335 * LD/ST Immediate has no individual control over src/dest zeroing,
1336 whereas LD/ST Indexed does.
1337 * LD/ST Indexed has limited zeroing on pred-result, LD/ST Immediate has
1338 *no* option to select zeroing on pred-result.
1339
1340 ## Format and fields
1341
1342 Fields used in tables below:
1343
1344 * **sz / dz** if predication is enabled will put zeros into the dest
1345 (or as src in the case of twin pred) when the predicate bit is zero.
1346 otherwise the element is ignored or skipped, depending on context.
1347 * **zz**: both sz and dz are set equal to this flag.
1348 * **inv CR bit** just as in branches (BO) these bits allow testing of
1349 a CR bit and whether it is set (inv=0) or unset (inv=1)
1350 * **N** sets signed/unsigned saturation.
1351 * **RC1** as if Rc=1, stores CRs *but not the result*
1352 * **SEA** - Signed Effective Address, if enabled performs sign-extension on
1353 registers that have been reduced due to elwidth overrides
1354 * **PI** - post-increment mode (applies to LD/ST with update only).
1355 the Effective Address utilised is always just RA, i.e. the computation of
1356 EA is stored in RA **after** it is actually used.
1357 * **LF** - Load/Store Fail or Fault First: for any reason Load or Store Vectors
1358 may be truncated to (at least) one element, and VL altered to indicate such.
1359
1360 **LD/ST immediate**
1361
1362 The table for [[sv/svp64]] for `immed(RA)` which is `RM.MODE`
1363 (bits 19:23 of `RM`) is:
1364
1365 | 0-1 | 2 | 3 4 | description |
1366 | --- | --- |---------|--------------------------- |
1367 | 00 | 0 | zz els | simple mode |
1368 | 00 | 1 | PI LF | post-increment and Fault-First |
1369 | 01 | inv | CR-bit | Rc=1: ffirst CR sel |
1370 | 01 | inv | els RC1 | Rc=0: ffirst z/nonz |
1371 | 10 | N | zz els | sat mode: N=0/1 u/s |
1372 | 11 | inv | CR-bit | Rc=1: pred-result CR sel |
1373 | 11 | inv | els RC1 | Rc=0: pred-result z/nonz |
1374
1375 The `els` bit is only relevant when `RA.isvec` is clear: this indicates
1376 whether stride is unit or element:
1377
1378 ```
1379 if RA.isvec:
1380 svctx.ldstmode = indexed
1381 elif els == 0:
1382 svctx.ldstmode = unitstride
1383 elif immediate != 0:
1384 svctx.ldstmode = elementstride
1385 ```
1386
1387 An immediate of zero is a safety-valve to allow `LD-VSPLAT`: in effect
1388 the multiplication of the immediate-offset by zero results in reading from
1389 the exact same memory location, *even with a Vector register*. (Normally
1390 this type of behaviour is reserved for the mapreduce modes)
1391
1392 For `LD-VSPLAT`, on non-cache-inhibited Loads, the read can occur just
1393 the once and be copied, rather than hitting the Data Cache multiple
1394 times with the same memory read at the same location. The benefit of
1395 Cache-inhibited LD-splats is that it allows for memory-mapped peripherals
1396 to have multiple data values read in quick succession and stored in
1397 sequentially numbered registers (but, see Note below).
1398
1399 For non-cache-inhibited ST from a vector source onto a scalar destination:
1400 with the Vector loop effectively creating multiple memory writes to
1401 the same location, we can deduce that the last of these will be the
1402 "successful" one. Thus, implementations are free and clear to optimise
1403 out the overwriting STs, leaving just the last one as the "winner".
1404 Bear in mind that predicate masks will skip some elements (in source
1405 non-zeroing mode). Cache-inhibited ST operations on the other hand
1406 **MUST** write out a Vector source multiple successive times to the exact
1407 same Scalar destination. Just like Cache-inhibited LDs, multiple values
1408 may be written out in quick succession to a memory-mapped peripheral
1409 from sequentially-numbered registers.
1410
1411 Note that any memory location may be Cache-inhibited
1412 (Power ISA v3.1, Book III, 1.6.1, p1033)
1413
1414 *Programmer's Note: an immediate also with a Scalar source as a "VSPLAT"
1415 mode is simply not possible: there are not enough Mode bits. One single
1416 Scalar Load operation may be used instead, followed by any arithmetic
1417 operation (including a simple mv) in "Splat" mode.*
1418
1419 **LD/ST Indexed**
1420
1421 The modes for `RA+RB` indexed version are slightly different
1422 but are the same `RM.MODE` bits (19:23 of `RM`):
1423
1424 | 0-1 | 2 | 3 4 | description |
1425 | --- | --- |---------|-------------------------- |
1426 | 00 | SEA | dz sz | simple mode |
1427 | 01 | SEA | dz sz | Strided (scalar only source) |
1428 | 10 | N | dz sz | sat mode: N=0/1 u/s |
1429 | 11 | inv | CR-bit | Rc=1: pred-result CR sel |
1430 | 11 | inv | zz RC1 | Rc=0: pred-result z/nonz |
1431
1432 Vector Indexed Strided Mode is qualified as follows:
1433
1434 if mode = 0b01 and !RA.isvec and !RB.isvec:
1435 svctx.ldstmode = elementstride
1436
1437 A summary of the effect of Vectorisation of src or dest:
1438
1439 ```
1440 imm(RA) RT.v RA.v no stride allowed
1441 imm(RA) RT.s RA.v no stride allowed
1442 imm(RA) RT.v RA.s stride-select allowed
1443 imm(RA) RT.s RA.s not vectorised
1444 RA,RB RT.v {RA|RB}.v Standard Indexed
1445 RA,RB RT.s {RA|RB}.v Indexed but single LD (no VSPLAT)
1446 RA,RB RT.v {RA&RB}.s VSPLAT possible. stride selectable
1447 RA,RB RT.s {RA&RB}.s not vectorised (scalar identity)
1448 ```
1449
1450 Signed Effective Address computation is only relevant for Vector Indexed
1451 Mode, when elwidth overrides are applied. The source override applies to
1452 RB, and before adding to RA in order to calculate the Effective Address,
1453 if SEA is set RB is sign-extended from elwidth bits to the full 64 bits.
1454 For other Modes (ffirst, saturate), all EA computation with elwidth
1455 overrides is unsigned.
1456
1457 Note that cache-inhibited LD/ST when VSPLAT is activated will perform
1458 **multiple** LD/ST operations, sequentially. Even with scalar src
1459 a Cache-inhibited LD will read the same memory location *multiple
1460 times*, storing the result in successive Vector destination registers.
1461 This because the cache-inhibit instructions are typically used to read
1462 and write memory-mapped peripherals. If a genuine cache-inhibited
1463 LD-VSPLAT is required then a single *scalar* cache-inhibited LD should
1464 be performed, followed by a VSPLAT-augmented mv, copying the one *scalar*
1465 value into multiple register destinations.
1466
1467 Note also that cache-inhibited VSPLAT with Predicate-result is possible.
1468 This allows for example to issue a massive batch of memory-mapped
1469 peripheral reads, stopping at the first NULL-terminated character and
1470 truncating VL to that point. No branch is needed to issue that large
1471 burst of LDs, which may be valuable in Embedded scenarios.
1472
1473 ## Vectorisation of Scalar Power ISA v3.0B
1474
1475 Scalar Power ISA Load/Store operations may be seen from their
1476 pseudocode to be of the form:
1477
1478 ```
1479 lbux RT, RA, RB
1480 EA <- (RA) + (RB)
1481 RT <- MEM(EA)
1482 ```
1483
1484 and for immediate variants:
1485
1486 ```
1487 lb RT,D(RA)
1488 EA <- RA + EXTS(D)
1489 RT <- MEM(EA)
1490 ```
1491
1492 Thus in the first example, the source registers may each be independently
1493 marked as scalar or vector, and likewise the destination; in the second
1494 example only the one source and one dest may be marked as scalar or
1495 vector.
1496
1497 Thus we can see that Vector Indexed may be covered, and, as demonstrated
1498 with the pseudocode below, the immediate can be used to give unit
1499 stride or element stride. With there being no way to tell which from
1500 the Power v3.0B Scalar opcode alone, the choice is provided instead by
1501 the SV Context.
1502
1503 ```
1504 # LD not VLD! format - ldop RT, immed(RA)
1505 # op_width: lb=1, lh=2, lw=4, ld=8
1506 op_load(RT, RA, op_width, immed, svctx, RAupdate):
1507  ps = get_pred_val(FALSE, RA); # predication on src
1508  pd = get_pred_val(FALSE, RT); # ... AND on dest
1509  for (i=0, j=0, u=0; i < VL && j < VL;):
1510 # skip nonpredicates elements
1511 if (RA.isvec) while (!(ps & 1<<i)) i++;
1512 if (RAupdate.isvec) while (!(ps & 1<<u)) u++;
1513 if (RT.isvec) while (!(pd & 1<<j)) j++;
1514 if postinc:
1515 offs = 0; # added afterwards
1516 if RA.isvec: srcbase = ireg[RA+i]
1517 else srcbase = ireg[RA]
1518 elif svctx.ldstmode == elementstride:
1519 # element stride mode
1520 srcbase = ireg[RA]
1521 offs = i * immed # j*immed for a ST
1522 elif svctx.ldstmode == unitstride:
1523 # unit stride mode
1524 srcbase = ireg[RA]
1525 offs = immed + (i * op_width) # j*op_width for ST
1526 elif RA.isvec:
1527 # quirky Vector indexed mode but with an immediate
1528 srcbase = ireg[RA+i]
1529 offs = immed;
1530 else
1531 # standard scalar mode (but predicated)
1532 # no stride multiplier means VSPLAT mode
1533 srcbase = ireg[RA]
1534 offs = immed
1535
1536 # compute EA
1537 EA = srcbase + offs
1538 # load from memory
1539 ireg[RT+j] <= MEM[EA];
1540 # check post-increment of EA
1541 if postinc: EA = srcbase + immed;
1542 # update RA?
1543 if RAupdate: ireg[RAupdate+u] = EA;
1544 if (!RT.isvec)
1545 break # destination scalar, end now
1546 if (RA.isvec) i++;
1547 if (RAupdate.isvec) u++;
1548 if (RT.isvec) j++;
1549 ```
1550
1551 Indexed LD is:
1552
1553 ```
1554 # format: ldop RT, RA, RB
1555 function op_ldx(RT, RA, RB, RAupdate=False) # LD not VLD!
1556  ps = get_pred_val(FALSE, RA); # predication on src
1557  pd = get_pred_val(FALSE, RT); # ... AND on dest
1558  for (i=0, j=0, k=0, u=0; i < VL && j < VL && k < VL):
1559 # skip nonpredicated RA, RB and RT
1560 if (RA.isvec) while (!(ps & 1<<i)) i++;
1561 if (RAupdate.isvec) while (!(ps & 1<<u)) u++;
1562 if (RB.isvec) while (!(ps & 1<<k)) k++;
1563 if (RT.isvec) while (!(pd & 1<<j)) j++;
1564 if svctx.ldstmode == elementstride:
1565 EA = ireg[RA] + ireg[RB]*j # register-strided
1566 else
1567 EA = ireg[RA+i] + ireg[RB+k] # indexed address
1568 if RAupdate: ireg[RAupdate+u] = EA
1569 ireg[RT+j] <= MEM[EA];
1570 if (!RT.isvec)
1571 break # destination scalar, end immediately
1572 if (RA.isvec) i++;
1573 if (RAupdate.isvec) u++;
1574 if (RB.isvec) k++;
1575 if (RT.isvec) j++;
1576 ```
1577
1578 Note that Element-Strided uses the Destination Step because with both
1579 sources being Scalar as a prerequisite condition of activation of
1580 Element-Stride Mode, the source step (being Scalar) would never advance.
1581
1582 Note in both cases that [[sv/svp64]] allows RA-as-a-dest in "update"
1583 mode (`ldux`) to be effectively a *completely different* register from
1584 RA-as-a-source. This because there is room in svp64 to extend RA-as-src
1585 as well as RA-as-dest, both independently as scalar or vector *and*
1586 independently extending their range.
1587
1588 *Programmer's note: being able to set RA-as-a-source as separate from
1589 RA-as-a-destination as Scalar is **extremely valuable** once it is
1590 remembered that Simple-V element operations must be in Program Order,
1591 especially in loops, for saving on multiple address computations. Care
1592 does have to be taken however that RA-as-src is not overwritten by
1593 RA-as-dest unless intentionally desired, especially in element-strided
1594 Mode.*
1595
1596 ## LD/ST Indexed vs Indexed REMAP
1597
1598 Unfortunately the word "Indexed" is used twice in completely different
1599 contexts, potentially causing confusion.
1600
1601 * There has existed instructions in the Power ISA `ld RT,RA,RB` since
1602 its creation: these are called "LD/ST Indexed" instructions and their
1603 name and meaning is well-established.
1604 * There now exists, in Simple-V, a REMAP mode called "Indexed"
1605 Mode that can be applied to *any* instruction **including those
1606 named LD/ST Indexed**.
1607
1608 Whilst it may be costly in terms of register reads to allow REMAP Indexed
1609 Mode to be applied to any Vectorised LD/ST Indexed operation such as
1610 `sv.ld *RT,RA,*RB`, or even misleadingly labelled as redundant, firstly
1611 the strict application of the RISC Paradigm that Simple-V follows makes
1612 it awkward to consider *preventing* the application of Indexed REMAP to
1613 such operations, and secondly they are not actually the same at all.
1614
1615 Indexed REMAP, as applied to RB in the instruction `sv.ld *RT,RA,*RB`
1616 effectively performs an *in-place* re-ordering of the offsets, RB.
1617 To achieve the same effect without Indexed REMAP would require taking
1618 a *copy* of the Vector of offsets starting at RB, manually explicitly
1619 reordering them, and finally using the copy of re-ordered offsets in a
1620 non-REMAP'ed `sv.ld`. Using non-strided LD as an example, pseudocode
1621 showing what actually occurs, where the pseudocode for `indexed_remap`
1622 may be found in [[sv/remap]]:
1623
1624 ```
1625 # sv.ld *RT,RA,*RB with Index REMAP applied to RB
1626 for i in 0..VL-1:
1627 if remap.indexed:
1628 rb_idx = indexed_remap(i) # remap
1629 else:
1630 rb_idx = i # use the index as-is
1631 EA = GPR(RA) + GPR(RB+rb_idx)
1632 GPR(RT+i) = MEM(EA, 8)
1633 ```
1634
1635 Thus it can be seen that the use of Indexed REMAP saves copying
1636 and manual reordering of the Vector of RB offsets.
1637
1638 ## LD/ST ffirst
1639
1640 LD/ST ffirst treats the first LD/ST in a vector (element 0 if REMAP
1641 is not active) as an ordinary one, with all behaviour with respect to
1642 Interrupts Exceptions Page Faults Memory Management being identical
1643 in every regard to Scalar v3.0 Power ISA LD/ST. However for elements
1644 1 and above, if an exception would occur, then VL is **truncated**
1645 to the previous element: the exception is **not** then raised because
1646 the LD/ST that would otherwise have caused an exception is *required*
1647 to be cancelled. Additionally an implementor may choose to truncate VL
1648 for any arbitrary reason *except for the very first*.
1649
1650 ffirst LD/ST to multiple pages via a Vectorised Index base is
1651 considered a security risk due to the abuse of probing multiple
1652 pages in rapid succession and getting speculative feedback on which
1653 pages would fail. Therefore Vector Indexed LD/ST is prohibited
1654 entirely, and the Mode bit instead used for element-strided LD/ST.
1655
1656 ```
1657 for(i = 0; i < VL; i++)
1658 reg[rt + i] = mem[reg[ra] + i * reg[rb]];
1659 ```
1660
1661 High security implementations where any kind of speculative probing of
1662 memory pages is considered a risk should take advantage of the fact
1663 that implementations may truncate VL at any point, without requiring
1664 software to be rewritten and made non-portable. Such implementations may
1665 choose to *always* set VL=1 which will have the effect of terminating
1666 any speculative probing (and also adversely affect performance), but
1667 will at least not require applications to be rewritten.
1668
1669 Low-performance simpler hardware implementations may also choose (always)
1670 to also set VL=1 as the bare minimum compliant implementation of LD/ST
1671 Fail-First. It is however critically important to remember that the first
1672 element LD/ST **MUST** be treated as an ordinary LD/ST, i.e. **MUST**
1673 raise exceptions exactly like an ordinary LD/ST.
1674
1675 For ffirst LD/STs, VL may be truncated arbitrarily to a nonzero value
1676 for any implementation-specific reason. For example: it is perfectly
1677 reasonable for implementations to alter VL when ffirst LD or ST operations
1678 are initiated on a nonaligned boundary, such that within a loop the
1679 subsequent iteration of that loop begins the following ffirst LD/ST
1680 operations on an aligned boundary such as the beginning of a cache line,
1681 or beginning of a Virtual Memory page. Likewise, to reduce workloads or
1682 balance resources.
1683
1684 Vertical-First Mode is slightly strange in that only one element at a time
1685 is ever executed anyway. Given that programmers may legitimately choose
1686 to alter srcstep and dststep in non-sequential order as part of explicit
1687 loops, it is neither possible nor safe to make speculative assumptions
1688 about future LD/STs. Therefore, Fail-First LD/ST in Vertical-First is
1689 `UNDEFINED`. This is very different from Arithmetic (Data-dependent)
1690 FFirst where Vertical-First Mode is fully deterministic, not speculative.
1691
1692 ## LOAD/STORE Elwidths <a name="elwidth"></a>
1693
1694 Loads and Stores are almost unique in that the Power Scalar ISA
1695 provides a width for the operation (lb, lh, lw, ld). Only `extsb` and
1696 others like it provide an explicit operation width. There are therefore
1697 *three* widths involved:
1698
1699 * operation width (lb=8, lh=16, lw=32, ld=64)
1700 * src element width override (8/16/32/default)
1701 * destination element width override (8/16/32/default)
1702
1703 Some care is therefore needed to express and make clear the transformations,
1704 which are expressly in this order:
1705
1706 * Calculate the Effective Address from RA at full width
1707 but (on Indexed Load) allow srcwidth overrides on RB
1708 * Load at the operation width (lb/lh/lw/ld) as usual
1709 * byte-reversal as usual
1710 * Non-saturated mode:
1711 - zero-extension or truncation from operation width to dest elwidth
1712 - place result in destination at dest elwidth
1713 * Saturated mode:
1714 - Sign-extension or truncation from operation width to dest width
1715 - signed/unsigned saturation down to dest elwidth
1716
1717 In order to respect Power v3.0B Scalar behaviour the memory side
1718 is treated effectively as completely separate and distinct from SV
1719 augmentation. This is primarily down to quirks surrounding LE/BE and
1720 byte-reversal.
1721
1722 It is rather unfortunately possible to request an elwidth override on
1723 the memory side which does not mesh with the overridden operation width:
1724 these result in `UNDEFINED` behaviour. The reason is that the effect
1725 of attempting a 64-bit `sv.ld` operation with a source elwidth override
1726 of 8/16/32 would result in overlapping memory requests, particularly
1727 on unit and element strided operations. Thus it is `UNDEFINED` when
1728 the elwidth is smaller than the memory operation width. Examples include
1729 `sv.lw/sw=16/els` which requests (overlapping) 4-byte memory reads offset
1730 from each other at 2-byte intervals. Store likewise is also `UNDEFINED`
1731 where the dest elwidth override is less than the operation width.
1732
1733 Note the following regarding the pseudocode to follow:
1734
1735 * `scalar identity behaviour` SV Context parameter conditions turn this
1736 into a straight absolute fully-compliant Scalar v3.0B LD operation
1737 * `brev` selects whether the operation is the byte-reversed variant (`ldbrx`
1738 rather than `ld`)
1739 * `op_width` specifies the operation width (`lb`, `lh`, `lw`, `ld`) as
1740 a "normal" part of Scalar v3.0B LD
1741 * `imm_offs` specifies the immediate offset `ld r3, imm_offs(r5)`, again
1742 as a "normal" part of Scalar v3.0B LD
1743 * `svctx` specifies the SV Context and includes VL as well as
1744 source and destination elwidth overrides.
1745
1746 Below is the pseudocode for Unit-Strided LD (which includes Vector
1747 capability). Observe in particular that RA, as the base address in both
1748 Immediate and Indexed LD/ST, does not have element-width overriding
1749 applied to it.
1750
1751 Note that predication, predication-zeroing, and other modes except
1752 saturation have all been removed, for clarity and simplicity:
1753
1754 ```
1755 # LD not VLD!
1756 # this covers unit stride mode and a type of vector offset
1757 function op_ld(RT, RA, op_width, imm_offs, svctx)
1758 for (int i = 0, int j = 0; i < svctx.VL && j < svctx.VL):
1759 if not svctx.unit/el-strided:
1760 # strange vector mode, compute 64 bit address which is
1761 # not polymorphic! elwidth hardcoded to 64 here
1762 srcbase = get_polymorphed_reg(RA, 64, i)
1763 else:
1764 # unit / element stride mode, compute 64 bit address
1765 srcbase = get_polymorphed_reg(RA, 64, 0)
1766 # adjust for unit/el-stride
1767 srcbase += ....
1768
1769 # read the underlying memory
1770 memread <= MEM(srcbase + imm_offs, op_width)
1771
1772 # check saturation.
1773 if svpctx.saturation_mode:
1774 # ... saturation adjustment...
1775 memread = clamp(memread, op_width, svctx.dest_elwidth)
1776 else:
1777 # truncate/extend to over-ridden dest width.
1778 memread = adjust_wid(memread, op_width, svctx.dest_elwidth)
1779
1780 # takes care of inserting memory-read (now correctly byteswapped)
1781 # into regfile underlying LE-defined order, into the right place
1782 # within the NEON-like register, respecting destination element
1783 # bitwidth, and the element index (j)
1784 set_polymorphed_reg(RT, svctx.dest_elwidth, j, memread)
1785
1786 # increments both src and dest element indices (no predication here)
1787 i++;
1788 j++;
1789 ```
1790
1791 Note above that the source elwidth is *not used at all* in LD-immediate.
1792
1793 For LD/Indexed, the key is that in the calculation of the Effective Address,
1794 RA has no elwidth override but RB does. Pseudocode below is simplified
1795 for clarity: predication and all modes except saturation are removed:
1796
1797 ```
1798 # LD not VLD! ld*rx if brev else ld*
1799 function op_ld(RT, RA, RB, op_width, svctx, brev)
1800 for (int i = 0, int j = 0; i < svctx.VL && j < svctx.VL):
1801 if not svctx.el-strided:
1802 # RA not polymorphic! elwidth hardcoded to 64 here
1803 srcbase = get_polymorphed_reg(RA, 64, i)
1804 else:
1805 # element stride mode, again RA not polymorphic
1806 srcbase = get_polymorphed_reg(RA, 64, 0)
1807 # RB *is* polymorphic
1808 offs = get_polymorphed_reg(RB, svctx.src_elwidth, i)
1809 # sign-extend
1810 if svctx.SEA: offs = sext(offs, svctx.src_elwidth, 64)
1811
1812 # takes care of (merges) processor LE/BE and ld/ldbrx
1813 bytereverse = brev XNOR MSR.LE
1814
1815 # read the underlying memory
1816 memread <= MEM(srcbase + offs, op_width)
1817
1818 # optionally performs byteswap at op width
1819 if (bytereverse):
1820 memread = byteswap(memread, op_width)
1821
1822 if svpctx.saturation_mode:
1823 # ... saturation adjustment...
1824 memread = clamp(memread, op_width, svctx.dest_elwidth)
1825 else:
1826 # truncate/extend to over-ridden dest width.
1827 memread = adjust_wid(memread, op_width, svctx.dest_elwidth)
1828
1829 # takes care of inserting memory-read (now correctly byteswapped)
1830 # into regfile underlying LE-defined order, into the right place
1831 # within the NEON-like register, respecting destination element
1832 # bitwidth, and the element index (j)
1833 set_polymorphed_reg(RT, svctx.dest_elwidth, j, memread)
1834
1835 # increments both src and dest element indices (no predication here)
1836 i++;
1837 j++;
1838 ```
1839
1840 ## Remapped LD/ST
1841
1842 In the [[sv/remap]] page the concept of "Remapping" is described. Whilst
1843 it is expensive to set up (2 64-bit opcodes minimum) it provides a way to
1844 arbitrarily perform 1D, 2D and 3D "remapping" of up to 64 elements worth
1845 of LDs or STs. The usual interest in such re-mapping is for example in
1846 separating out 24-bit RGB channel data into separate contiguous registers.
1847
1848 REMAP easily covers this capability, and with dest elwidth overrides
1849 and saturation may do so with built-in conversion that would normally
1850 require additional width-extension, sign-extension and min/max Vectorised
1851 instructions as post-processing stages.
1852
1853 Thus we do not need to provide specialist LD/ST "Structure Packed" opcodes
1854 because the generic abstracted concept of "Remapping", when applied to
1855 LD/ST, will give that same capability, with far more flexibility.
1856
1857 It is worth noting that Pack/Unpack Modes of SVSTATE, which may be
1858 established through `svstep`, are also an easy way to perform regular
1859 Structure Packing, at the vec2/vec3/vec4 granularity level. Beyond that,
1860 REMAP will need to be used.
1861
1862 --------
1863
1864 \newpage{}
1865
1866 # Condition Register SVP64 Operations
1867
1868 Condition Register Fields are only 4 bits wide: this presents some
1869 interesting conceptual challenges for SVP64, which was designed
1870 primarily for vectors of arithmetic and logical operations. However
1871 if predicates may be bits of CR Fields it makes sense to extend
1872 Simple-V to cover CR Operations, especially given that Vectorised Rc=1
1873 may be processed by Vectorised CR Operations tbat usefully in turn
1874 may become Predicate Masks to yet more Vector operations, like so:
1875
1876 ```
1877 sv.cmpi/ew=8 *B,*ra,0 # compare bytes against zero
1878 sv.cmpi/ew=8 *B2,*ra,13. # and against newline
1879 sv.cror PM.EQ,B.EQ,B2.EQ # OR compares to create mask
1880 sv.stb/sm=EQ ... # store only nonzero/newline
1881 ```
1882
1883 Element width however is clearly meaningless for a 4-bit collation of
1884 Conditions, EQ LT GE SO. Likewise, arithmetic saturation (an important
1885 part of Arithmetic SVP64) has no meaning. An alternative Mode Format is
1886 required, and given that elwidths are meaningless for CR Fields the bits
1887 in SVP64 `RM` may be used for other purposes.
1888
1889 This alternative mapping **only** applies to instructions that **only**
1890 reference a CR Field or CR bit as the sole exclusive result. This section
1891 **does not** apply to instructions which primarily produce arithmetic
1892 results that also, as an aside, produce a corresponding CR Field (such as
1893 when Rc=1). Instructions that involve Rc=1 are definitively arithmetic
1894 in nature, where the corresponding Condition Register Field can be
1895 considered to be a "co-result". Such CR Field "co-result" arithmeric
1896 operations are firmly out of scope for this section, being covered fully
1897 by [[sv/normal]].
1898
1899 * Examples of v3.0B instructions to which this section does
1900 apply is
1901 - `mfcr` and `cmpi` (3 bit operands) and
1902 - `crnor` and `crand` (5 bit operands).
1903 * Examples to which this section does **not** apply include
1904 `fadds.` and `subf.` which both produce arithmetic results
1905 (and a CR Field co-result).
1906
1907 The CR Mode Format still applies to `sv.cmpi` because despite
1908 taking a GPR as input, the output from the Base Scalar v3.0B `cmpi`
1909 instruction is purely to a Condition Register Field.
1910
1911 Other modes are still applicable and include:
1912
1913 * **Data-dependent fail-first**.
1914 useful to truncate VL based on analysis of a Condition Register result bit.
1915 * **Reduction**.
1916 Reduction is useful for analysing a Vector of Condition Register Fields
1917 and reducing it to one single Condition Register Field.
1918
1919 Predicate-result does not make any sense because when Rc=1 a co-result
1920 is created (a CR Field). Testing the co-result allows the decision to
1921 be made to store or not store the main result, and for CR Ops the CR
1922 Field result *is* the main result.
1923
1924 ## Format
1925
1926 SVP64 RM `MODE` (includes `ELWIDTH_SRC` bits) for CR-based operations:
1927
1928 |6 | 7 |19-20| 21 | 22 23 | description |
1929 |--|---|-----| --- |---------|----------------- |
1930 |/ | / |0 RG | 0 | dz sz | simple mode |
1931 |/ | / |0 RG | 1 | dz sz | scalar reduce mode (mapreduce) |
1932 |zz|SNZ|1 VLI| inv | CR-bit | Ffirst 3-bit mode |
1933 |/ |SNZ|1 VLI| inv | dz sz | Ffirst 5-bit mode (implies CR-bit from result) |
1934
1935 Fields:
1936
1937 * **sz / dz** if predication is enabled will put zeros into the dest
1938 (or as src in the case of twin pred) when the predicate bit is zero.
1939 otherwise the element is ignored or skipped, depending on context.
1940 * **zz** set both sz and dz equal to this flag
1941 * **SNZ** In fail-first mode, on the bit being tested, when sz=1 and
1942 SNZ=1 a value "1" is put in place of "0".
1943 * **inv CR-bit** just as in branches (BO) these bits allow testing of
1944 a CR bit and whether it is set (inv=0) or unset (inv=1)
1945 * **RG** inverts the Vector Loop order (VL-1 downto 0) rather
1946 than the normal 0..VL-1
1947 * **SVM** sets "subvector" reduce mode
1948 * **VLi** VL inclusive: in fail-first mode, the truncation of
1949 VL *includes* the current element at the failure point rather
1950 than excludes it from the count.
1951
1952 ## Data-dependent fail-first on CR operations
1953
1954 The principle of data-dependent fail-first is that if, during the course
1955 of sequentially evaluating an element's Condition Test, one such test
1956 is encountered which fails, then VL (Vector Length) is truncated (set)
1957 at that point. In the case of Arithmetic SVP64 Operations the Condition
1958 Register Field generated from Rc=1 is used as the basis for the truncation
1959 decision. However with CR-based operations that CR Field result to be
1960 tested is provided *by the operation itself*.
1961
1962 Data-dependent SVP64 Vectorised Operations involving the creation
1963 or modification of a CR can require an extra two bits, which are not
1964 available in the compact space of the SVP64 RM `MODE` Field. With the
1965 concept of element width overrides being meaningless for CR Fields it
1966 is possible to use the `ELWIDTH` field for alternative purposes.
1967
1968 Condition Register based operations such as `sv.mfcr` and `sv.crand`
1969 can thus be made more flexible. However the rules that apply in this
1970 section also apply to future CR-based instructions.
1971
1972 There are two primary different types of CR operations:
1973
1974 * Those which have a 3-bit operand field (referring to a CR Field)
1975 * Those which have a 5-bit operand (referring to a bit within the
1976 whole 32-bit CR)
1977
1978 Examining these two types it is observed that the difference may
1979 be considered to be that the 5-bit variant *already* provides the
1980 prerequisite information about which CR Field bit (EQ, GE, LT, SO) is
1981 to be operated on by the instruction. Thus, logically, we may set the
1982 following rule:
1983
1984 * When a 5-bit CR Result field is used in an instruction, the
1985 5-bit variant of Data-Dependent Fail-First
1986 must be used. i.e. the bit of the CR field to be tested is
1987 the one that has just been modified (created) by the operation.
1988 * When a 3-bit CR Result field is used the 3-bit variant
1989 must be used, providing as it does the missing `CRbit` field
1990 in order to select which CR Field bit of the result shall
1991 be tested (EQ, LE, GE, SO)
1992
1993 The reason why the 3-bit CR variant needs the additional CR-bit field
1994 should be obvious from the fact that the 3-bit CR Field from the base
1995 Power ISA v3.0B operation clearly does not contain and is missing the
1996 two CR Field Selector bits. Thus, these two bits (to select EQ, LE,
1997 GE or SO) must be provided in another way.
1998
1999 Examples of the former type:
2000
2001 * crand, cror, crnor. These all are 5-bit (BA, BB, BT). The bit
2002 to be tested against `inv` is the one selected by `BT`
2003 * mcrf. This has only 3-bit (BF, BFA). In order to select the
2004 bit to be tested, the alternative encoding must be used.
2005 With `CRbit` coming from the SVP64 RM bits 22-23 the bit
2006 of BF to be tested is identified.
2007
2008 Just as with SVP64 [[sv/branches]] there is the option to truncate
2009 VL to include the element being tested (`VLi=1`) and to exclude it
2010 (`VLi=0`).
2011
2012 Also exactly as with [[sv/normal]] fail-first, VL cannot, unlike
2013 [[sv/ldst]], be set to an arbitrary value. Deterministic behaviour
2014 is *required*.
2015
2016 ## Reduction and Iteration
2017
2018 Bearing in mind as described in the svp64 Appendix, SVP64 Horizontal
2019 Reduction is a deterministic schedule on top of base Scalar v3.0
2020 operations, the same rules apply to CR Operations, i.e. that programmers
2021 must follow certain conventions in order for an *end result* of a
2022 reduction to be achieved. Unlike other Vector ISAs *there are no explicit
2023 reduction opcodes* in SVP64: Schedules however achieve the same effect.
2024
2025 Due to these conventions only reduction on operations such as `crand`
2026 and `cror` are meaningful because these have Condition Register Fields
2027 as both input and output. Meaningless operations are not prohibited
2028 because the cost in hardware of doing so is prohibitive, but neither
2029 are they `UNDEFINED`. Implementations are still required to execute them
2030 but are at liberty to optimise out any operations that would ultimately
2031 be overwritten, as long as Strict Program Order is still obvservable by
2032 the programmer.
2033
2034 Also bear in mind that 'Reverse Gear' may be enabled, which can be
2035 used in combination with overlapping CR operations to iteratively
2036 accumulate results. Issuing a `sv.crand` operation for example with
2037 `BA` differing from `BB` by one Condition Register Field would result
2038 in a cascade effect, where the first-encountered CR Field would set the
2039 result to zero, and also all subsequent CR Field elements thereafter:
2040
2041 ```
2042 # sv.crand/mr/rg CR4.ge.v, CR5.ge.v, CR4.ge.v
2043 for i in VL-1 downto 0 # reverse gear
2044 CR.field[4+i].ge &= CR.field[5+i].ge
2045 ```
2046
2047 `sv.crxor` with reduction would be particularly useful for parity
2048 calculation for example, although there are many ways in which the same
2049 calculation could be carried out after transferring a vector of CR Fields
2050 to a GPR using crweird operations.
2051
2052 Implementations are free and clear to optimise these reductions in any way
2053 they see fit, as long as the end-result is compatible with Strict Program
2054 Order being observed, and Interrupt latency is not adversely impacted.
2055
2056 ## Unusual and quirky CR operations
2057
2058 **cmp and other compare ops**
2059
2060 `cmp` and `cmpi` etc take GPRs as sources and create a CR Field as a result.
2061
2062 cmpli BF,L,RA,UI
2063 cmpeqb BF,RA,RB
2064
2065 With `ELWIDTH` applying to the source GPR operands this is perfectly fine.
2066
2067 **crweird operations**
2068
2069 There are 4 weird CR-GPR operations and one reasonable one in
2070 the [[cr_int_predication]] set:
2071
2072 * crrweird
2073 * mtcrweird
2074 * crweirder
2075 * crweird
2076 * mcrfm - reasonably normal and referring to CR Fields for src and dest.
2077
2078 The "weird" operations have a non-standard behaviour, being able to
2079 treat *individual bits* of a GPR effectively as elements. They are
2080 expected to be Micro-coded by most Hardware implementations.
2081
2082
2083 --------
2084
2085 \newpage{}
2086
2087 # SVP64 Branch Conditional behaviour
2088
2089 Please note: although similar, SVP64 Branch instructions should be
2090 considered completely separate and distinct from standard scalar
2091 OpenPOWER-approved v3.0B branches. **v3.0B branches are in no way
2092 impacted, altered, changed or modified in any way, shape or form by the
2093 SVP64 Vectorised Variants**.
2094
2095 It is also extremely important to note that Branches are the sole
2096 pseudo-exception in SVP64 to `Scalar Identity Behaviour`. SVP64 Branches
2097 contain additional modes that are useful for scalar operations (i.e. even
2098 when VL=1 or when using single-bit predication).
2099
2100 **Rationale**
2101
2102 Scalar 3.0B Branch Conditional operations, `bc`, `bctar` etc. test
2103 a Condition Register. However for parallel processing it is simply
2104 impossible to perform multiple independent branches: the Program
2105 Counter simply cannot branch to multiple destinations based on multiple
2106 conditions. The best that can be done is to test multiple Conditions
2107 and make a decision of a *single* branch, based on analysis of a *Vector*
2108 of CR Fields which have just been calculated from a *Vector* of results.
2109
2110 In 3D Shader binaries, which are inherently parallelised and predicated,
2111 testing all or some results and branching based on multiple tests is
2112 extremely common, and a fundamental part of Shader Compilers. Example:
2113 without such multi-condition test-and-branch, if a predicate mask is
2114 all zeros a large batch of instructions may be masked out to `nop`,
2115 and it would waste CPU cycles to run them. 3D GPU ISAs can test for
2116 this scenario and, with the appropriate predicate-analysis instruction,
2117 jump over fully-masked-out operations, by spotting that *all* Conditions
2118 are false.
2119
2120 Unless Branches are aware and capable of such analysis, additional
2121 instructions would be required which perform Horizontal Cumulative
2122 analysis of Vectorised Condition Register Fields, in order to reduce
2123 the Vector of CR Fields down to one single yes or no decision that a
2124 Scalar-only v3.0B Branch-Conditional could cope with. Such instructions
2125 would be unavoidable, required, and costly by comparison to a single
2126 Vector-aware Branch. Therefore, in order to be commercially competitive,
2127 `sv.bc` and other Vector-aware Branch Conditional instructions are a
2128 high priority for 3D GPU (and OpenCL-style) workloads.
2129
2130 Given that Power ISA v3.0B is already quite powerful, particularly
2131 the Condition Registers and their interaction with Branches, there are
2132 opportunities to create extremely flexible and compact Vectorised Branch
2133 behaviour. In addition, the side-effects (updating of CTR, truncation
2134 of VL, described below) make it a useful instruction even if the branch
2135 points to the next instruction (no actual branch).
2136
2137 ## Overview
2138
2139 When considering an "array" of branch-tests, there are four
2140 primarily-useful modes: AND, OR, NAND and NOR of all Conditions.
2141 NAND and NOR may be synthesised from AND and OR by inverting `BO[1]`
2142 which just leaves two modes:
2143
2144 * Branch takes place on the **first** CR Field test to succeed
2145 (a Great Big OR of all condition tests). Exit occurs
2146 on the first **successful** test.
2147 * Branch takes place only if **all** CR field tests succeed:
2148 a Great Big AND of all condition tests. Exit occurs
2149 on the first **failed** test.
2150
2151 Early-exit is enacted such that the Vectorised Branch does not
2152 perform needless extra tests, which will help reduce reads on
2153 the Condition Register file.
2154
2155 *Note: Early-exit is **MANDATORY** (required) behaviour. Branches
2156 **MUST** exit at the first sequentially-encountered failure point,
2157 for exactly the same reasons for which it is mandatory in programming
2158 languages doing early-exit: to avoid damaging side-effects and to provide
2159 deterministic behaviour. Speculative testing of Condition Register
2160 Fields is permitted, as is speculative calculation of CTR, as long as,
2161 as usual in any Out-of-Order microarchitecture, that speculative testing
2162 is cancelled should an early-exit occur. i.e. the speculation must be
2163 "precise": Program Order must be preserved*
2164
2165 Also note that when early-exit occurs in Horizontal-first Mode, srcstep,
2166 dststep etc. are all reset, ready to begin looping from the beginning
2167 for the next instruction. However for Vertical-first Mode srcstep
2168 etc. are incremented "as usual" i.e. an early-exit has no special impact,
2169 regardless of whether the branch occurred or not. This can leave srcstep
2170 etc. in what may be considered an unusual state on exit from a loop and
2171 it is up to the programmer to reset srcstep, dststep etc. to known-good
2172 values *(easily achieved with `setvl`)*.
2173
2174 Additional useful behaviour involves two primary Modes (both of which
2175 may be enabled and combined):
2176
2177 * **VLSET Mode**: identical to Data-Dependent Fail-First Mode
2178 for Arithmetic SVP64 operations, with more
2179 flexibility and a close interaction and integration into the
2180 underlying base Scalar v3.0B Branch instruction.
2181 Truncation of VL takes place around the early-exit point.
2182 * **CTR-test Mode**: gives much more flexibility over when and why
2183 CTR is decremented, including options to decrement if a Condition
2184 test succeeds *or if it fails*.
2185
2186 With these side-effects, basic Boolean Logic Analysis advises that it
2187 is important to provide a means to enact them each based on whether
2188 testing succeeds *or fails*. This results in a not-insignificant number
2189 of additional Mode Augmentation bits, accompanying VLSET and CTR-test
2190 Modes respectively.
2191
2192 Predicate skipping or zeroing may, as usual with SVP64, be controlled by
2193 `sz`. Where the predicate is masked out and zeroing is enabled, then in
2194 such circumstances the same Boolean Logic Analysis dictates that rather
2195 than testing only against zero, the option to test against one is also
2196 prudent. This introduces a new immediate field, `SNZ`, which works in
2197 conjunction with `sz`.
2198
2199 Vectorised Branches can be used in either SVP64 Horizontal-First or
2200 Vertical-First Mode. Essentially, at an element level, the behaviour
2201 is identical in both Modes, although the `ALL` bit is meaningless in
2202 Vertical-First Mode.
2203
2204 It is also important to bear in mind that, fundamentally, Vectorised
2205 Branch-Conditional is still extremely close to the Scalar v3.0B
2206 Branch-Conditional instructions, and that the same v3.0B Scalar
2207 Branch-Conditional instructions are still *completely separate and
2208 independent*, being unaltered and unaffected by their SVP64 variants in
2209 every conceivable way.
2210
2211 *Programming note: One important point is that SVP64 instructions are
2212 64 bit. (8 bytes not 4). This needs to be taken into consideration
2213 when computing branch offsets: the offset is relative to the start of
2214 the instruction, which **includes** the SVP64 Prefix*
2215
2216 ## Format and fields
2217
2218 With element-width overrides being meaningless for Condition Register
2219 Fields, bits 4 thru 7 of SVP64 RM may be used for additional Mode bits.
2220
2221 SVP64 RM `MODE` (includes repurposing `ELWIDTH` bits 4:5, and
2222 `ELWIDTH_SRC` bits 6-7 for *alternate* uses) for Branch Conditional:
2223
2224 | 4 | 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 23 | description |
2225 | - | - | - | - | -- | -- | -- | -- | --- |--------|----------------- |
2226 |ALL|SNZ| / | / | SL |SLu | 0 | 0 | / | LRu sz | simple mode |
2227 |ALL|SNZ| / |VSb| SL |SLu | 0 | 1 | VLI | LRu sz | VLSET mode |
2228 |ALL|SNZ|CTi| / | SL |SLu | 1 | 0 | / | LRu sz | CTR-test mode |
2229 |ALL|SNZ|CTi|VSb| SL |SLu | 1 | 1 | VLI | LRu sz | CTR-test+VLSET mode |
2230
2231 Brief description of fields:
2232
2233 * **sz=1** if predication is enabled and `sz=1` and a predicate
2234 element bit is zero, `SNZ` will
2235 be substituted in place of the CR bit selected by `BI`,
2236 as the Condition tested.
2237 Contrast this with
2238 normal SVP64 `sz=1` behaviour, where *only* a zero is put in
2239 place of masked-out predicate bits.
2240 * **sz=0** When `sz=0` skipping occurs as usual on
2241 masked-out elements, but unlike all
2242 other SVP64 behaviour which entirely skips an element with
2243 no related side-effects at all, there are certain
2244 special circumstances where CTR
2245 may be decremented. See CTR-test Mode, below.
2246 * **ALL** when set, all branch conditional tests must pass in order for
2247 the branch to succeed. When clear, it is the first sequentially
2248 encountered successful test that causes the branch to succeed.
2249 This is identical behaviour to how programming languages perform
2250 early-exit on Boolean Logic chains.
2251 * **VLI** VLSET is identical to Data-dependent Fail-First mode.
2252 In VLSET mode, VL *may* (depending on `VSb`) be truncated.
2253 If VLI (Vector Length Inclusive) is clear,
2254 VL is truncated to *exclude* the current element, otherwise it is
2255 included. SVSTATE.MVL is not altered: only VL.
2256 * **SL** identical to `LR` except applicable to SVSTATE. If `SL`
2257 is set, SVSTATE is transferred to SVLR (conditionally on
2258 whether `SLu` is set).
2259 * **SLu**: SVSTATE Link Update, like `LRu` except applies to SVSTATE.
2260 * **LRu**: Link Register Update, used in conjunction with LK=1
2261 to make LR update conditional
2262 * **VSb** In VLSET Mode, after testing,
2263 if VSb is set, VL is truncated if the test succeeds. If VSb is clear,
2264 VL is truncated if a test *fails*. Masked-out (skipped)
2265 bits are not considered
2266 part of testing when `sz=0`
2267 * **CTi** CTR inversion. CTR-test Mode normally decrements per element
2268 tested. CTR inversion decrements if a test *fails*. Only relevant
2269 in CTR-test Mode.
2270
2271 LRu and CTR-test modes are where SVP64 Branches subtly differ from
2272 Scalar v3.0B Branches. `sv.bcl` for example will always update LR,
2273 whereas `sv.bcl/lru` will only update LR if the branch succeeds.
2274
2275 Of special interest is that when using ALL Mode (Great Big AND of all
2276 Condition Tests), if `VL=0`, which is rare but can occur in Data-Dependent
2277 Modes, the Branch will always take place because there will be no failing
2278 Condition Tests to prevent it. Likewise when not using ALL Mode (Great
2279 Big OR of all Condition Tests) and `VL=0` the Branch is guaranteed not
2280 to occur because there will be no *successful* Condition Tests to make
2281 it happen.
2282
2283 ## Vectorised CR Field numbering, and Scalar behaviour
2284
2285 It is important to keep in mind that just like all SVP64 instructions,
2286 the `BI` field of the base v3.0B Branch Conditional instruction may be
2287 extended by SVP64 EXTRA augmentation, as well as be marked as either
2288 Scalar or Vector. It is also crucially important to keep in mind that for
2289 CRs, SVP64 sequentially increments the CR *Field* numbers. CR *Fields*
2290 are treated as elements, not bit-numbers of the CR *register*.
2291
2292 The `BI` operand of Branch Conditional operations is five bits, in scalar
2293 v3.0B this would select one bit of the 32 bit CR, comprising eight CR
2294 Fields of 4 bits each. In SVP64 there are 16 32 bit CRs, containing
2295 128 4-bit CR Fields. Therefore, the 2 LSBs of `BI` select the bit from
2296 the CR Field (EQ LT GT SO), and the top 3 bits are extended to either
2297 scalar or vector and to select CR Fields 0..127 as specified in SVP64
2298 [[sv/svp64/appendix]].
2299
2300 When the CR Fields selected by SVP64-Augmented `BI` is marked as scalar,
2301 then as the usual SVP64 rules apply: the Vector loop ends at the first
2302 element tested (the first CR *Field*), after taking predication into
2303 consideration. Thus, also as usual, when a predicate mask is given, and
2304 `BI` marked as scalar, and `sz` is zero, srcstep skips forward to the
2305 first non-zero predicated element, and only that one element is tested.
2306
2307 In other words, the fact that this is a Branch Operation (instead of an
2308 arithmetic one) does not result, ultimately, in significant changes as
2309 to how SVP64 is fundamentally applied, except with respect to:
2310
2311 * the unique properties associated with conditionally
2312 changing the Program Counter (aka "a Branch"), resulting in early-out
2313 opportunities
2314 * CTR-testing
2315
2316 Both are outlined below, in later sections.
2317
2318 ## Horizontal-First and Vertical-First Modes
2319
2320 In SVP64 Horizontal-First Mode, the first failure in ALL mode (Great Big
2321 AND) results in early exit: no more updates to CTR occur (if requested);
2322 no branch occurs, and LR is not updated (if requested). Likewise for
2323 non-ALL mode (Great Big Or) on first success early exit also occurs,
2324 however this time with the Branch proceeding. In both cases the testing
2325 of the Vector of CRs should be done in linear sequential order (or in
2326 REMAP re-sequenced order): such that tests that are sequentially beyond
2327 the exit point are *not* carried out. (*Note: it is standard practice
2328 in Programming languages to exit early from conditional tests, however a
2329 little unusual to consider in an ISA that is designed for Parallel Vector
2330 Processing. The reason is to have strictly-defined guaranteed behaviour*)
2331
2332 In Vertical-First Mode, setting the `ALL` bit results in `UNDEFINED`
2333 behaviour. Given that only one element is being tested at a time in
2334 Vertical-First Mode, a test designed to be done on multiple bits is
2335 meaningless.
2336
2337 ## Description and Modes
2338
2339 Predication in both INT and CR modes may be applied to `sv.bc` and other
2340 SVP64 Branch Conditional operations, exactly as they may be applied to
2341 other SVP64 operations. When `sz` is zero, any masked-out Branch-element
2342 operations are not included in condition testing, exactly like all other
2343 SVP64 operations, *including* side-effects such as potentially updating
2344 LR or CTR, which will also be skipped. There is *one* exception here,
2345 which is when `BO[2]=0, sz=0, CTR-test=0, CTi=1` and the relevant element
2346 predicate mask bit is also zero: under these special circumstances CTR
2347 will also decrement.
2348
2349 When `sz` is non-zero, this normally requests insertion of a zero in
2350 place of the input data, when the relevant predicate mask bit is zero.
2351 This would mean that a zero is inserted in place of `CR[BI+32]` for
2352 testing against `BO`, which may not be desirable in all circumstances.
2353 Therefore, an extra field is provided `SNZ`, which, if set, will insert
2354 a **one** in place of a masked-out element, instead of a zero.
2355
2356 (*Note: Both options are provided because it is useful to deliberately
2357 cause the Branch-Conditional Vector testing to fail at a specific point,
2358 controlled by the Predicate mask. This is particularly useful in `VLSET`
2359 mode, which will truncate SVSTATE.VL at the point of the first failed
2360 test.*)
2361
2362 Normally, CTR mode will decrement once per Condition Test, resulting under
2363 normal circumstances that CTR reduces by up to VL in Horizontal-First
2364 Mode. Just as when v3.0B Branch-Conditional saves at least one instruction
2365 on tight inner loops through auto-decrementation of CTR, likewise it
2366 is also possible to save instruction count for SVP64 loops in both
2367 Vertical-First and Horizontal-First Mode, particularly in circumstances
2368 where there is conditional interaction between the element computation
2369 and testing, and the continuation (or otherwise) of a given loop. The
2370 potential combinations of interactions is why CTR testing options have
2371 been added.
2372
2373 Also, the unconditional bit `BO[0]` is still relevant when Predication
2374 is applied to the Branch because in `ALL` mode all nonmasked bits have
2375 to be tested, and when `sz=0` skipping occurs. Even when VLSET mode is
2376 not used, CTR may still be decremented by the total number of nonmasked
2377 elements, acting in effect as either a popcount or cntlz depending
2378 on which mode bits are set. In short, Vectorised Branch becomes an
2379 extremely powerful tool.
2380
2381 **Micro-Architectural Implementation Note**: *when implemented on top
2382 of a Multi-Issue Out-of-Order Engine it is possible to pass a copy of
2383 the predicate and the prerequisite CR Fields to all Branch Units, as
2384 well as the current value of CTR at the time of multi-issue, and for
2385 each Branch Unit to compute how many times CTR would be subtracted,
2386 in a fully-deterministic and parallel fashion. A SIMD-based Branch
2387 Unit, receiving and processing multiple CR Fields covered by multiple
2388 predicate bits, would do the exact same thing. Obviously, however, if
2389 CTR is modified within any given loop (mtctr) the behaviour of CTR is
2390 no longer deterministic.*
2391
2392 ### Link Register Update
2393
2394 For a Scalar Branch, unconditional updating of the Link Register LR
2395 is useful and practical. However, if a loop of CR Fields is tested,
2396 unconditional updating of LR becomes problematic.
2397
2398 For example when using `bclr` with `LRu=1,LK=0` in Horizontal-First Mode,
2399 LR's value will be unconditionally overwritten after the first element,
2400 such that for execution (testing) of the second element, LR has the value
2401 `CIA+8`. This is covered in the `bclrl` example, in a later section.
2402
2403 The addition of a LRu bit modifies behaviour in conjunction with LK,
2404 as follows:
2405
2406 * `sv.bc` When LRu=0,LK=0, Link Register is not updated
2407 * `sv.bcl` When LRu=0,LK=1, Link Register is updated unconditionally
2408 * `sv.bcl/lru` When LRu=1,LK=1, Link Register will
2409 only be updated if the Branch Condition fails.
2410 * `sv.bc/lru` When LRu=1,LK=0, Link Register will only be updated if
2411 the Branch Condition succeeds.
2412
2413 This avoids destruction of LR during loops (particularly Vertical-First
2414 ones).
2415
2416 **SVLR and SVSTATE**
2417
2418 For precisely the reasons why `LK=1` was added originally to the Power
2419 ISA, with SVSTATE being a peer of the Program Counter it becomes necessary
2420 to also add an SVLR (SVSTATE Link Register) and corresponding control bits
2421 `SL` and `SLu`.
2422
2423 ### CTR-test
2424
2425 Where a standard Scalar v3.0B branch unconditionally decrements CTR when
2426 `BO[2]` is clear, CTR-test Mode introduces more flexibility which allows
2427 CTR to be used for many more types of Vector loops constructs.
2428
2429 CTR-test mode and CTi interaction is as follows: note that `BO[2]`
2430 is still required to be clear for CTR decrements to be considered,
2431 exactly as is the case in Scalar Power ISA v3.0B
2432
2433 * **CTR-test=0, CTi=0**: CTR decrements on a per-element basis
2434 if `BO[2]` is zero. Masked-out elements when `sz=0` are
2435 skipped (i.e. CTR is *not* decremented when the predicate
2436 bit is zero and `sz=0`).
2437 * **CTR-test=0, CTi=1**: CTR decrements on a per-element basis
2438 if `BO[2]` is zero and a masked-out element is skipped
2439 (`sz=0` and predicate bit is zero). This one special case is the
2440 **opposite** of other combinations, as well as being
2441 completely different from normal SVP64 `sz=0` behaviour)
2442 * **CTR-test=1, CTi=0**: CTR decrements on a per-element basis
2443 if `BO[2]` is zero and the Condition Test succeeds.
2444 Masked-out elements when `sz=0` are skipped (including
2445 not decrementing CTR)
2446 * **CTR-test=1, CTi=1**: CTR decrements on a per-element basis
2447 if `BO[2]` is zero and the Condition Test *fails*.
2448 Masked-out elements when `sz=0` are skipped (including
2449 not decrementing CTR)
2450
2451 `CTR-test=0, CTi=1, sz=0` requires special emphasis because it is the
2452 only time in the entirety of SVP64 that has side-effects when
2453 a predicate mask bit is clear. **All** other SVP64 operations
2454 entirely skip an element when sz=0 and a predicate mask bit is zero.
2455 It is also critical to emphasise that in this unusual mode,
2456 no other side-effects occur: **only** CTR is decremented, i.e. the
2457 rest of the Branch operation is skipped.
2458
2459 ### VLSET Mode
2460
2461 VLSET Mode truncates the Vector Length so that subsequent instructions
2462 operate on a reduced Vector Length. This is similar to Data-dependent
2463 Fail-First and LD/ST Fail-First, where for VLSET the truncation occurs
2464 at the Branch decision-point.
2465
2466 Interestingly, due to the side-effects of `VLSET` mode it is actually
2467 useful to use Branch Conditional even to perform no actual branch
2468 operation, i.e to point to the instruction after the branch. Truncation of
2469 VL would thus conditionally occur yet control flow alteration would not.
2470
2471 `VLSET` mode with Vertical-First is particularly unusual. Vertical-First
2472 is designed to be used for explicit looping, where an explicit call to
2473 `svstep` is required to move both srcstep and dststep on to the next
2474 element, until VL (or other condition) is reached. Vertical-First Looping
2475 is expected (required) to terminate if the end of the Vector, VL, is
2476 reached. If however that loop is terminated early because VL is truncated,
2477 VLSET with Vertical-First becomes meaningless. Resolving this would
2478 require two branches: one Conditional, the other branching unconditionally
2479 to create the loop, where the Conditional one jumps over it.
2480
2481 Therefore, with `VSb`, the option to decide whether truncation should
2482 occur if the branch succeeds *or* if the branch condition fails allows
2483 for the flexibility required. This allows a Vertical-First Branch to
2484 *either* be used as a branch-back (loop) *or* as part of a conditional
2485 exit or function call from *inside* a loop, and for VLSET to be integrated
2486 into both types of decision-making.
2487
2488 In the case of a Vertical-First branch-back (loop), with `VSb=0` the
2489 branch takes place if success conditions are met, but on exit from that
2490 loop (branch condition fails), VL will be truncated. This is extremely
2491 useful.
2492
2493 `VLSET` mode with Horizontal-First when `VSb=0` is still useful, because
2494 it can be used to truncate VL to the first predicated (non-masked-out)
2495 element.
2496
2497 The truncation point for VL, when VLi is clear, must not include skipped
2498 elements that preceded the current element being tested. Example:
2499 `sz=0, VLi=0, predicate mask = 0b110010` and the Condition Register
2500 failure point is at CR Field element 4.
2501
2502 * Testing at element 0 is skipped because its predicate bit is zero
2503 * Testing at element 1 passed
2504 * Testing elements 2 and 3 are skipped because their
2505 respective predicate mask bits are zero
2506 * Testing element 4 fails therefore VL is truncated to **2**
2507 not 4 due to elements 2 and 3 being skipped.
2508
2509 If `sz=1` in the above example *then* VL would have been set to 4 because
2510 in non-zeroing mode the zero'd elements are still effectively part of the
2511 Vector (with their respective elements set to `SNZ`)
2512
2513 If `VLI=1` then VL would be set to 5 regardless of sz, due to being inclusive
2514 of the element actually being tested.
2515
2516 ### VLSET and CTR-test combined
2517
2518 If both CTR-test and VLSET Modes are requested, it is important to
2519 observe the correct order. What occurs depends on whether VLi is enabled,
2520 because VLi affects the length, VL.
2521
2522 If VLi (VL truncate inclusive) is set:
2523
2524 1. compute the test including whether CTR triggers
2525 2. (optionally) decrement CTR
2526 3. (optionally) truncate VL (VSb inverts the decision)
2527 4. decide (based on step 1) whether to terminate looping
2528 (including not executing step 5)
2529 5. decide whether to branch.
2530
2531 If VLi is clear, then when a test fails that element
2532 and any following it
2533 should **not** be considered part of the Vector. Consequently:
2534
2535 1. compute the branch test including whether CTR triggers
2536 2. if the test fails against VSb, truncate VL to the *previous*
2537 element, and terminate looping. No further steps executed.
2538 3. (optionally) decrement CTR
2539 4. decide whether to branch.
2540
2541 ## Boolean Logic combinations
2542
2543 In a Scalar ISA, Branch-Conditional testing even of vector results may be
2544 performed through inversion of tests. NOR of all tests may be performed
2545 by inversion of the scalar condition and branching *out* from the scalar
2546 loop around elements, using scalar operations.
2547
2548 In a parallel (Vector) ISA it is the ISA itself which must perform
2549 the prerequisite logic manipulation. Thus for SVP64 there are an
2550 extraordinary number of nesessary combinations which provide completely
2551 different and useful behaviour. Available options to combine:
2552
2553 * `BO[0]` to make an unconditional branch would seem irrelevant if
2554 it were not for predication and for side-effects (CTR Mode
2555 for example)
2556 * Enabling CTR-test Mode and setting `BO[2]` can still result in the
2557 Branch
2558 taking place, not because the Condition Test itself failed, but
2559 because CTR reached zero **because**, as required by CTR-test mode,
2560 CTR was decremented as a **result** of Condition Tests failing.
2561 * `BO[1]` to select whether the CR bit being tested is zero or nonzero
2562 * `R30` and `~R30` and other predicate mask options including CR and
2563 inverted CR bit testing
2564 * `sz` and `SNZ` to insert either zeros or ones in place of masked-out
2565 predicate bits
2566 * `ALL` or `ANY` behaviour corresponding to `AND` of all tests and
2567 `OR` of all tests, respectively.
2568 * Predicate Mask bits, which combine in effect with the CR being
2569 tested.
2570 * Inversion of Predicate Masks (`~r3` instead of `r3`, or using
2571 `NE` rather than `EQ`) which results in an additional
2572 level of possible ANDing, ORing etc. that would otherwise
2573 need explicit instructions.
2574
2575 The most obviously useful combinations here are to set `BO[1]` to zero
2576 in order to turn `ALL` into Great-Big-NAND and `ANY` into Great-Big-NOR.
2577 Other Mode bits which perform behavioural inversion then have to work
2578 round the fact that the Condition Testing is NOR or NAND. The alternative
2579 to not having additional behavioural inversion (`SNZ`, `VSb`, `CTi`)
2580 would be to have a second (unconditional) branch directly after the first,
2581 which the first branch jumps over. This contrivance is avoided by the
2582 behavioural inversion bits.
2583
2584 ## Pseudocode and examples
2585
2586 Please see the SVP64 appendix regarding CR bit ordering and for
2587 the definition of `CR{n}`
2588
2589 For comparative purposes this is a copy of the v3.0B `bc` pseudocode
2590
2591 ```
2592 if (mode_is_64bit) then M <- 0
2593 else M <- 32
2594 if ¬BO[2] then CTR <- CTR - 1
2595 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2596 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2597 if ctr_ok & cond_ok then
2598 if AA then NIA <-iea EXTS(BD || 0b00)
2599 else NIA <-iea CIA + EXTS(BD || 0b00)
2600 if LK then LR <-iea CIA + 4
2601 ```
2602
2603 Simplified pseudocode including LRu and CTR skipping, which illustrates
2604 clearly that SVP64 Scalar Branches (VL=1) are **not** identical to
2605 v3.0B Scalar Branches. The key areas where differences occur are the
2606 inclusion of predication (which can still be used when VL=1), in when and
2607 why CTR is decremented (CTRtest Mode) and whether LR is updated (which
2608 is unconditional in v3.0B when LK=1, and conditional in SVP64 when LRu=1).
2609
2610 Inline comments highlight the fact that the Scalar Branch behaviour and
2611 pseudocode is still clearly visible and embedded within the Vectorised
2612 variant:
2613
2614 ```
2615 if (mode_is_64bit) then M <- 0
2616 else M <- 32
2617 # the bit of CR to test, if the predicate bit is zero,
2618 # is overridden
2619 testbit = CR[BI+32]
2620 if ¬predicate_bit then testbit = SVRMmode.SNZ
2621 # otherwise apart from the override ctr_ok and cond_ok
2622 # are exactly the same
2623 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2624 cond_ok <- BO[0] | ¬(testbit ^ BO[1])
2625 if ¬predicate_bit & ¬SVRMmode.sz then
2626 # this is entirely new: CTR-test mode still decrements CTR
2627 # even when predicate-bits are zero
2628 if ¬BO[2] & CTRtest & ¬CTi then
2629 CTR = CTR - 1
2630 # instruction finishes here
2631 else
2632 # usual BO[2] CTR-mode now under CTR-test mode as well
2633 if ¬BO[2] & ¬(CTRtest & (cond_ok ^ CTi)) then CTR <- CTR - 1
2634 # new VLset mode, conditional test truncates VL
2635 if VLSET and VSb = (cond_ok & ctr_ok) then
2636 if SVRMmode.VLI then SVSTATE.VL = srcstep+1
2637 else SVSTATE.VL = srcstep
2638 # usual LR is now conditional, but also joined by SVLR
2639 lr_ok <- LK
2640 svlr_ok <- SVRMmode.SL
2641 if ctr_ok & cond_ok then
2642 if AA then NIA <-iea EXTS(BD || 0b00)
2643 else NIA <-iea CIA + EXTS(BD || 0b00)
2644 if SVRMmode.LRu then lr_ok <- ¬lr_ok
2645 if SVRMmode.SLu then svlr_ok <- ¬svlr_ok
2646 if lr_ok then LR <-iea CIA + 4
2647 if svlr_ok then SVLR <- SVSTATE
2648 ```
2649
2650 Below is the pseudocode for SVP64 Branches, which is a little less
2651 obvious but identical to the above. The lack of obviousness is down to
2652 the early-exit opportunities.
2653
2654 Effective pseudocode for Horizontal-First Mode:
2655
2656 ```
2657 if (mode_is_64bit) then M <- 0
2658 else M <- 32
2659 cond_ok = not SVRMmode.ALL
2660 for srcstep in range(VL):
2661 # select predicate bit or zero/one
2662 if predicate[srcstep]:
2663 # get SVP64 extended CR field 0..127
2664 SVCRf = SVP64EXTRA(BI>>2)
2665 CRbits = CR{SVCRf}
2666 testbit = CRbits[BI & 0b11]
2667 # testbit = CR[BI+32+srcstep*4]
2668 else if not SVRMmode.sz:
2669 # inverted CTR test skip mode
2670 if ¬BO[2] & CTRtest & ¬CTI then
2671 CTR = CTR - 1
2672 continue # skip to next element
2673 else
2674 testbit = SVRMmode.SNZ
2675 # actual element test here
2676 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2677 el_cond_ok <- BO[0] | ¬(testbit ^ BO[1])
2678 # check if CTR dec should occur
2679 ctrdec = ¬BO[2]
2680 if CTRtest & (el_cond_ok ^ CTi) then
2681 ctrdec = 0b0
2682 if ctrdec then CTR <- CTR - 1
2683 # merge in the test
2684 if SVRMmode.ALL:
2685 cond_ok &= (el_cond_ok & ctr_ok)
2686 else
2687 cond_ok |= (el_cond_ok & ctr_ok)
2688 # test for VL to be set (and exit)
2689 if VLSET and VSb = (el_cond_ok & ctr_ok) then
2690 if SVRMmode.VLI then SVSTATE.VL = srcstep+1
2691 else SVSTATE.VL = srcstep
2692 break
2693 # early exit?
2694 if SVRMmode.ALL != (el_cond_ok & ctr_ok):
2695 break
2696 # SVP64 rules about Scalar registers still apply!
2697 if SVCRf.scalar:
2698 break
2699 # loop finally done, now test if branch (and update LR)
2700 lr_ok <- LK
2701 svlr_ok <- SVRMmode.SL
2702 if cond_ok then
2703 if AA then NIA <-iea EXTS(BD || 0b00)
2704 else NIA <-iea CIA + EXTS(BD || 0b00)
2705 if SVRMmode.LRu then lr_ok <- ¬lr_ok
2706 if SVRMmode.SLu then svlr_ok <- ¬svlr_ok
2707 if lr_ok then LR <-iea CIA + 4
2708 if svlr_ok then SVLR <- SVSTATE
2709 ```
2710
2711 Pseudocode for Vertical-First Mode:
2712
2713 ```
2714 # get SVP64 extended CR field 0..127
2715 SVCRf = SVP64EXTRA(BI>>2)
2716 CRbits = CR{SVCRf}
2717 # select predicate bit or zero/one
2718 if predicate[srcstep]:
2719 if BRc = 1 then # CR0 vectorised
2720 CR{SVCRf+srcstep} = CRbits
2721 testbit = CRbits[BI & 0b11]
2722 else if not SVRMmode.sz:
2723 # inverted CTR test skip mode
2724 if ¬BO[2] & CTRtest & ¬CTI then
2725 CTR = CTR - 1
2726 SVSTATE.srcstep = new_srcstep
2727 exit # no branch testing
2728 else
2729 testbit = SVRMmode.SNZ
2730 # actual element test here
2731 cond_ok <- BO[0] | ¬(testbit ^ BO[1])
2732 # test for VL to be set (and exit)
2733 if VLSET and cond_ok = VSb then
2734 if SVRMmode.VLI
2735 SVSTATE.VL = new_srcstep+1
2736 else
2737 SVSTATE.VL = new_srcstep
2738 ```
2739
2740 ### Example Shader code
2741
2742 ```
2743 // assume f() g() or h() modify a and/or b
2744 while(a > 2) {
2745 if(b < 5)
2746 f();
2747 else
2748 g();
2749 h();
2750 }
2751 ```
2752
2753 which compiles to something like:
2754
2755 ```
2756 vec<i32> a, b;
2757 // ...
2758 pred loop_pred = a > 2;
2759 // loop continues while any of a elements greater than 2
2760 while(loop_pred.any()) {
2761 // vector of predicate bits
2762 pred if_pred = loop_pred & (b < 5);
2763 // only call f() if at least 1 bit set
2764 if(if_pred.any()) {
2765 f(if_pred);
2766 }
2767 label1:
2768 // loop mask ANDs with inverted if-test
2769 pred else_pred = loop_pred & ~if_pred;
2770 // only call g() if at least 1 bit set
2771 if(else_pred.any()) {
2772 g(else_pred);
2773 }
2774 h(loop_pred);
2775 }
2776 ```
2777
2778 which will end up as:
2779
2780 ```
2781 # start from while loop test point
2782 b looptest
2783 while_loop:
2784 sv.cmpi CR80.v, b.v, 5 # vector compare b into CR64 Vector
2785 sv.bc/m=r30/~ALL/sz CR80.v.LT skip_f # skip when none
2786 # only calculate loop_pred & pred_b because needed in f()
2787 sv.crand CR80.v.SO, CR60.v.GT, CR80.V.LT # if = loop & pred_b
2788 f(CR80.v.SO)
2789 skip_f:
2790 # illustrate inversion of pred_b. invert r30, test ALL
2791 # rather than SOME, but masked-out zero test would FAIL,
2792 # therefore masked-out instead is tested against 1 not 0
2793 sv.bc/m=~r30/ALL/SNZ CR80.v.LT skip_g
2794 # else = loop & ~pred_b, need this because used in g()
2795 sv.crternari(A&~B) CR80.v.SO, CR60.v.GT, CR80.V.LT
2796 g(CR80.v.SO)
2797 skip_g:
2798 # conditionally call h(r30) if any loop pred set
2799 sv.bclr/m=r30/~ALL/sz BO[1]=1 h()
2800 looptest:
2801 sv.cmpi CR60.v a.v, 2 # vector compare a into CR60 vector
2802 sv.crweird r30, CR60.GT # transfer GT vector to r30
2803 sv.bc/m=r30/~ALL/sz BO[1]=1 while_loop
2804 end:
2805 ```
2806
2807 ### LRu example
2808
2809 show why LRu would be useful in a loop. Imagine the following
2810 c code:
2811
2812 ```
2813 for (int i = 0; i < 8; i++) {
2814 if (x < y) break;
2815 }
2816 ```
2817
2818 Under these circumstances exiting from the loop is not only based on
2819 CTR it has become conditional on a CR result. Thus it is desirable that
2820 NIA *and* LR only be modified if the conditions are met
2821
2822 v3.0 pseudocode for `bclrl`:
2823
2824 ```
2825 if (mode_is_64bit) then M <- 0
2826 else M <- 32
2827 if ¬BO[2] then CTR <- CTR - 1
2828 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2829 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2830 if ctr_ok & cond_ok then NIA <-iea LR[0:61] || 0b00
2831 if LK then LR <-iea CIA + 4
2832 ```
2833
2834 the latter part for SVP64 `bclrl` becomes:
2835
2836 ```
2837 for i in 0 to VL-1:
2838 ...
2839 ...
2840 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2841 lr_ok <- LK
2842 if ctr_ok & cond_ok then
2843 NIA <-iea LR[0:61] || 0b00
2844 if SVRMmode.LRu then lr_ok <- ¬lr_ok
2845 if lr_ok then LR <-iea CIA + 4
2846 # if NIA modified exit loop
2847 ```
2848
2849 The reason why should be clear from this being a Vector loop:
2850 unconditional destruction of LR when LK=1 makes `sv.bclrl` ineffective,
2851 because the intention going into the loop is that the branch should be to
2852 the copy of LR set at the *start* of the loop, not half way through it.
2853 However if the change to LR only occurs if the branch is taken then it
2854 becomes a useful instruction.
2855
2856 The following pseudocode should **not** be implemented because it
2857 violates the fundamental principle of SVP64 which is that SVP64 looping
2858 is a thin wrapper around Scalar Instructions. The pseducode below is
2859 more an actual Vector ISA Branch and as such is not at all appropriate:
2860
2861 ```
2862 for i in 0 to VL-1:
2863 ...
2864 ...
2865 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2866 if ctr_ok & cond_ok then NIA <-iea LR[0:61] || 0b00
2867 # only at the end of looping is LK checked.
2868 # this completely violates the design principle of SVP64
2869 # and would actually need to be a separate (scalar)
2870 # instruction "set LR to CIA+4 but retrospectively"
2871 # which is clearly impossible
2872 if LK then LR <-iea CIA + 4
2873 ```
2874
2875 [[!tag opf_rfc]]