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