(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 ## Fail-on-first
941
942 Data-dependent fail-on-first has two distinct variants: one for LD/ST,
943 the other for arithmetic operations (actually, CR-driven). Note in
944 each case the assumption is that 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 Two extremely important aspects of ffirst are:
997
998 * LDST ffirst may never set VL equal to zero. This because on the first
999 element an exception must be raised "as normal".
1000 * CR-based data-dependent ffirst on the other hand **can** set VL equal
1001 to zero. This is the only means in the entirety of SV that VL may be set
1002 to zero (with the exception of via the SV.STATE SPR). When VL is set
1003 zero due to the first element failing the CR bit-test, all subsequent
1004 vectorised operations are effectively `nops` which is
1005 *precisely the desired and intended behaviour*.
1006
1007 The second crucial aspect, compared to LDST Ffirst:
1008
1009 * LD/ST Failfirst may (beyond the initial first element
1010 conditions) truncate VL for any architecturally suitable reason. Beyond
1011 the first element LD/ST Failfirst is arbitrarily speculative and 100%
1012 non-deterministic.
1013 * CR-based data-dependent first on the other hand MUST NOT truncate VL
1014 arbitrarily to a length decided by the hardware: VL MUST only be
1015 truncated based explicitly on whether a test fails. This because it is
1016 a precise Deterministic test on which algorithms can and will will rely.
1017
1018 **Floating-point Exceptions**
1019
1020 When Floating-point exceptions are enabled VL must be truncated at
1021 the point where the Exception appears not to have occurred. If `VLi`
1022 is set then VL must include the faulting element, and thus the faulting
1023 element will always raise its exception. If however `VLi` is clear then
1024 VL **excludes** the faulting element and thus the exception will **never**
1025 be raised.
1026
1027 Although very strongly discouraged the Exception Mode that permits
1028 Floating Point Exception notification to arrive too late to unwind
1029 is permitted (under protest, due it violating the otherwise 100%
1030 Deterministic nature of Data-dependent Fail-first) and is `UNDEFINED`
1031 behaviour.
1032
1033 **Use of lax FP Exception Notification Mode could result in parallel
1034 computations proceeding with invalid results that have to be explicitly
1035 detected, whereas with the strict FP Execption Mode enabled, FFirst
1036 truncates VL, allows subsequent parallel computation to avoid the
1037 exceptions entirely**
1038
1039 ## Data-dependent fail-first on CR operations (crand etc)
1040
1041 Operations that actually produce or alter CR Field as a result have
1042 their own SVP64 Mode, described in [[sv/cr_ops]].
1043
1044 ## pred-result mode
1045
1046 This mode merges common CR testing with predication, saving on instruction
1047 count. Below is the pseudocode excluding predicate zeroing and elwidth
1048 overrides. Note that the pseudocode for SVP64 CR-ops is slightly different.
1049
1050 ```
1051 for i in range(VL):
1052 # predication test, skip all masked out elements.
1053 if predicate_masked_out(i):
1054 continue
1055 result = op(iregs[RA+i], iregs[RB+i])
1056 CRnew = analyse(result) # calculates eq/lt/gt
1057 # Rc=1 always stores the CR field
1058 if Rc=1 or RC1:
1059 CR.field[offs+i] = CRnew
1060 # now test CR, similar to branch
1061 if RC1 or CR.field[BO[0:1]] != BO[2]:
1062 continue # test failed: cancel store
1063 # result optionally stored but CR always is
1064 iregs[RT+i] = result
1065 ```
1066
1067 The reason for allowing the CR element to be stored is so that
1068 post-analysis of the CR Vector may be carried out. For example:
1069 Saturation may have occurred (and been prevented from updating, by the
1070 test) but it is desirable to know *which* elements fail saturation.
1071
1072 Note that RC1 Mode basically turns all operations into `cmp`. The
1073 calculation is performed but it is only the CR that is written. The
1074 element result is *always* discarded, never written (just like `cmp`).
1075
1076 Note that predication is still respected: predicate zeroing is slightly
1077 different: elements that fail the CR test *or* are masked out are zero'd.
1078
1079 --------
1080
1081 \newpage{}
1082
1083 # SV Load and Store
1084
1085 **Rationale**
1086
1087 All Vector ISAs dating back fifty years have extensive and comprehensive
1088 Load and Store operations that go far beyond the capabilities of Scalar
1089 RISC and most CISC processors, yet at their heart on an individual element
1090 basis may be found to be no different from RISC Scalar equivalents.
1091
1092 The resource savings from Vector LD/ST are significant and stem
1093 from the fact that one single instruction can trigger a dozen (or in
1094 some microarchitectures such as Cray or NEC SX Aurora) hundreds of
1095 element-level Memory accesses.
1096
1097 Additionally, and simply: if the Arithmetic side of an ISA supports
1098 Vector Operations, then in order to keep the ALUs 100% occupied the
1099 Memory infrastructure (and the ISA itself) correspondingly needs Vector
1100 Memory Operations as well.
1101
1102 Vectorised Load and Store also presents an extra dimension (literally)
1103 which creates scenarios unique to Vector applications, that a Scalar
1104 (and even a SIMD) ISA simply never encounters. SVP64 endeavours to add
1105 the modes typically found in *all* Scalable Vector ISAs, without changing
1106 the behaviour of the underlying Base (Scalar) v3.0B operations in any way.
1107
1108 ## Modes overview
1109
1110 Vectorisation of Load and Store requires creation, from scalar operations,
1111 a number of different modes:
1112
1113 * **fixed aka "unit" stride** - contiguous sequence with no gaps
1114 * **element strided** - sequential but regularly offset, with gaps
1115 * **vector indexed** - vector of base addresses and vector of offsets
1116 * **Speculative fail-first** - where it makes sense to do so
1117 * **Structure Packing** - covered in SV by [[sv/remap]] and Pack/Unpack Mode.
1118
1119 *Despite being constructed from Scalar LD/ST none of these Modes exist
1120 or make sense in any Scalar ISA. They **only** exist in Vector ISAs*
1121
1122 Also included in SVP64 LD/ST is both signed and unsigned Saturation,
1123 as well as Element-width overrides and Twin-Predication.
1124
1125 Note also that Indexed [[sv/remap]] mode may be applied to both v3.0
1126 LD/ST Immediate instructions *and* v3.0 LD/ST Indexed instructions.
1127 LD/ST-Indexed should not be conflated with Indexed REMAP mode:
1128 clarification is provided below.
1129
1130 **Determining the LD/ST Modes**
1131
1132 A minor complication (caused by the retro-fitting of modern Vector
1133 features to a Scalar ISA) is that certain features do not exactly make
1134 sense or are considered a security risk. Fail-first on Vector Indexed
1135 would allow attackers to probe large numbers of pages from userspace,
1136 where strided fail-first (by creating contiguous sequential LDs) does not.
1137
1138 In addition, reduce mode makes no sense. Realistically we need an
1139 alternative table definition for [[sv/svp64]] `RM.MODE`. The following
1140 modes make sense:
1141
1142 * saturation
1143 * predicate-result (mostly for cache-inhibited LD/ST)
1144 * simple (no augmentation)
1145 * fail-first (where Vector Indexed is banned)
1146 * Signed Effective Address computation (Vector Indexed only)
1147
1148 More than that however it is necessary to fit the usual Vector ISA
1149 capabilities onto both Power ISA LD/ST with immediate and to LD/ST
1150 Indexed. They present subtly different Mode tables, which, due to lack
1151 of space, have the following quirks:
1152
1153 * LD/ST Immediate has no individual control over src/dest zeroing,
1154 whereas LD/ST Indexed does.
1155 * LD/ST Immediate has no Saturated Pack/Unpack (Arithmetic Mode does)
1156 * LD/ST Indexed has no Pack/Unpack (REMAP may be used instead)
1157
1158 ## Format and fields
1159
1160 Fields used in tables below:
1161
1162 * **sz / dz** if predication is enabled will put zeros into the dest
1163 (or as src in the case of twin pred) when the predicate bit is zero.
1164 otherwise the element is ignored or skipped, depending on context.
1165 * **zz**: both sz and dz are set equal to this flag.
1166 * **inv CR bit** just as in branches (BO) these bits allow testing of
1167 a CR bit and whether it is set (inv=0) or unset (inv=1)
1168 * **N** sets signed/unsigned saturation.
1169 * **RC1** as if Rc=1, stores CRs *but not the result*
1170 * **SEA** - Signed Effective Address, if enabled performs sign-extension on
1171 registers that have been reduced due to elwidth overrides
1172 * **PI** - post-increment mode (applies to LD/ST with update only).
1173 the Effective Address utilised is always just RA, i.e. the computation of
1174 EA is stored in RA **after** it is actually used.
1175
1176 **LD/ST immediate**
1177
1178 The table for [[sv/svp64]] for `immed(RA)` which is `RM.MODE`
1179 (bits 19:23 of `RM`) is:
1180
1181 | 0-1 | 2 | 3 4 | description |
1182 | --- | --- |---------|--------------------------- |
1183 | 00 | 0 | zz els | simple mode |
1184 | 00 | 1 | PI LF | post-increment and Fault-First |
1185 | 01 | inv | CR-bit | Rc=1: ffirst CR sel |
1186 | 01 | inv | els RC1 | Rc=0: ffirst z/nonz |
1187 | 10 | N | zz els | sat mode: N=0/1 u/s |
1188 | 11 | inv | CR-bit | Rc=1: pred-result CR sel |
1189 | 11 | inv | els RC1 | Rc=0: pred-result z/nonz |
1190
1191 The `els` bit is only relevant when `RA.isvec` is clear: this indicates
1192 whether stride is unit or element:
1193
1194 ```
1195 if RA.isvec:
1196 svctx.ldstmode = indexed
1197 elif els == 0:
1198 svctx.ldstmode = unitstride
1199 elif immediate != 0:
1200 svctx.ldstmode = elementstride
1201 ```
1202
1203 An immediate of zero is a safety-valve to allow `LD-VSPLAT`: in effect
1204 the multiplication of the immediate-offset by zero results in reading from
1205 the exact same memory location, *even with a Vector register*. (Normally
1206 this type of behaviour is reserved for the mapreduce modes)
1207
1208 For `LD-VSPLAT`, on non-cache-inhibited Loads, the read can occur just
1209 the once and be copied, rather than hitting the Data Cache multiple
1210 times with the same memory read at the same location. The benefit of
1211 Cache-inhibited LD-splats is that it allows for memory-mapped peripherals
1212 to have multiple data values read in quick succession and stored in
1213 sequentially numbered registers (but, see Note below).
1214
1215 For non-cache-inhibited ST from a vector source onto a scalar destination:
1216 with the Vector loop effectively creating multiple memory writes to
1217 the same location, we can deduce that the last of these will be the
1218 "successful" one. Thus, implementations are free and clear to optimise
1219 out the overwriting STs, leaving just the last one as the "winner".
1220 Bear in mind that predicate masks will skip some elements (in source
1221 non-zeroing mode). Cache-inhibited ST operations on the other hand
1222 **MUST** write out a Vector source multiple successive times to the exact
1223 same Scalar destination. Just like Cache-inhibited LDs, multiple values
1224 may be written out in quick succession to a memory-mapped peripheral
1225 from sequentially-numbered registers.
1226
1227 Note that any memory location may be Cache-inhibited
1228 (Power ISA v3.1, Book III, 1.6.1, p1033)
1229
1230 *Programmer's Note: an immediate also with a Scalar source as a "VSPLAT"
1231 mode is simply not possible: there are not enough Mode bits. One single
1232 Scalar Load operation may be used instead, followed by any arithmetic
1233 operation (including a simple mv) in "Splat" mode.*
1234
1235 **LD/ST Indexed**
1236
1237 The modes for `RA+RB` indexed version are slightly different
1238 but are the same `RM.MODE` bits (19:23 of `RM`):
1239
1240 | 0-1 | 2 | 3 4 | description |
1241 | --- | --- |---------|-------------------------- |
1242 | 00 | SEA | dz sz | simple mode |
1243 | 01 | SEA | dz sz | Strided (scalar only source) |
1244 | 10 | N | dz sz | sat mode: N=0/1 u/s |
1245 | 11 | inv | CR-bit | Rc=1: pred-result CR sel |
1246 | 11 | inv | zz RC1 | Rc=0: pred-result z/nonz |
1247
1248 Vector Indexed Strided Mode is qualified as follows:
1249
1250 if mode = 0b01 and !RA.isvec and !RB.isvec:
1251 svctx.ldstmode = elementstride
1252
1253 A summary of the effect of Vectorisation of src or dest:
1254
1255 ```
1256 imm(RA) RT.v RA.v no stride allowed
1257 imm(RA) RT.s RA.v no stride allowed
1258 imm(RA) RT.v RA.s stride-select allowed
1259 imm(RA) RT.s RA.s not vectorised
1260 RA,RB RT.v {RA|RB}.v Standard Indexed
1261 RA,RB RT.s {RA|RB}.v Indexed but single LD (no VSPLAT)
1262 RA,RB RT.v {RA&RB}.s VSPLAT possible. stride selectable
1263 RA,RB RT.s {RA&RB}.s not vectorised (scalar identity)
1264 ```
1265
1266 Signed Effective Address computation is only relevant for Vector Indexed
1267 Mode, when elwidth overrides are applied. The source override applies to
1268 RB, and before adding to RA in order to calculate the Effective Address,
1269 if SEA is set RB is sign-extended from elwidth bits to the full 64 bits.
1270 For other Modes (ffirst, saturate), all EA computation with elwidth
1271 overrides is unsigned.
1272
1273 Note that cache-inhibited LD/ST when VSPLAT is activated will perform
1274 **multiple** LD/ST operations, sequentially. Even with scalar src
1275 a Cache-inhibited LD will read the same memory location *multiple
1276 times*, storing the result in successive Vector destination registers.
1277 This because the cache-inhibit instructions are typically used to read
1278 and write memory-mapped peripherals. If a genuine cache-inhibited
1279 LD-VSPLAT is required then a single *scalar* cache-inhibited LD should
1280 be performed, followed by a VSPLAT-augmented mv, copying the one *scalar*
1281 value into multiple register destinations.
1282
1283 Note also that cache-inhibited VSPLAT with Predicate-result is possible.
1284 This allows for example to issue a massive batch of memory-mapped
1285 peripheral reads, stopping at the first NULL-terminated character and
1286 truncating VL to that point. No branch is needed to issue that large
1287 burst of LDs, which may be valuable in Embedded scenarios.
1288
1289 ## Vectorisation of Scalar Power ISA v3.0B
1290
1291 Scalar Power ISA Load/Store operations may be seen from their
1292 pseudocode to be of the form:
1293
1294 ```
1295 lbux RT, RA, RB
1296 EA <- (RA) + (RB)
1297 RT <- MEM(EA)
1298 ```
1299
1300 and for immediate variants:
1301
1302 ```
1303 lb RT,D(RA)
1304 EA <- RA + EXTS(D)
1305 RT <- MEM(EA)
1306 ```
1307
1308 Thus in the first example, the source registers may each be independently
1309 marked as scalar or vector, and likewise the destination; in the second
1310 example only the one source and one dest may be marked as scalar or
1311 vector.
1312
1313 Thus we can see that Vector Indexed may be covered, and, as demonstrated
1314 with the pseudocode below, the immediate can be used to give unit
1315 stride or element stride. With there being no way to tell which from
1316 the Power v3.0B Scalar opcode alone, the choice is provided instead by
1317 the SV Context.
1318
1319 ```
1320 # LD not VLD! format - ldop RT, immed(RA)
1321 # op_width: lb=1, lh=2, lw=4, ld=8
1322 op_load(RT, RA, op_width, immed, svctx, RAupdate):
1323  ps = get_pred_val(FALSE, RA); # predication on src
1324  pd = get_pred_val(FALSE, RT); # ... AND on dest
1325  for (i=0, j=0, u=0; i < VL && j < VL;):
1326 # skip nonpredicates elements
1327 if (RA.isvec) while (!(ps & 1<<i)) i++;
1328 if (RAupdate.isvec) while (!(ps & 1<<u)) u++;
1329 if (RT.isvec) while (!(pd & 1<<j)) j++;
1330 if postinc:
1331 offs = 0; # added afterwards
1332 if RA.isvec: srcbase = ireg[RA+i]
1333 else srcbase = ireg[RA]
1334 elif svctx.ldstmode == elementstride:
1335 # element stride mode
1336 srcbase = ireg[RA]
1337 offs = i * immed # j*immed for a ST
1338 elif svctx.ldstmode == unitstride:
1339 # unit stride mode
1340 srcbase = ireg[RA]
1341 offs = immed + (i * op_width) # j*op_width for ST
1342 elif RA.isvec:
1343 # quirky Vector indexed mode but with an immediate
1344 srcbase = ireg[RA+i]
1345 offs = immed;
1346 else
1347 # standard scalar mode (but predicated)
1348 # no stride multiplier means VSPLAT mode
1349 srcbase = ireg[RA]
1350 offs = immed
1351
1352 # compute EA
1353 EA = srcbase + offs
1354 # load from memory
1355 ireg[RT+j] <= MEM[EA];
1356 # check post-increment of EA
1357 if postinc: EA = srcbase + immed;
1358 # update RA?
1359 if RAupdate: ireg[RAupdate+u] = EA;
1360 if (!RT.isvec)
1361 break # destination scalar, end now
1362 if (RA.isvec) i++;
1363 if (RAupdate.isvec) u++;
1364 if (RT.isvec) j++;
1365 ```
1366
1367 Indexed LD is:
1368
1369 ```
1370 # format: ldop RT, RA, RB
1371 function op_ldx(RT, RA, RB, RAupdate=False) # LD not VLD!
1372  ps = get_pred_val(FALSE, RA); # predication on src
1373  pd = get_pred_val(FALSE, RT); # ... AND on dest
1374  for (i=0, j=0, k=0, u=0; i < VL && j < VL && k < VL):
1375 # skip nonpredicated RA, RB and RT
1376 if (RA.isvec) while (!(ps & 1<<i)) i++;
1377 if (RAupdate.isvec) while (!(ps & 1<<u)) u++;
1378 if (RB.isvec) while (!(ps & 1<<k)) k++;
1379 if (RT.isvec) while (!(pd & 1<<j)) j++;
1380 if svctx.ldstmode == elementstride:
1381 EA = ireg[RA] + ireg[RB]*j # register-strided
1382 else
1383 EA = ireg[RA+i] + ireg[RB+k] # indexed address
1384 if RAupdate: ireg[RAupdate+u] = EA
1385 ireg[RT+j] <= MEM[EA];
1386 if (!RT.isvec)
1387 break # destination scalar, end immediately
1388 if (RA.isvec) i++;
1389 if (RAupdate.isvec) u++;
1390 if (RB.isvec) k++;
1391 if (RT.isvec) j++;
1392 ```
1393
1394 Note that Element-Strided uses the Destination Step because with both
1395 sources being Scalar as a prerequisite condition of activation of
1396 Element-Stride Mode, the source step (being Scalar) would never advance.
1397
1398 Note in both cases that [[sv/svp64]] allows RA-as-a-dest in "update"
1399 mode (`ldux`) to be effectively a *completely different* register from
1400 RA-as-a-source. This because there is room in svp64 to extend RA-as-src
1401 as well as RA-as-dest, both independently as scalar or vector *and*
1402 independently extending their range.
1403
1404 *Programmer's note: being able to set RA-as-a-source as separate from
1405 RA-as-a-destination as Scalar is **extremely valuable** once it is
1406 remembered that Simple-V element operations must be in Program Order,
1407 especially in loops, for saving on multiple address computations. Care
1408 does have to be taken however that RA-as-src is not overwritten by
1409 RA-as-dest unless intentionally desired, especially in element-strided
1410 Mode.*
1411
1412 ## LD/ST Indexed vs Indexed REMAP
1413
1414 Unfortunately the word "Indexed" is used twice in completely different
1415 contexts, potentially causing confusion.
1416
1417 * There has existed instructions in the Power ISA `ld RT,RA,RB` since
1418 its creation: these are called "LD/ST Indexed" instructions and their
1419 name and meaning is well-established.
1420 * There now exists, in Simple-V, a REMAP mode called "Indexed"
1421 Mode that can be applied to *any* instruction **including those
1422 named LD/ST Indexed**.
1423
1424 Whilst it may be costly in terms of register reads to allow REMAP Indexed
1425 Mode to be applied to any Vectorised LD/ST Indexed operation such as
1426 `sv.ld *RT,RA,*RB`, or even misleadingly labelled as redundant, firstly
1427 the strict application of the RISC Paradigm that Simple-V follows makes
1428 it awkward to consider *preventing* the application of Indexed REMAP to
1429 such operations, and secondly they are not actually the same at all.
1430
1431 Indexed REMAP, as applied to RB in the instruction `sv.ld *RT,RA,*RB`
1432 effectively performs an *in-place* re-ordering of the offsets, RB.
1433 To achieve the same effect without Indexed REMAP would require taking
1434 a *copy* of the Vector of offsets starting at RB, manually explicitly
1435 reordering them, and finally using the copy of re-ordered offsets in a
1436 non-REMAP'ed `sv.ld`. Using non-strided LD as an example, pseudocode
1437 showing what actually occurs, where the pseudocode for `indexed_remap`
1438 may be found in [[sv/remap]]:
1439
1440 ```
1441 # sv.ld *RT,RA,*RB with Index REMAP applied to RB
1442 for i in 0..VL-1:
1443 if remap.indexed:
1444 rb_idx = indexed_remap(i) # remap
1445 else:
1446 rb_idx = i # use the index as-is
1447 EA = GPR(RA) + GPR(RB+rb_idx)
1448 GPR(RT+i) = MEM(EA, 8)
1449 ```
1450
1451 Thus it can be seen that the use of Indexed REMAP saves copying
1452 and manual reordering of the Vector of RB offsets.
1453
1454 ## LD/ST ffirst
1455
1456 LD/ST ffirst treats the first LD/ST in a vector (element 0 if REMAP
1457 is not active) as an ordinary one, with all behaviour with respect to
1458 Interrupts Exceptions Page Faults Memory Management being identical
1459 in every regard to Scalar v3.0 Power ISA LD/ST. However for elements
1460 1 and above, if an exception would occur, then VL is **truncated**
1461 to the previous element: the exception is **not** then raised because
1462 the LD/ST that would otherwise have caused an exception is *required*
1463 to be cancelled. Additionally an implementor may choose to truncate VL
1464 for any arbitrary reason *except for the very first*.
1465
1466 ffirst LD/ST to multiple pages via a Vectorised Index base is
1467 considered a security risk due to the abuse of probing multiple
1468 pages in rapid succession and getting speculative feedback on which
1469 pages would fail. Therefore Vector Indexed LD/ST is prohibited
1470 entirely, and the Mode bit instead used for element-strided LD/ST.
1471
1472 ```
1473 for(i = 0; i < VL; i++)
1474 reg[rt + i] = mem[reg[ra] + i * reg[rb]];
1475 ```
1476
1477 High security implementations where any kind of speculative probing of
1478 memory pages is considered a risk should take advantage of the fact
1479 that implementations may truncate VL at any point, without requiring
1480 software to be rewritten and made non-portable. Such implementations may
1481 choose to *always* set VL=1 which will have the effect of terminating
1482 any speculative probing (and also adversely affect performance), but
1483 will at least not require applications to be rewritten.
1484
1485 Low-performance simpler hardware implementations may also choose (always)
1486 to also set VL=1 as the bare minimum compliant implementation of LD/ST
1487 Fail-First. It is however critically important to remember that the first
1488 element LD/ST **MUST** be treated as an ordinary LD/ST, i.e. **MUST**
1489 raise exceptions exactly like an ordinary LD/ST.
1490
1491 For ffirst LD/STs, VL may be truncated arbitrarily to a nonzero value
1492 for any implementation-specific reason. For example: it is perfectly
1493 reasonable for implementations to alter VL when ffirst LD or ST operations
1494 are initiated on a nonaligned boundary, such that within a loop the
1495 subsequent iteration of that loop begins the following ffirst LD/ST
1496 operations on an aligned boundary such as the beginning of a cache line,
1497 or beginning of a Virtual Memory page. Likewise, to reduce workloads or
1498 balance resources.
1499
1500 Vertical-First Mode is slightly strange in that only one element at a time
1501 is ever executed anyway. Given that programmers may legitimately choose
1502 to alter srcstep and dststep in non-sequential order as part of explicit
1503 loops, it is neither possible nor safe to make speculative assumptions
1504 about future LD/STs. Therefore, Fail-First LD/ST in Vertical-First is
1505 `UNDEFINED`. This is very different from Arithmetic (Data-dependent)
1506 FFirst where Vertical-First Mode is fully deterministic, not speculative.
1507
1508 ## LOAD/STORE Elwidths <a name="elwidth"></a>
1509
1510 Loads and Stores are almost unique in that the Power Scalar ISA
1511 provides a width for the operation (lb, lh, lw, ld). Only `extsb` and
1512 others like it provide an explicit operation width. There are therefore
1513 *three* widths involved:
1514
1515 * operation width (lb=8, lh=16, lw=32, ld=64)
1516 * src element width override (8/16/32/default)
1517 * destination element width override (8/16/32/default)
1518
1519 Some care is therefore needed to express and make clear the transformations,
1520 which are expressly in this order:
1521
1522 * Calculate the Effective Address from RA at full width
1523 but (on Indexed Load) allow srcwidth overrides on RB
1524 * Load at the operation width (lb/lh/lw/ld) as usual
1525 * byte-reversal as usual
1526 * Non-saturated mode:
1527 - zero-extension or truncation from operation width to dest elwidth
1528 - place result in destination at dest elwidth
1529 * Saturated mode:
1530 - Sign-extension or truncation from operation width to dest width
1531 - signed/unsigned saturation down to dest elwidth
1532
1533 In order to respect Power v3.0B Scalar behaviour the memory side
1534 is treated effectively as completely separate and distinct from SV
1535 augmentation. This is primarily down to quirks surrounding LE/BE and
1536 byte-reversal.
1537
1538 It is rather unfortunately possible to request an elwidth override on
1539 the memory side which does not mesh with the overridden operation width:
1540 these result in `UNDEFINED` behaviour. The reason is that the effect
1541 of attempting a 64-bit `sv.ld` operation with a source elwidth override
1542 of 8/16/32 would result in overlapping memory requests, particularly
1543 on unit and element strided operations. Thus it is `UNDEFINED` when
1544 the elwidth is smaller than the memory operation width. Examples include
1545 `sv.lw/sw=16/els` which requests (overlapping) 4-byte memory reads offset
1546 from each other at 2-byte intervals. Store likewise is also `UNDEFINED`
1547 where the dest elwidth override is less than the operation width.
1548
1549 Note the following regarding the pseudocode to follow:
1550
1551 * `scalar identity behaviour` SV Context parameter conditions turn this
1552 into a straight absolute fully-compliant Scalar v3.0B LD operation
1553 * `brev` selects whether the operation is the byte-reversed variant (`ldbrx`
1554 rather than `ld`)
1555 * `op_width` specifies the operation width (`lb`, `lh`, `lw`, `ld`) as
1556 a "normal" part of Scalar v3.0B LD
1557 * `imm_offs` specifies the immediate offset `ld r3, imm_offs(r5)`, again
1558 as a "normal" part of Scalar v3.0B LD
1559 * `svctx` specifies the SV Context and includes VL as well as
1560 source and destination elwidth overrides.
1561
1562 Below is the pseudocode for Unit-Strided LD (which includes Vector
1563 capability). Observe in particular that RA, as the base address in both
1564 Immediate and Indexed LD/ST, does not have element-width overriding
1565 applied to it.
1566
1567 Note that predication, predication-zeroing, and other modes except
1568 saturation have all been removed, for clarity and simplicity:
1569
1570 ```
1571 # LD not VLD!
1572 # this covers unit stride mode and a type of vector offset
1573 function op_ld(RT, RA, op_width, imm_offs, svctx)
1574 for (int i = 0, int j = 0; i < svctx.VL && j < svctx.VL):
1575 if not svctx.unit/el-strided:
1576 # strange vector mode, compute 64 bit address which is
1577 # not polymorphic! elwidth hardcoded to 64 here
1578 srcbase = get_polymorphed_reg(RA, 64, i)
1579 else:
1580 # unit / element stride mode, compute 64 bit address
1581 srcbase = get_polymorphed_reg(RA, 64, 0)
1582 # adjust for unit/el-stride
1583 srcbase += ....
1584
1585 # read the underlying memory
1586 memread <= MEM(srcbase + imm_offs, op_width)
1587
1588 # check saturation.
1589 if svpctx.saturation_mode:
1590 # ... saturation adjustment...
1591 memread = clamp(memread, op_width, svctx.dest_elwidth)
1592 else:
1593 # truncate/extend to over-ridden dest width.
1594 memread = adjust_wid(memread, op_width, svctx.dest_elwidth)
1595
1596 # takes care of inserting memory-read (now correctly byteswapped)
1597 # into regfile underlying LE-defined order, into the right place
1598 # within the NEON-like register, respecting destination element
1599 # bitwidth, and the element index (j)
1600 set_polymorphed_reg(RT, svctx.dest_elwidth, j, memread)
1601
1602 # increments both src and dest element indices (no predication here)
1603 i++;
1604 j++;
1605 ```
1606
1607 Note above that the source elwidth is *not used at all* in LD-immediate.
1608
1609 For LD/Indexed, the key is that in the calculation of the Effective Address,
1610 RA has no elwidth override but RB does. Pseudocode below is simplified
1611 for clarity: predication and all modes except saturation are removed:
1612
1613 ```
1614 # LD not VLD! ld*rx if brev else ld*
1615 function op_ld(RT, RA, RB, op_width, svctx, brev)
1616 for (int i = 0, int j = 0; i < svctx.VL && j < svctx.VL):
1617 if not svctx.el-strided:
1618 # RA not polymorphic! elwidth hardcoded to 64 here
1619 srcbase = get_polymorphed_reg(RA, 64, i)
1620 else:
1621 # element stride mode, again RA not polymorphic
1622 srcbase = get_polymorphed_reg(RA, 64, 0)
1623 # RB *is* polymorphic
1624 offs = get_polymorphed_reg(RB, svctx.src_elwidth, i)
1625 # sign-extend
1626 if svctx.SEA: offs = sext(offs, svctx.src_elwidth, 64)
1627
1628 # takes care of (merges) processor LE/BE and ld/ldbrx
1629 bytereverse = brev XNOR MSR.LE
1630
1631 # read the underlying memory
1632 memread <= MEM(srcbase + offs, op_width)
1633
1634 # optionally performs byteswap at op width
1635 if (bytereverse):
1636 memread = byteswap(memread, op_width)
1637
1638 if svpctx.saturation_mode:
1639 # ... saturation adjustment...
1640 memread = clamp(memread, op_width, svctx.dest_elwidth)
1641 else:
1642 # truncate/extend to over-ridden dest width.
1643 memread = adjust_wid(memread, op_width, svctx.dest_elwidth)
1644
1645 # takes care of inserting memory-read (now correctly byteswapped)
1646 # into regfile underlying LE-defined order, into the right place
1647 # within the NEON-like register, respecting destination element
1648 # bitwidth, and the element index (j)
1649 set_polymorphed_reg(RT, svctx.dest_elwidth, j, memread)
1650
1651 # increments both src and dest element indices (no predication here)
1652 i++;
1653 j++;
1654 ```
1655
1656 ## Remapped LD/ST
1657
1658 In the [[sv/remap]] page the concept of "Remapping" is described. Whilst
1659 it is expensive to set up (2 64-bit opcodes minimum) it provides a way to
1660 arbitrarily perform 1D, 2D and 3D "remapping" of up to 64 elements worth
1661 of LDs or STs. The usual interest in such re-mapping is for example in
1662 separating out 24-bit RGB channel data into separate contiguous registers.
1663
1664 REMAP easily covers this capability, and with dest elwidth overrides
1665 and saturation may do so with built-in conversion that would normally
1666 require additional width-extension, sign-extension and min/max Vectorised
1667 instructions as post-processing stages.
1668
1669 Thus we do not need to provide specialist LD/ST "Structure Packed" opcodes
1670 because the generic abstracted concept of "Remapping", when applied to
1671 LD/ST, will give that same capability, with far more flexibility.
1672
1673 It is worth noting that Pack/Unpack Modes of SVSTATE, which may be
1674 established through `svstep`, are also an easy way to perform regular
1675 Structure Packing, at the vec2/vec3/vec4 granularity level. Beyond that,
1676 REMAP will need to be used.
1677
1678 --------
1679
1680 \newpage{}
1681
1682 # Condition Register SVP64 Operations
1683
1684 Condition Register Fields are only 4 bits wide: this presents some
1685 interesting conceptual challenges for SVP64, which was designed
1686 primarily for vectors of arithmetic and logical operations. However
1687 if predicates may be bits of CR Fields it makes sense to extend
1688 Simple-V to cover CR Operations, especially given that Vectorised Rc=1
1689 may be processed by Vectorised CR Operations tbat usefully in turn
1690 may become Predicate Masks to yet more Vector operations, like so:
1691
1692 ```
1693 sv.cmpi/ew=8 *B,*ra,0 # compare bytes against zero
1694 sv.cmpi/ew=8 *B2,*ra,13. # and against newline
1695 sv.cror PM.EQ,B.EQ,B2.EQ # OR compares to create mask
1696 sv.stb/sm=EQ ... # store only nonzero/newline
1697 ```
1698
1699 Element width however is clearly meaningless for a 4-bit collation of
1700 Conditions, EQ LT GE SO. Likewise, arithmetic saturation (an important
1701 part of Arithmetic SVP64) has no meaning. An alternative Mode Format is
1702 required, and given that elwidths are meaningless for CR Fields the bits
1703 in SVP64 `RM` may be used for other purposes.
1704
1705 This alternative mapping **only** applies to instructions that **only**
1706 reference a CR Field or CR bit as the sole exclusive result. This section
1707 **does not** apply to instructions which primarily produce arithmetic
1708 results that also, as an aside, produce a corresponding CR Field (such as
1709 when Rc=1). Instructions that involve Rc=1 are definitively arithmetic
1710 in nature, where the corresponding Condition Register Field can be
1711 considered to be a "co-result". Such CR Field "co-result" arithmeric
1712 operations are firmly out of scope for this section, being covered fully
1713 by [[sv/normal]].
1714
1715 * Examples of v3.0B instructions to which this section does
1716 apply is
1717 - `mfcr` and `cmpi` (3 bit operands) and
1718 - `crnor` and `crand` (5 bit operands).
1719 * Examples to which this section does **not** apply include
1720 `fadds.` and `subf.` which both produce arithmetic results
1721 (and a CR Field co-result).
1722
1723 The CR Mode Format still applies to `sv.cmpi` because despite
1724 taking a GPR as input, the output from the Base Scalar v3.0B `cmpi`
1725 instruction is purely to a Condition Register Field.
1726
1727 Other modes are still applicable and include:
1728
1729 * **Data-dependent fail-first**.
1730 useful to truncate VL based on analysis of a Condition Register result bit.
1731 * **Reduction**.
1732 Reduction is useful for analysing a Vector of Condition Register Fields
1733 and reducing it to one single Condition Register Field.
1734
1735 Predicate-result does not make any sense because when Rc=1 a co-result
1736 is created (a CR Field). Testing the co-result allows the decision to
1737 be made to store or not store the main result, and for CR Ops the CR
1738 Field result *is* the main result.
1739
1740 ## Format
1741
1742 SVP64 RM `MODE` (includes `ELWIDTH_SRC` bits) for CR-based operations:
1743
1744 |6 | 7 |19-20| 21 | 22 23 | description |
1745 |--|---|-----| --- |---------|----------------- |
1746 |/ | / |0 RG | 0 | dz sz | simple mode |
1747 |/ | / |0 RG | 1 | dz sz | scalar reduce mode (mapreduce) |
1748 |zz|SNZ|1 VLI| inv | CR-bit | Ffirst 3-bit mode |
1749 |/ |SNZ|1 VLI| inv | dz sz | Ffirst 5-bit mode (implies CR-bit from result) |
1750
1751 Fields:
1752
1753 * **sz / dz** if predication is enabled will put zeros into the dest
1754 (or as src in the case of twin pred) when the predicate bit is zero.
1755 otherwise the element is ignored or skipped, depending on context.
1756 * **zz** set both sz and dz equal to this flag
1757 * **SNZ** In fail-first mode, on the bit being tested, when sz=1 and
1758 SNZ=1 a value "1" is put in place of "0".
1759 * **inv CR-bit** just as in branches (BO) these bits allow testing of
1760 a CR bit and whether it is set (inv=0) or unset (inv=1)
1761 * **RG** inverts the Vector Loop order (VL-1 downto 0) rather
1762 than the normal 0..VL-1
1763 * **SVM** sets "subvector" reduce mode
1764 * **VLi** VL inclusive: in fail-first mode, the truncation of
1765 VL *includes* the current element at the failure point rather
1766 than excludes it from the count.
1767
1768 ## Data-dependent fail-first on CR operations
1769
1770 The principle of data-dependent fail-first is that if, during the course
1771 of sequentially evaluating an element's Condition Test, one such test
1772 is encountered which fails, then VL (Vector Length) is truncated (set)
1773 at that point. In the case of Arithmetic SVP64 Operations the Condition
1774 Register Field generated from Rc=1 is used as the basis for the truncation
1775 decision. However with CR-based operations that CR Field result to be
1776 tested is provided *by the operation itself*.
1777
1778 Data-dependent SVP64 Vectorised Operations involving the creation
1779 or modification of a CR can require an extra two bits, which are not
1780 available in the compact space of the SVP64 RM `MODE` Field. With the
1781 concept of element width overrides being meaningless for CR Fields it
1782 is possible to use the `ELWIDTH` field for alternative purposes.
1783
1784 Condition Register based operations such as `sv.mfcr` and `sv.crand`
1785 can thus be made more flexible. However the rules that apply in this
1786 section also apply to future CR-based instructions.
1787
1788 There are two primary different types of CR operations:
1789
1790 * Those which have a 3-bit operand field (referring to a CR Field)
1791 * Those which have a 5-bit operand (referring to a bit within the
1792 whole 32-bit CR)
1793
1794 Examining these two types it is observed that the difference may
1795 be considered to be that the 5-bit variant *already* provides the
1796 prerequisite information about which CR Field bit (EQ, GE, LT, SO) is
1797 to be operated on by the instruction. Thus, logically, we may set the
1798 following rule:
1799
1800 * When a 5-bit CR Result field is used in an instruction, the
1801 5-bit variant of Data-Dependent Fail-First
1802 must be used. i.e. the bit of the CR field to be tested is
1803 the one that has just been modified (created) by the operation.
1804 * When a 3-bit CR Result field is used the 3-bit variant
1805 must be used, providing as it does the missing `CRbit` field
1806 in order to select which CR Field bit of the result shall
1807 be tested (EQ, LE, GE, SO)
1808
1809 The reason why the 3-bit CR variant needs the additional CR-bit field
1810 should be obvious from the fact that the 3-bit CR Field from the base
1811 Power ISA v3.0B operation clearly does not contain and is missing the
1812 two CR Field Selector bits. Thus, these two bits (to select EQ, LE,
1813 GE or SO) must be provided in another way.
1814
1815 Examples of the former type:
1816
1817 * crand, cror, crnor. These all are 5-bit (BA, BB, BT). The bit
1818 to be tested against `inv` is the one selected by `BT`
1819 * mcrf. This has only 3-bit (BF, BFA). In order to select the
1820 bit to be tested, the alternative encoding must be used.
1821 With `CRbit` coming from the SVP64 RM bits 22-23 the bit
1822 of BF to be tested is identified.
1823
1824 Just as with SVP64 [[sv/branches]] there is the option to truncate
1825 VL to include the element being tested (`VLi=1`) and to exclude it
1826 (`VLi=0`).
1827
1828 Also exactly as with [[sv/normal]] fail-first, VL cannot, unlike
1829 [[sv/ldst]], be set to an arbitrary value. Deterministic behaviour
1830 is *required*.
1831
1832 ## Reduction and Iteration
1833
1834 Bearing in mind as described in the svp64 Appendix, SVP64 Horizontal
1835 Reduction is a deterministic schedule on top of base Scalar v3.0
1836 operations, the same rules apply to CR Operations, i.e. that programmers
1837 must follow certain conventions in order for an *end result* of a
1838 reduction to be achieved. Unlike other Vector ISAs *there are no explicit
1839 reduction opcodes* in SVP64: Schedules however achieve the same effect.
1840
1841 Due to these conventions only reduction on operations such as `crand`
1842 and `cror` are meaningful because these have Condition Register Fields
1843 as both input and output. Meaningless operations are not prohibited
1844 because the cost in hardware of doing so is prohibitive, but neither
1845 are they `UNDEFINED`. Implementations are still required to execute them
1846 but are at liberty to optimise out any operations that would ultimately
1847 be overwritten, as long as Strict Program Order is still obvservable by
1848 the programmer.
1849
1850 Also bear in mind that 'Reverse Gear' may be enabled, which can be
1851 used in combination with overlapping CR operations to iteratively
1852 accumulate results. Issuing a `sv.crand` operation for example with
1853 `BA` differing from `BB` by one Condition Register Field would result
1854 in a cascade effect, where the first-encountered CR Field would set the
1855 result to zero, and also all subsequent CR Field elements thereafter:
1856
1857 ```
1858 # sv.crand/mr/rg CR4.ge.v, CR5.ge.v, CR4.ge.v
1859 for i in VL-1 downto 0 # reverse gear
1860 CR.field[4+i].ge &= CR.field[5+i].ge
1861 ```
1862
1863 `sv.crxor` with reduction would be particularly useful for parity
1864 calculation for example, although there are many ways in which the same
1865 calculation could be carried out after transferring a vector of CR Fields
1866 to a GPR using crweird operations.
1867
1868 Implementations are free and clear to optimise these reductions in any way
1869 they see fit, as long as the end-result is compatible with Strict Program
1870 Order being observed, and Interrupt latency is not adversely impacted.
1871
1872 ## Unusual and quirky CR operations
1873
1874 **cmp and other compare ops**
1875
1876 `cmp` and `cmpi` etc take GPRs as sources and create a CR Field as a result.
1877
1878 cmpli BF,L,RA,UI
1879 cmpeqb BF,RA,RB
1880
1881 With `ELWIDTH` applying to the source GPR operands this is perfectly fine.
1882
1883 **crweird operations**
1884
1885 There are 4 weird CR-GPR operations and one reasonable one in
1886 the [[cr_int_predication]] set:
1887
1888 * crrweird
1889 * mtcrweird
1890 * crweirder
1891 * crweird
1892 * mcrfm - reasonably normal and referring to CR Fields for src and dest.
1893
1894 The "weird" operations have a non-standard behaviour, being able to
1895 treat *individual bits* of a GPR effectively as elements. They are
1896 expected to be Micro-coded by most Hardware implementations.
1897
1898
1899 --------
1900
1901 \newpage{}
1902
1903 # SVP64 Branch Conditional behaviour
1904
1905 Please note: although similar, SVP64 Branch instructions should be
1906 considered completely separate and distinct from standard scalar
1907 OpenPOWER-approved v3.0B branches. **v3.0B branches are in no way
1908 impacted, altered, changed or modified in any way, shape or form by the
1909 SVP64 Vectorised Variants**.
1910
1911 It is also extremely important to note that Branches are the sole
1912 pseudo-exception in SVP64 to `Scalar Identity Behaviour`. SVP64 Branches
1913 contain additional modes that are useful for scalar operations (i.e. even
1914 when VL=1 or when using single-bit predication).
1915
1916 **Rationale**
1917
1918 Scalar 3.0B Branch Conditional operations, `bc`, `bctar` etc. test
1919 a Condition Register. However for parallel processing it is simply
1920 impossible to perform multiple independent branches: the Program
1921 Counter simply cannot branch to multiple destinations based on multiple
1922 conditions. The best that can be done is to test multiple Conditions
1923 and make a decision of a *single* branch, based on analysis of a *Vector*
1924 of CR Fields which have just been calculated from a *Vector* of results.
1925
1926 In 3D Shader binaries, which are inherently parallelised and predicated,
1927 testing all or some results and branching based on multiple tests is
1928 extremely common, and a fundamental part of Shader Compilers. Example:
1929 without such multi-condition test-and-branch, if a predicate mask is
1930 all zeros a large batch of instructions may be masked out to `nop`,
1931 and it would waste CPU cycles to run them. 3D GPU ISAs can test for
1932 this scenario and, with the appropriate predicate-analysis instruction,
1933 jump over fully-masked-out operations, by spotting that *all* Conditions
1934 are false.
1935
1936 Unless Branches are aware and capable of such analysis, additional
1937 instructions would be required which perform Horizontal Cumulative
1938 analysis of Vectorised Condition Register Fields, in order to reduce
1939 the Vector of CR Fields down to one single yes or no decision that a
1940 Scalar-only v3.0B Branch-Conditional could cope with. Such instructions
1941 would be unavoidable, required, and costly by comparison to a single
1942 Vector-aware Branch. Therefore, in order to be commercially competitive,
1943 `sv.bc` and other Vector-aware Branch Conditional instructions are a
1944 high priority for 3D GPU (and OpenCL-style) workloads.
1945
1946 Given that Power ISA v3.0B is already quite powerful, particularly
1947 the Condition Registers and their interaction with Branches, there are
1948 opportunities to create extremely flexible and compact Vectorised Branch
1949 behaviour. In addition, the side-effects (updating of CTR, truncation
1950 of VL, described below) make it a useful instruction even if the branch
1951 points to the next instruction (no actual branch).
1952
1953 ## Overview
1954
1955 When considering an "array" of branch-tests, there are four
1956 primarily-useful modes: AND, OR, NAND and NOR of all Conditions.
1957 NAND and NOR may be synthesised from AND and OR by inverting `BO[1]`
1958 which just leaves two modes:
1959
1960 * Branch takes place on the **first** CR Field test to succeed
1961 (a Great Big OR of all condition tests). Exit occurs
1962 on the first **successful** test.
1963 * Branch takes place only if **all** CR field tests succeed:
1964 a Great Big AND of all condition tests. Exit occurs
1965 on the first **failed** test.
1966
1967 Early-exit is enacted such that the Vectorised Branch does not
1968 perform needless extra tests, which will help reduce reads on
1969 the Condition Register file.
1970
1971 *Note: Early-exit is **MANDATORY** (required) behaviour. Branches
1972 **MUST** exit at the first sequentially-encountered failure point,
1973 for exactly the same reasons for which it is mandatory in programming
1974 languages doing early-exit: to avoid damaging side-effects and to provide
1975 deterministic behaviour. Speculative testing of Condition Register
1976 Fields is permitted, as is speculative calculation of CTR, as long as,
1977 as usual in any Out-of-Order microarchitecture, that speculative testing
1978 is cancelled should an early-exit occur. i.e. the speculation must be
1979 "precise": Program Order must be preserved*
1980
1981 Also note that when early-exit occurs in Horizontal-first Mode, srcstep,
1982 dststep etc. are all reset, ready to begin looping from the beginning
1983 for the next instruction. However for Vertical-first Mode srcstep
1984 etc. are incremented "as usual" i.e. an early-exit has no special impact,
1985 regardless of whether the branch occurred or not. This can leave srcstep
1986 etc. in what may be considered an unusual state on exit from a loop and
1987 it is up to the programmer to reset srcstep, dststep etc. to known-good
1988 values *(easily achieved with `setvl`)*.
1989
1990 Additional useful behaviour involves two primary Modes (both of which
1991 may be enabled and combined):
1992
1993 * **VLSET Mode**: identical to Data-Dependent Fail-First Mode
1994 for Arithmetic SVP64 operations, with more
1995 flexibility and a close interaction and integration into the
1996 underlying base Scalar v3.0B Branch instruction.
1997 Truncation of VL takes place around the early-exit point.
1998 * **CTR-test Mode**: gives much more flexibility over when and why
1999 CTR is decremented, including options to decrement if a Condition
2000 test succeeds *or if it fails*.
2001
2002 With these side-effects, basic Boolean Logic Analysis advises that it
2003 is important to provide a means to enact them each based on whether
2004 testing succeeds *or fails*. This results in a not-insignificant number
2005 of additional Mode Augmentation bits, accompanying VLSET and CTR-test
2006 Modes respectively.
2007
2008 Predicate skipping or zeroing may, as usual with SVP64, be controlled by
2009 `sz`. Where the predicate is masked out and zeroing is enabled, then in
2010 such circumstances the same Boolean Logic Analysis dictates that rather
2011 than testing only against zero, the option to test against one is also
2012 prudent. This introduces a new immediate field, `SNZ`, which works in
2013 conjunction with `sz`.
2014
2015 Vectorised Branches can be used in either SVP64 Horizontal-First or
2016 Vertical-First Mode. Essentially, at an element level, the behaviour
2017 is identical in both Modes, although the `ALL` bit is meaningless in
2018 Vertical-First Mode.
2019
2020 It is also important to bear in mind that, fundamentally, Vectorised
2021 Branch-Conditional is still extremely close to the Scalar v3.0B
2022 Branch-Conditional instructions, and that the same v3.0B Scalar
2023 Branch-Conditional instructions are still *completely separate and
2024 independent*, being unaltered and unaffected by their SVP64 variants in
2025 every conceivable way.
2026
2027 *Programming note: One important point is that SVP64 instructions are
2028 64 bit. (8 bytes not 4). This needs to be taken into consideration
2029 when computing branch offsets: the offset is relative to the start of
2030 the instruction, which **includes** the SVP64 Prefix*
2031
2032 ## Format and fields
2033
2034 With element-width overrides being meaningless for Condition Register
2035 Fields, bits 4 thru 7 of SVP64 RM may be used for additional Mode bits.
2036
2037 SVP64 RM `MODE` (includes repurposing `ELWIDTH` bits 4:5, and
2038 `ELWIDTH_SRC` bits 6-7 for *alternate* uses) for Branch Conditional:
2039
2040 | 4 | 5 | 6 | 7 | 17 | 18 | 19 | 20 | 21 | 22 23 | description |
2041 | - | - | - | - | -- | -- | -- | -- | --- |--------|----------------- |
2042 |ALL|SNZ| / | / | SL |SLu | 0 | 0 | / | LRu sz | simple mode |
2043 |ALL|SNZ| / |VSb| SL |SLu | 0 | 1 | VLI | LRu sz | VLSET mode |
2044 |ALL|SNZ|CTi| / | SL |SLu | 1 | 0 | / | LRu sz | CTR-test mode |
2045 |ALL|SNZ|CTi|VSb| SL |SLu | 1 | 1 | VLI | LRu sz | CTR-test+VLSET mode |
2046
2047 Brief description of fields:
2048
2049 * **sz=1** if predication is enabled and `sz=1` and a predicate
2050 element bit is zero, `SNZ` will
2051 be substituted in place of the CR bit selected by `BI`,
2052 as the Condition tested.
2053 Contrast this with
2054 normal SVP64 `sz=1` behaviour, where *only* a zero is put in
2055 place of masked-out predicate bits.
2056 * **sz=0** When `sz=0` skipping occurs as usual on
2057 masked-out elements, but unlike all
2058 other SVP64 behaviour which entirely skips an element with
2059 no related side-effects at all, there are certain
2060 special circumstances where CTR
2061 may be decremented. See CTR-test Mode, below.
2062 * **ALL** when set, all branch conditional tests must pass in order for
2063 the branch to succeed. When clear, it is the first sequentially
2064 encountered successful test that causes the branch to succeed.
2065 This is identical behaviour to how programming languages perform
2066 early-exit on Boolean Logic chains.
2067 * **VLI** VLSET is identical to Data-dependent Fail-First mode.
2068 In VLSET mode, VL *may* (depending on `VSb`) be truncated.
2069 If VLI (Vector Length Inclusive) is clear,
2070 VL is truncated to *exclude* the current element, otherwise it is
2071 included. SVSTATE.MVL is not altered: only VL.
2072 * **SL** identical to `LR` except applicable to SVSTATE. If `SL`
2073 is set, SVSTATE is transferred to SVLR (conditionally on
2074 whether `SLu` is set).
2075 * **SLu**: SVSTATE Link Update, like `LRu` except applies to SVSTATE.
2076 * **LRu**: Link Register Update, used in conjunction with LK=1
2077 to make LR update conditional
2078 * **VSb** In VLSET Mode, after testing,
2079 if VSb is set, VL is truncated if the test succeeds. If VSb is clear,
2080 VL is truncated if a test *fails*. Masked-out (skipped)
2081 bits are not considered
2082 part of testing when `sz=0`
2083 * **CTi** CTR inversion. CTR-test Mode normally decrements per element
2084 tested. CTR inversion decrements if a test *fails*. Only relevant
2085 in CTR-test Mode.
2086
2087 LRu and CTR-test modes are where SVP64 Branches subtly differ from
2088 Scalar v3.0B Branches. `sv.bcl` for example will always update LR,
2089 whereas `sv.bcl/lru` will only update LR if the branch succeeds.
2090
2091 Of special interest is that when using ALL Mode (Great Big AND of all
2092 Condition Tests), if `VL=0`, which is rare but can occur in Data-Dependent
2093 Modes, the Branch will always take place because there will be no failing
2094 Condition Tests to prevent it. Likewise when not using ALL Mode (Great
2095 Big OR of all Condition Tests) and `VL=0` the Branch is guaranteed not
2096 to occur because there will be no *successful* Condition Tests to make
2097 it happen.
2098
2099 ## Vectorised CR Field numbering, and Scalar behaviour
2100
2101 It is important to keep in mind that just like all SVP64 instructions,
2102 the `BI` field of the base v3.0B Branch Conditional instruction may be
2103 extended by SVP64 EXTRA augmentation, as well as be marked as either
2104 Scalar or Vector. It is also crucially important to keep in mind that for
2105 CRs, SVP64 sequentially increments the CR *Field* numbers. CR *Fields*
2106 are treated as elements, not bit-numbers of the CR *register*.
2107
2108 The `BI` operand of Branch Conditional operations is five bits, in scalar
2109 v3.0B this would select one bit of the 32 bit CR, comprising eight CR
2110 Fields of 4 bits each. In SVP64 there are 16 32 bit CRs, containing
2111 128 4-bit CR Fields. Therefore, the 2 LSBs of `BI` select the bit from
2112 the CR Field (EQ LT GT SO), and the top 3 bits are extended to either
2113 scalar or vector and to select CR Fields 0..127 as specified in SVP64
2114 [[sv/svp64/appendix]].
2115
2116 When the CR Fields selected by SVP64-Augmented `BI` is marked as scalar,
2117 then as the usual SVP64 rules apply: the Vector loop ends at the first
2118 element tested (the first CR *Field*), after taking predication into
2119 consideration. Thus, also as usual, when a predicate mask is given, and
2120 `BI` marked as scalar, and `sz` is zero, srcstep skips forward to the
2121 first non-zero predicated element, and only that one element is tested.
2122
2123 In other words, the fact that this is a Branch Operation (instead of an
2124 arithmetic one) does not result, ultimately, in significant changes as
2125 to how SVP64 is fundamentally applied, except with respect to:
2126
2127 * the unique properties associated with conditionally
2128 changing the Program Counter (aka "a Branch"), resulting in early-out
2129 opportunities
2130 * CTR-testing
2131
2132 Both are outlined below, in later sections.
2133
2134 ## Horizontal-First and Vertical-First Modes
2135
2136 In SVP64 Horizontal-First Mode, the first failure in ALL mode (Great Big
2137 AND) results in early exit: no more updates to CTR occur (if requested);
2138 no branch occurs, and LR is not updated (if requested). Likewise for
2139 non-ALL mode (Great Big Or) on first success early exit also occurs,
2140 however this time with the Branch proceeding. In both cases the testing
2141 of the Vector of CRs should be done in linear sequential order (or in
2142 REMAP re-sequenced order): such that tests that are sequentially beyond
2143 the exit point are *not* carried out. (*Note: it is standard practice
2144 in Programming languages to exit early from conditional tests, however a
2145 little unusual to consider in an ISA that is designed for Parallel Vector
2146 Processing. The reason is to have strictly-defined guaranteed behaviour*)
2147
2148 In Vertical-First Mode, setting the `ALL` bit results in `UNDEFINED`
2149 behaviour. Given that only one element is being tested at a time in
2150 Vertical-First Mode, a test designed to be done on multiple bits is
2151 meaningless.
2152
2153 ## Description and Modes
2154
2155 Predication in both INT and CR modes may be applied to `sv.bc` and other
2156 SVP64 Branch Conditional operations, exactly as they may be applied to
2157 other SVP64 operations. When `sz` is zero, any masked-out Branch-element
2158 operations are not included in condition testing, exactly like all other
2159 SVP64 operations, *including* side-effects such as potentially updating
2160 LR or CTR, which will also be skipped. There is *one* exception here,
2161 which is when `BO[2]=0, sz=0, CTR-test=0, CTi=1` and the relevant element
2162 predicate mask bit is also zero: under these special circumstances CTR
2163 will also decrement.
2164
2165 When `sz` is non-zero, this normally requests insertion of a zero in
2166 place of the input data, when the relevant predicate mask bit is zero.
2167 This would mean that a zero is inserted in place of `CR[BI+32]` for
2168 testing against `BO`, which may not be desirable in all circumstances.
2169 Therefore, an extra field is provided `SNZ`, which, if set, will insert
2170 a **one** in place of a masked-out element, instead of a zero.
2171
2172 (*Note: Both options are provided because it is useful to deliberately
2173 cause the Branch-Conditional Vector testing to fail at a specific point,
2174 controlled by the Predicate mask. This is particularly useful in `VLSET`
2175 mode, which will truncate SVSTATE.VL at the point of the first failed
2176 test.*)
2177
2178 Normally, CTR mode will decrement once per Condition Test, resulting under
2179 normal circumstances that CTR reduces by up to VL in Horizontal-First
2180 Mode. Just as when v3.0B Branch-Conditional saves at least one instruction
2181 on tight inner loops through auto-decrementation of CTR, likewise it
2182 is also possible to save instruction count for SVP64 loops in both
2183 Vertical-First and Horizontal-First Mode, particularly in circumstances
2184 where there is conditional interaction between the element computation
2185 and testing, and the continuation (or otherwise) of a given loop. The
2186 potential combinations of interactions is why CTR testing options have
2187 been added.
2188
2189 Also, the unconditional bit `BO[0]` is still relevant when Predication
2190 is applied to the Branch because in `ALL` mode all nonmasked bits have
2191 to be tested, and when `sz=0` skipping occurs. Even when VLSET mode is
2192 not used, CTR may still be decremented by the total number of nonmasked
2193 elements, acting in effect as either a popcount or cntlz depending
2194 on which mode bits are set. In short, Vectorised Branch becomes an
2195 extremely powerful tool.
2196
2197 **Micro-Architectural Implementation Note**: *when implemented on top
2198 of a Multi-Issue Out-of-Order Engine it is possible to pass a copy of
2199 the predicate and the prerequisite CR Fields to all Branch Units, as
2200 well as the current value of CTR at the time of multi-issue, and for
2201 each Branch Unit to compute how many times CTR would be subtracted,
2202 in a fully-deterministic and parallel fashion. A SIMD-based Branch
2203 Unit, receiving and processing multiple CR Fields covered by multiple
2204 predicate bits, would do the exact same thing. Obviously, however, if
2205 CTR is modified within any given loop (mtctr) the behaviour of CTR is
2206 no longer deterministic.*
2207
2208 ### Link Register Update
2209
2210 For a Scalar Branch, unconditional updating of the Link Register LR
2211 is useful and practical. However, if a loop of CR Fields is tested,
2212 unconditional updating of LR becomes problematic.
2213
2214 For example when using `bclr` with `LRu=1,LK=0` in Horizontal-First Mode,
2215 LR's value will be unconditionally overwritten after the first element,
2216 such that for execution (testing) of the second element, LR has the value
2217 `CIA+8`. This is covered in the `bclrl` example, in a later section.
2218
2219 The addition of a LRu bit modifies behaviour in conjunction with LK,
2220 as follows:
2221
2222 * `sv.bc` When LRu=0,LK=0, Link Register is not updated
2223 * `sv.bcl` When LRu=0,LK=1, Link Register is updated unconditionally
2224 * `sv.bcl/lru` When LRu=1,LK=1, Link Register will
2225 only be updated if the Branch Condition fails.
2226 * `sv.bc/lru` When LRu=1,LK=0, Link Register will only be updated if
2227 the Branch Condition succeeds.
2228
2229 This avoids destruction of LR during loops (particularly Vertical-First
2230 ones).
2231
2232 **SVLR and SVSTATE**
2233
2234 For precisely the reasons why `LK=1` was added originally to the Power
2235 ISA, with SVSTATE being a peer of the Program Counter it becomes necessary
2236 to also add an SVLR (SVSTATE Link Register) and corresponding control bits
2237 `SL` and `SLu`.
2238
2239 ### CTR-test
2240
2241 Where a standard Scalar v3.0B branch unconditionally decrements CTR when
2242 `BO[2]` is clear, CTR-test Mode introduces more flexibility which allows
2243 CTR to be used for many more types of Vector loops constructs.
2244
2245 CTR-test mode and CTi interaction is as follows: note that `BO[2]`
2246 is still required to be clear for CTR decrements to be considered,
2247 exactly as is the case in Scalar Power ISA v3.0B
2248
2249 * **CTR-test=0, CTi=0**: CTR decrements on a per-element basis
2250 if `BO[2]` is zero. Masked-out elements when `sz=0` are
2251 skipped (i.e. CTR is *not* decremented when the predicate
2252 bit is zero and `sz=0`).
2253 * **CTR-test=0, CTi=1**: CTR decrements on a per-element basis
2254 if `BO[2]` is zero and a masked-out element is skipped
2255 (`sz=0` and predicate bit is zero). This one special case is the
2256 **opposite** of other combinations, as well as being
2257 completely different from normal SVP64 `sz=0` behaviour)
2258 * **CTR-test=1, CTi=0**: CTR decrements on a per-element basis
2259 if `BO[2]` is zero and the Condition Test succeeds.
2260 Masked-out elements when `sz=0` are skipped (including
2261 not decrementing CTR)
2262 * **CTR-test=1, CTi=1**: CTR decrements on a per-element basis
2263 if `BO[2]` is zero and the Condition Test *fails*.
2264 Masked-out elements when `sz=0` are skipped (including
2265 not decrementing CTR)
2266
2267 `CTR-test=0, CTi=1, sz=0` requires special emphasis because it is the
2268 only time in the entirety of SVP64 that has side-effects when
2269 a predicate mask bit is clear. **All** other SVP64 operations
2270 entirely skip an element when sz=0 and a predicate mask bit is zero.
2271 It is also critical to emphasise that in this unusual mode,
2272 no other side-effects occur: **only** CTR is decremented, i.e. the
2273 rest of the Branch operation is skipped.
2274
2275 ### VLSET Mode
2276
2277 VLSET Mode truncates the Vector Length so that subsequent instructions
2278 operate on a reduced Vector Length. This is similar to Data-dependent
2279 Fail-First and LD/ST Fail-First, where for VLSET the truncation occurs
2280 at the Branch decision-point.
2281
2282 Interestingly, due to the side-effects of `VLSET` mode it is actually
2283 useful to use Branch Conditional even to perform no actual branch
2284 operation, i.e to point to the instruction after the branch. Truncation of
2285 VL would thus conditionally occur yet control flow alteration would not.
2286
2287 `VLSET` mode with Vertical-First is particularly unusual. Vertical-First
2288 is designed to be used for explicit looping, where an explicit call to
2289 `svstep` is required to move both srcstep and dststep on to the next
2290 element, until VL (or other condition) is reached. Vertical-First Looping
2291 is expected (required) to terminate if the end of the Vector, VL, is
2292 reached. If however that loop is terminated early because VL is truncated,
2293 VLSET with Vertical-First becomes meaningless. Resolving this would
2294 require two branches: one Conditional, the other branching unconditionally
2295 to create the loop, where the Conditional one jumps over it.
2296
2297 Therefore, with `VSb`, the option to decide whether truncation should
2298 occur if the branch succeeds *or* if the branch condition fails allows
2299 for the flexibility required. This allows a Vertical-First Branch to
2300 *either* be used as a branch-back (loop) *or* as part of a conditional
2301 exit or function call from *inside* a loop, and for VLSET to be integrated
2302 into both types of decision-making.
2303
2304 In the case of a Vertical-First branch-back (loop), with `VSb=0` the
2305 branch takes place if success conditions are met, but on exit from that
2306 loop (branch condition fails), VL will be truncated. This is extremely
2307 useful.
2308
2309 `VLSET` mode with Horizontal-First when `VSb=0` is still useful, because
2310 it can be used to truncate VL to the first predicated (non-masked-out)
2311 element.
2312
2313 The truncation point for VL, when VLi is clear, must not include skipped
2314 elements that preceded the current element being tested. Example:
2315 `sz=0, VLi=0, predicate mask = 0b110010` and the Condition Register
2316 failure point is at CR Field element 4.
2317
2318 * Testing at element 0 is skipped because its predicate bit is zero
2319 * Testing at element 1 passed
2320 * Testing elements 2 and 3 are skipped because their
2321 respective predicate mask bits are zero
2322 * Testing element 4 fails therefore VL is truncated to **2**
2323 not 4 due to elements 2 and 3 being skipped.
2324
2325 If `sz=1` in the above example *then* VL would have been set to 4 because
2326 in non-zeroing mode the zero'd elements are still effectively part of the
2327 Vector (with their respective elements set to `SNZ`)
2328
2329 If `VLI=1` then VL would be set to 5 regardless of sz, due to being inclusive
2330 of the element actually being tested.
2331
2332 ### VLSET and CTR-test combined
2333
2334 If both CTR-test and VLSET Modes are requested, it is important to
2335 observe the correct order. What occurs depends on whether VLi is enabled,
2336 because VLi affects the length, VL.
2337
2338 If VLi (VL truncate inclusive) is set:
2339
2340 1. compute the test including whether CTR triggers
2341 2. (optionally) decrement CTR
2342 3. (optionally) truncate VL (VSb inverts the decision)
2343 4. decide (based on step 1) whether to terminate looping
2344 (including not executing step 5)
2345 5. decide whether to branch.
2346
2347 If VLi is clear, then when a test fails that element
2348 and any following it
2349 should **not** be considered part of the Vector. Consequently:
2350
2351 1. compute the branch test including whether CTR triggers
2352 2. if the test fails against VSb, truncate VL to the *previous*
2353 element, and terminate looping. No further steps executed.
2354 3. (optionally) decrement CTR
2355 4. decide whether to branch.
2356
2357 ## Boolean Logic combinations
2358
2359 In a Scalar ISA, Branch-Conditional testing even of vector results may be
2360 performed through inversion of tests. NOR of all tests may be performed
2361 by inversion of the scalar condition and branching *out* from the scalar
2362 loop around elements, using scalar operations.
2363
2364 In a parallel (Vector) ISA it is the ISA itself which must perform
2365 the prerequisite logic manipulation. Thus for SVP64 there are an
2366 extraordinary number of nesessary combinations which provide completely
2367 different and useful behaviour. Available options to combine:
2368
2369 * `BO[0]` to make an unconditional branch would seem irrelevant if
2370 it were not for predication and for side-effects (CTR Mode
2371 for example)
2372 * Enabling CTR-test Mode and setting `BO[2]` can still result in the
2373 Branch
2374 taking place, not because the Condition Test itself failed, but
2375 because CTR reached zero **because**, as required by CTR-test mode,
2376 CTR was decremented as a **result** of Condition Tests failing.
2377 * `BO[1]` to select whether the CR bit being tested is zero or nonzero
2378 * `R30` and `~R30` and other predicate mask options including CR and
2379 inverted CR bit testing
2380 * `sz` and `SNZ` to insert either zeros or ones in place of masked-out
2381 predicate bits
2382 * `ALL` or `ANY` behaviour corresponding to `AND` of all tests and
2383 `OR` of all tests, respectively.
2384 * Predicate Mask bits, which combine in effect with the CR being
2385 tested.
2386 * Inversion of Predicate Masks (`~r3` instead of `r3`, or using
2387 `NE` rather than `EQ`) which results in an additional
2388 level of possible ANDing, ORing etc. that would otherwise
2389 need explicit instructions.
2390
2391 The most obviously useful combinations here are to set `BO[1]` to zero
2392 in order to turn `ALL` into Great-Big-NAND and `ANY` into Great-Big-NOR.
2393 Other Mode bits which perform behavioural inversion then have to work
2394 round the fact that the Condition Testing is NOR or NAND. The alternative
2395 to not having additional behavioural inversion (`SNZ`, `VSb`, `CTi`)
2396 would be to have a second (unconditional) branch directly after the first,
2397 which the first branch jumps over. This contrivance is avoided by the
2398 behavioural inversion bits.
2399
2400 ## Pseudocode and examples
2401
2402 Please see the SVP64 appendix regarding CR bit ordering and for
2403 the definition of `CR{n}`
2404
2405 For comparative purposes this is a copy of the v3.0B `bc` pseudocode
2406
2407 ```
2408 if (mode_is_64bit) then M <- 0
2409 else M <- 32
2410 if ¬BO[2] then CTR <- CTR - 1
2411 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2412 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2413 if ctr_ok & cond_ok then
2414 if AA then NIA <-iea EXTS(BD || 0b00)
2415 else NIA <-iea CIA + EXTS(BD || 0b00)
2416 if LK then LR <-iea CIA + 4
2417 ```
2418
2419 Simplified pseudocode including LRu and CTR skipping, which illustrates
2420 clearly that SVP64 Scalar Branches (VL=1) are **not** identical to
2421 v3.0B Scalar Branches. The key areas where differences occur are the
2422 inclusion of predication (which can still be used when VL=1), in when and
2423 why CTR is decremented (CTRtest Mode) and whether LR is updated (which
2424 is unconditional in v3.0B when LK=1, and conditional in SVP64 when LRu=1).
2425
2426 Inline comments highlight the fact that the Scalar Branch behaviour and
2427 pseudocode is still clearly visible and embedded within the Vectorised
2428 variant:
2429
2430 ```
2431 if (mode_is_64bit) then M <- 0
2432 else M <- 32
2433 # the bit of CR to test, if the predicate bit is zero,
2434 # is overridden
2435 testbit = CR[BI+32]
2436 if ¬predicate_bit then testbit = SVRMmode.SNZ
2437 # otherwise apart from the override ctr_ok and cond_ok
2438 # are exactly the same
2439 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2440 cond_ok <- BO[0] | ¬(testbit ^ BO[1])
2441 if ¬predicate_bit & ¬SVRMmode.sz then
2442 # this is entirely new: CTR-test mode still decrements CTR
2443 # even when predicate-bits are zero
2444 if ¬BO[2] & CTRtest & ¬CTi then
2445 CTR = CTR - 1
2446 # instruction finishes here
2447 else
2448 # usual BO[2] CTR-mode now under CTR-test mode as well
2449 if ¬BO[2] & ¬(CTRtest & (cond_ok ^ CTi)) then CTR <- CTR - 1
2450 # new VLset mode, conditional test truncates VL
2451 if VLSET and VSb = (cond_ok & ctr_ok) then
2452 if SVRMmode.VLI then SVSTATE.VL = srcstep+1
2453 else SVSTATE.VL = srcstep
2454 # usual LR is now conditional, but also joined by SVLR
2455 lr_ok <- LK
2456 svlr_ok <- SVRMmode.SL
2457 if ctr_ok & cond_ok then
2458 if AA then NIA <-iea EXTS(BD || 0b00)
2459 else NIA <-iea CIA + EXTS(BD || 0b00)
2460 if SVRMmode.LRu then lr_ok <- ¬lr_ok
2461 if SVRMmode.SLu then svlr_ok <- ¬svlr_ok
2462 if lr_ok then LR <-iea CIA + 4
2463 if svlr_ok then SVLR <- SVSTATE
2464 ```
2465
2466 Below is the pseudocode for SVP64 Branches, which is a little less
2467 obvious but identical to the above. The lack of obviousness is down to
2468 the early-exit opportunities.
2469
2470 Effective pseudocode for Horizontal-First Mode:
2471
2472 ```
2473 if (mode_is_64bit) then M <- 0
2474 else M <- 32
2475 cond_ok = not SVRMmode.ALL
2476 for srcstep in range(VL):
2477 # select predicate bit or zero/one
2478 if predicate[srcstep]:
2479 # get SVP64 extended CR field 0..127
2480 SVCRf = SVP64EXTRA(BI>>2)
2481 CRbits = CR{SVCRf}
2482 testbit = CRbits[BI & 0b11]
2483 # testbit = CR[BI+32+srcstep*4]
2484 else if not SVRMmode.sz:
2485 # inverted CTR test skip mode
2486 if ¬BO[2] & CTRtest & ¬CTI then
2487 CTR = CTR - 1
2488 continue # skip to next element
2489 else
2490 testbit = SVRMmode.SNZ
2491 # actual element test here
2492 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2493 el_cond_ok <- BO[0] | ¬(testbit ^ BO[1])
2494 # check if CTR dec should occur
2495 ctrdec = ¬BO[2]
2496 if CTRtest & (el_cond_ok ^ CTi) then
2497 ctrdec = 0b0
2498 if ctrdec then CTR <- CTR - 1
2499 # merge in the test
2500 if SVRMmode.ALL:
2501 cond_ok &= (el_cond_ok & ctr_ok)
2502 else
2503 cond_ok |= (el_cond_ok & ctr_ok)
2504 # test for VL to be set (and exit)
2505 if VLSET and VSb = (el_cond_ok & ctr_ok) then
2506 if SVRMmode.VLI then SVSTATE.VL = srcstep+1
2507 else SVSTATE.VL = srcstep
2508 break
2509 # early exit?
2510 if SVRMmode.ALL != (el_cond_ok & ctr_ok):
2511 break
2512 # SVP64 rules about Scalar registers still apply!
2513 if SVCRf.scalar:
2514 break
2515 # loop finally done, now test if branch (and update LR)
2516 lr_ok <- LK
2517 svlr_ok <- SVRMmode.SL
2518 if cond_ok then
2519 if AA then NIA <-iea EXTS(BD || 0b00)
2520 else NIA <-iea CIA + EXTS(BD || 0b00)
2521 if SVRMmode.LRu then lr_ok <- ¬lr_ok
2522 if SVRMmode.SLu then svlr_ok <- ¬svlr_ok
2523 if lr_ok then LR <-iea CIA + 4
2524 if svlr_ok then SVLR <- SVSTATE
2525 ```
2526
2527 Pseudocode for Vertical-First Mode:
2528
2529 ```
2530 # get SVP64 extended CR field 0..127
2531 SVCRf = SVP64EXTRA(BI>>2)
2532 CRbits = CR{SVCRf}
2533 # select predicate bit or zero/one
2534 if predicate[srcstep]:
2535 if BRc = 1 then # CR0 vectorised
2536 CR{SVCRf+srcstep} = CRbits
2537 testbit = CRbits[BI & 0b11]
2538 else if not SVRMmode.sz:
2539 # inverted CTR test skip mode
2540 if ¬BO[2] & CTRtest & ¬CTI then
2541 CTR = CTR - 1
2542 SVSTATE.srcstep = new_srcstep
2543 exit # no branch testing
2544 else
2545 testbit = SVRMmode.SNZ
2546 # actual element test here
2547 cond_ok <- BO[0] | ¬(testbit ^ BO[1])
2548 # test for VL to be set (and exit)
2549 if VLSET and cond_ok = VSb then
2550 if SVRMmode.VLI
2551 SVSTATE.VL = new_srcstep+1
2552 else
2553 SVSTATE.VL = new_srcstep
2554 ```
2555
2556 ### Example Shader code
2557
2558 ```
2559 // assume f() g() or h() modify a and/or b
2560 while(a > 2) {
2561 if(b < 5)
2562 f();
2563 else
2564 g();
2565 h();
2566 }
2567 ```
2568
2569 which compiles to something like:
2570
2571 ```
2572 vec<i32> a, b;
2573 // ...
2574 pred loop_pred = a > 2;
2575 // loop continues while any of a elements greater than 2
2576 while(loop_pred.any()) {
2577 // vector of predicate bits
2578 pred if_pred = loop_pred & (b < 5);
2579 // only call f() if at least 1 bit set
2580 if(if_pred.any()) {
2581 f(if_pred);
2582 }
2583 label1:
2584 // loop mask ANDs with inverted if-test
2585 pred else_pred = loop_pred & ~if_pred;
2586 // only call g() if at least 1 bit set
2587 if(else_pred.any()) {
2588 g(else_pred);
2589 }
2590 h(loop_pred);
2591 }
2592 ```
2593
2594 which will end up as:
2595
2596 ```
2597 # start from while loop test point
2598 b looptest
2599 while_loop:
2600 sv.cmpi CR80.v, b.v, 5 # vector compare b into CR64 Vector
2601 sv.bc/m=r30/~ALL/sz CR80.v.LT skip_f # skip when none
2602 # only calculate loop_pred & pred_b because needed in f()
2603 sv.crand CR80.v.SO, CR60.v.GT, CR80.V.LT # if = loop & pred_b
2604 f(CR80.v.SO)
2605 skip_f:
2606 # illustrate inversion of pred_b. invert r30, test ALL
2607 # rather than SOME, but masked-out zero test would FAIL,
2608 # therefore masked-out instead is tested against 1 not 0
2609 sv.bc/m=~r30/ALL/SNZ CR80.v.LT skip_g
2610 # else = loop & ~pred_b, need this because used in g()
2611 sv.crternari(A&~B) CR80.v.SO, CR60.v.GT, CR80.V.LT
2612 g(CR80.v.SO)
2613 skip_g:
2614 # conditionally call h(r30) if any loop pred set
2615 sv.bclr/m=r30/~ALL/sz BO[1]=1 h()
2616 looptest:
2617 sv.cmpi CR60.v a.v, 2 # vector compare a into CR60 vector
2618 sv.crweird r30, CR60.GT # transfer GT vector to r30
2619 sv.bc/m=r30/~ALL/sz BO[1]=1 while_loop
2620 end:
2621 ```
2622
2623 ### LRu example
2624
2625 show why LRu would be useful in a loop. Imagine the following
2626 c code:
2627
2628 ```
2629 for (int i = 0; i < 8; i++) {
2630 if (x < y) break;
2631 }
2632 ```
2633
2634 Under these circumstances exiting from the loop is not only based on
2635 CTR it has become conditional on a CR result. Thus it is desirable that
2636 NIA *and* LR only be modified if the conditions are met
2637
2638 v3.0 pseudocode for `bclrl`:
2639
2640 ```
2641 if (mode_is_64bit) then M <- 0
2642 else M <- 32
2643 if ¬BO[2] then CTR <- CTR - 1
2644 ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
2645 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2646 if ctr_ok & cond_ok then NIA <-iea LR[0:61] || 0b00
2647 if LK then LR <-iea CIA + 4
2648 ```
2649
2650 the latter part for SVP64 `bclrl` becomes:
2651
2652 ```
2653 for i in 0 to VL-1:
2654 ...
2655 ...
2656 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2657 lr_ok <- LK
2658 if ctr_ok & cond_ok then
2659 NIA <-iea LR[0:61] || 0b00
2660 if SVRMmode.LRu then lr_ok <- ¬lr_ok
2661 if lr_ok then LR <-iea CIA + 4
2662 # if NIA modified exit loop
2663 ```
2664
2665 The reason why should be clear from this being a Vector loop:
2666 unconditional destruction of LR when LK=1 makes `sv.bclrl` ineffective,
2667 because the intention going into the loop is that the branch should be to
2668 the copy of LR set at the *start* of the loop, not half way through it.
2669 However if the change to LR only occurs if the branch is taken then it
2670 becomes a useful instruction.
2671
2672 The following pseudocode should **not** be implemented because it
2673 violates the fundamental principle of SVP64 which is that SVP64 looping
2674 is a thin wrapper around Scalar Instructions. The pseducode below is
2675 more an actual Vector ISA Branch and as such is not at all appropriate:
2676
2677 ```
2678 for i in 0 to VL-1:
2679 ...
2680 ...
2681 cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
2682 if ctr_ok & cond_ok then NIA <-iea LR[0:61] || 0b00
2683 # only at the end of looping is LK checked.
2684 # this completely violates the design principle of SVP64
2685 # and would actually need to be a separate (scalar)
2686 # instruction "set LR to CIA+4 but retrospectively"
2687 # which is clearly impossible
2688 if LK then LR <-iea CIA + 4
2689 ```
2690
2691 [[!tag standards]]