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