(no commit message)
[libreriscv.git] / openpower / sv / svp64.mdwn
index 54f25aabf83653f92db13424428a2184587b5826..55e537018c6b71eed4347e60514cd025d5a5c530 100644 (file)
@@ -44,12 +44,12 @@ Table of contents
 Simple-V is a type of Vectorisation best described as a "Prefix Loop
 Subsystem" similar to the 5 decades-old Zilog Z80 `LDIR` instruction and
 to the 8086 `REP` Prefix instruction.  More advanced features are similar
-to the Z80 `CPIR` instruction. If naively viewed one-dimensionally as an actual
-Vector ISA it introduces over 1.5 million 64-bit True-Scalable Vector instructions
-on the SFFS Subset and closer to 10 million 64-bit True-Scalable Vector
-instructions if introduced on VSX.
-SVP64, the instruction format used by Simple-V, is therefore best viewed
-as an orthogonal RISC-paradigm "Prefixing" subsystem instead.
+to the Z80 `CPIR` instruction. If naively viewed one-dimensionally as an
+actual Vector ISA it introduces over 1.5 million 64-bit True-Scalable
+Vector instructions on the SFFS Subset and closer to 10 million 64-bit
+True-Scalable Vector instructions if introduced on VSX.  SVP64, the
+instruction format used by Simple-V, is therefore best viewed as an
+orthogonal RISC-paradigm "Prefixing" subsystem instead.
 
 Except where explicitly stated all bit numbers remain as in the rest of
 the Power ISA: in MSB0 form (the bits are numbered from 0 at the MSB on
@@ -64,15 +64,15 @@ the following instruction, but does **not** change the actual Decoding
 of that following instruction.  **All prefixed 32-bit instructions
 (Defined Words) retain their non-prefixed encoding and definition**.
 
-Two apparent exceptions to the above hard rule exist: SV Branch-Conditional
-operations and LD/ST-update "Post-Increment" Mode.  Post-Increment
-was considered sufficiently high priority (significantly reducing hot-loop
-instruction count) that one bit in the Prefix is reserved for it
-(Note the intention to release that bit and move Post-Increment instructions
-to EXT2xx).
+Two apparent exceptions to the above hard rule exist: SV
+Branch-Conditional operations and LD/ST-update "Post-Increment"
+Mode.  Post-Increment was considered sufficiently high priority
+(significantly reducing hot-loop instruction count) that one bit in
+the Prefix is reserved for it (*Note the intention to release that bit
+and move Post-Increment instructions to EXT2xx, as part of [[ls011]]*).
 Vectorised Branch-Conditional operations "embed" the original Scalar
-Branch-Conditional behaviour into a much more advanced variant that
-is highly suited to High-Performance Computation (HPC), Supercomputing,
+Branch-Conditional behaviour into a much more advanced variant that is
+highly suited to High-Performance Computation (HPC), Supercomputing,
 and parallel GPU Workloads.
 
 *Architectural Resource Allocation note: it is prohibited to accept RFCs
@@ -100,7 +100,7 @@ only 24 bits:
 * Predication on both source and destination
 * Two different sources of predication: INT and CR Fields
 * SV Modes including saturation (for Audio, Video and DSP), mapreduce,
-  fail-first and predicate-result mode.
+  and fail-first mode.
 
 Different classes of operations require different formats. The earlier
 sections cover the common formats and the four separate modes follow:
@@ -137,6 +137,80 @@ required (identifying whether the Suffix - Defined Word - is
 Arithmetic/Logical, CR-op, Load/Store or Branch-Conditional),
 adding "UnVectorised" to this phase is not unreasonable.*
 
+## Definition of Strict Program Order
+
+Strict Program Order is defined as giving the appearance, as far
+as programs are concerned, that instructions were executed
+strictly in the sequence that they occurred.  A "Precise"
+out-of-order
+Micro-architecture goes to considerable lengths to ensure that
+this is the case.
+
+Many Vector ISAs allow interrupts to occur in the middle of
+processing of large Vector operations, only under the condition
+that partial results are cleanly discarded, and continuation on return
+from the Trap Handler will restart the entire operation.
+The reason is that saving of full Architectural State is
+not practical.
+
+Simple-V operates on an entirely different paradigm from traditional
+Vector ISAs: as a Sub-Program Counter where "Elements" are synonymous
+with Scalar instructions. With this in mind it is critical for
+implementations to observe Strict Element-Level Program Order
+at all times
+(often simply referred to as just "Strict Program Order"
+throughout
+this Chapter).
+*Any* element is Interruptible and Simple-V has
+been carefully designed to guarantee that Architectural State may
+be fully preserved and restored regardless of that same State, but
+it is not necessarily guaranteed that the amount of time needed to recover
+will be low latency (particularly if REMAP
+is active).
+
+Interrupts still only save `MSR` and `PC` in `SRR0` and `SRR1`
+but the full SVP64 Architectural State may be saved and
+restored through manual copying of `SVSTATE` (and the four
+REMAP SPRs if in use at the time)
+Whilst this initially sounds unsafe in reality
+all that Trap Handlers (and function call stack save/restore)
+need do is avoid
+use of SVP64 Prefixed instructions to perform the necessary
+save/restore of Simple-V Architectural State.
+This capability also allows nested function calls to be made from
+inside Vertical-First Vector loops, which is very rare for Vector ISAs.
+
+Strict Program Order is also preserved by the Parallel Reduction
+REMAP Schedule, but only at the cost of requiring the destination
+Vector to be used (Deterministically) to store partial progress of the
+Parallel Reduction.
+
+The only major caveat for REMAP is that
+after an explicit change to
+Architectural State caused by writing to the
+Simple-V SPRs, some implementations may find
+it easier to take longer to calculate where in a given Schedule
+the re-mapping Indices were.  Obvious examples include Interrupts occuring
+in the middle of a non-RADIX2 Matrix Multiply Schedule (5x3 by 3x3
+for example), which
+will force implementations to perform divide and modulo
+calculations.
+
+An additional caveat involves Condition Register Fields
+when also used as Predicate Masks. An operation that
+overwrites the same CR Fields that are simultaneously
+being used as a Predicate Mask is `UNDEFINED` behaviour
+if the overwritten CR field element was needed by a
+subsequent Element for its Predicate Mask bit.
+This allows implementations to relax some of the
+otherwise-draconian Register Hazards that would otherwise
+occur, and to consider internal cacheing of the CR-based
+Predicate
+bits, but some implementations *may not necessarily
+perform pre-reading* and consequently the risk of
+overwrite is the responsibility of the Programmer.
+Special care is particularly needed here when using REMAP.
+
 ## Register files, elements, and Element-width Overrides
 
 The relationship between register files, elements, and element-width
@@ -150,8 +224,8 @@ overrides is expressed as follows:
 * element-width overrides set the width of the *elements* in the
   sequentially-numbered contiguous array.
 
-The relationship is best defined in Canonical form, below, in ANSI c
-as a union data structure.  A key difference is that VSR elements are bounded
+The relationship is best defined in Canonical form, below, in ANSI c as a
+union data structure.  A key difference is that VSR elements are bounded
 fixed at 128-bit, where SVP64 elements are conceptually unbounded and
 only limited by the Maximum Vector Length.
 
@@ -196,14 +270,13 @@ sequentially from the LSB end
 incrementally to the MSB end (confusingly numbered the lowest in
 MSB0 ordering).
 
-When exclusively using MSB0-numbering, SVP64
-becomes unnecessarily complex to both express and subsequently understand:
-the required conditional subtractions from 63,
-31, 15 and 7 needed to express the fact that elements are LSB0-sequential
-unfortunately become a hostile minefield, obscuring both
-intent and meaning. Therefore for the
-purposes of this section the more natural **LSB0 numbering is assumed**
-and it is left to the reader to translate to MSB0 numbering.
+When exclusively using MSB0-numbering, SVP64 becomes unnecessarily complex
+to both express and subsequently understand: the required conditional
+subtractions from 63, 31, 15 and 7 needed to express the fact that
+elements are LSB0-sequential unfortunately become a hostile minefield,
+obscuring both intent and meaning. Therefore for the purposes of this
+section the more natural **LSB0 numbering is assumed** and it is left
+to the reader to translate to MSB0 numbering.
 
 The Canonical specification for how element-sequential numbering and
 element-width overrides is defined is expressed in the following c
@@ -265,14 +338,15 @@ However if elwidth overrides are set to 16 for both source and destination:
         int_regfile[RT].hwords[i] = int_regfile[RA].hwords[i] + int_regfile[RB].hwords[i]
 ```
 
-The most fundamental aspect here to understand is that the wrapping into
-subsequent Scalar GPRs that occurs on larger-numbered elements
-including and especially on smaller element widths is **deliberate and intentional**.
-From this Canonical definition it should be clear that sequential elements begin
-at the LSB end of any given underlying Scalar GPR, progress to the MSB end, and
-then to the LSB end of the *next numerically-larger Scalar GPR*.  In the
-example above if VL=5 and RT=1 then the contents of GPR(1) and GPR(2) will
-be as follows.  For clarity in the table below:
+The most fundamental aspect here to understand is that the wrapping
+into subsequent Scalar GPRs that occurs on larger-numbered elements
+including and especially on smaller element widths is **deliberate
+and intentional**.  From this Canonical definition it should be clear
+that sequential elements begin at the LSB end of any given underlying
+Scalar GPR, progress to the MSB end, and then to the LSB end of the
+*next numerically-larger Scalar GPR*.  In the example above if VL=5
+and RT=1 then the contents of GPR(1) and GPR(2) will be as follows.
+For clarity in the table below:
 
 * Both MSB0-ordered bitnumbering *and* LSB-ordered bitnumbering are shown
 * The GPR-numbering is considered LSB0-ordered
@@ -293,9 +367,9 @@ be as follows.  For clarity in the table below:
 ```
 
 Note that the upper 48 bits of GPR(2) would **not** be modified due to
-the example having VL=5.  Thus on "wrapping" - sequential progression from
-GPR(1) into GPR(2) - the 5th result modifies
-**only** the bottom 16 LSBs of GPR(1).
+the example having VL=5.  Thus on "wrapping" - sequential progression
+from GPR(1) into GPR(2) - the 5th result modifies **only** the bottom
+16 LSBs of GPR(1).
 
 Hardware Architectural note: to avoid a Read-Modify-Write at the register
 file it is strongly recommended to implement byte-level write-enable lines
@@ -328,27 +402,27 @@ Operation, the exact same contents would be viewed as follows:
 ```
 
 In other words, this perspective really is no different from the situation
-where the actual Register File is treated as an Industry-standard byte-level-addressable
-Little-Endian-addressed SRAM.  Note that this perspective does **not**
-involve `MSR.LE` in any way shape or form because `MSR.LE` is directly
-in control of the Memory-to-Register byte-ordering. This section is
-exclusively about how to correctly perceive Simple-V-Augmented **Register**
-Files.
+where the actual Register File is treated as an Industry-standard
+byte-level-addressable Little-Endian-addressed SRAM.  Note that
+this perspective does **not** involve `MSR.LE` in any way shape or
+form because `MSR.LE` is directly in control of the Memory-to-Register
+byte-ordering. This section is exclusively about how to correctly perceive
+Simple-V-Augmented **Register** Files.
 
 **Comparative equivalent using VSR registers**
 
 For a comparative data point the VSR Registers may be expressed in the
 same fashion. The c code below is directly an expression of Figure 97 in
-Power ISA Public v3.1 Book I Section 6.3 page 258, *after compensating for
-MSB0 numbering in both bits and elements, adapting in full to LSB0 numbering,
-and obeying LE ordering*.
+Power ISA Public v3.1 Book I Section 6.3 page 258, *after compensating
+for MSB0 numbering in both bits and elements, adapting in full to LSB0
+numbering, and obeying LE ordering*.
 
-**Crucial to understanding why the subtraction from 1,3,7,15 is present
-is because the Power ISA numbers VSX Registers elements also in MSB0 order**.
+**Crucial to understanding why the subtraction from 1,3,7,15 is present is
+because the Power ISA numbers VSX Registers elements also in MSB0 order**.
 SVP64 very specifically numbers elements in **LSB0** order with the first
-element (numbered zero) being at the bitwise-numbered **LSB** end of the register, where VSX
-does the reverse: places the numerically-*highest* (last-numbered) element at
-the LSB end of the register.
+element (numbered zero) being at the bitwise-numbered **LSB** end of the
+register, where VSX does the reverse: places the numerically-*highest*
+(last-numbered) element at the LSB end of the register.
 
 
 ```
@@ -394,21 +468,21 @@ the LSB end of the register.
     }
 ```
 
-For VSR Registers one key difference is that the overlay of different element
-widths is clearly a *bounded static quantity*, whereas for Simple-V the
-elements are
-unrestrained and permitted to flow into *successive underlying Scalar registers*.
-This difference is absolutely critical to a full understanding of the entire
-Simple-V paradigm and why element-ordering, bit-numbering *and register numbering*
-are all so strictly defined.
+For VSR Registers one key difference is that the overlay of different
+element widths is clearly a *bounded static quantity*, whereas for
+Simple-V the elements are unrestrained and permitted to flow into
+*successive underlying Scalar registers*.  This difference is absolutely
+critical to a full understanding of the entire Simple-V paradigm and
+why element-ordering, bit-numbering *and register numbering* are all so
+strictly defined.
 
-Implementations are not permitted to violate the Canonical definition. Software
-will be critically relying on the wrapped (overflow) behaviour inherently
-implied by the unbounded variable-length c arrays.
+Implementations are not permitted to violate the Canonical
+definition. Software will be critically relying on the wrapped (overflow)
+behaviour inherently implied by the unbounded variable-length c arrays.
 
-Illustrating the exact same loop with the exact same effect as achieved by Simple-V
-we are first forced to create wrapper functions, to cater for the fact
-that VSR register elements are static bounded:
+Illustrating the exact same loop with the exact same effect as achieved
+by Simple-V we are first forced to create wrapper functions, to cater
+for the fact that VSR register elements are static bounded:
 
 ```
     int calc_VSR_reg_offs(int elt, int width) {
@@ -462,19 +536,19 @@ whereas when VL=1 and the SV prefix is all zeros, the operation simply
 acts as if SV had not been applied at all to the instruction  (an
 "identity transformation").
 
-The fact that `VL` is dynamic and can be set to any value at runtime based
-on program conditions and behaviour means very specifically that
-`scalar identity behaviour` is **not** a redundant encoding. If the
-only means by which VL could be set was by way of static-compiled
-immediates then this assertion would be false.  VL should not
-be confused with MAXVL when understanding this key aspect of SimpleV.
+The fact that `VL` is dynamic and can be set to any value at runtime
+based on program conditions and behaviour means very specifically that
+`scalar identity behaviour` is **not** a redundant encoding. If the only
+means by which VL could be set was by way of static-compiled immediates
+then this assertion would be false.  VL should not be confused with
+MAXVL when understanding this key aspect of SimpleV.
 
 ## Register Naming and size
 
-As indicated above SV Registers are simply the GPR, FPR and CR
-register files extended linearly to larger sizes; SV Vectorisation
-iterates sequentially through these registers (LSB0 sequential ordering
-from 0 to VL-1).
+As indicated above SV Registers are simply the GPR, FPR and CR register
+files extended linearly to larger sizes; SV Vectorisation iterates
+sequentially through these registers (LSB0 sequential ordering from 0
+to VL-1).
 
 Where the integer regfile in standard scalar Power ISA v3.0B/v3.1B is
 r0 to r31, SV extends this as r0 to r127.  Likewise FP registers are
@@ -494,13 +568,13 @@ This is part of `scalar identity behaviour` described above.
 
 **Condition Register(s)**
 
-The Scalar Power ISA Condition Register is a 64 bit register where the top
-32 MSBs (numbered 0:31 in MSB0 numbering) are not used.  This convention is
-*preserved*
-in SVP64 and an additional 15 Condition Registers provided in
-order to store the new CR Fields, CR8-CR15, CR16-CR23 etc. sequentially.
-The top 32 MSBs in each new SVP64 Condition Register are *also* not used:
-only the bottom 32 bits (numbered 32:63 in MSB0 numbering).
+The Scalar Power ISA Condition Register is a 64 bit register where
+the top 32 MSBs (numbered 0:31 in MSB0 numbering) are not used.
+This convention is *preserved* in SVP64 and an additional 15 Condition
+Registers provided in order to store the new CR Fields, CR8-CR15,
+CR16-CR23 etc. sequentially.  The top 32 MSBs in each new SVP64 Condition
+Register are *also* not used: only the bottom 32 bits (numbered 32:63
+in MSB0 numbering).
 
 *Programmer's note: using `sv.mfcr` without element-width overrides
 to take into account the fact that the top 32 MSBs are zero and thus
@@ -520,6 +594,55 @@ Condition-Register instructions because all other CR instructions,
 on closer investigation, will be observed to all be CR-bit or CR-Field
 related. Thus a `VL` of 16 must be used*
 
+**Condition Register Fields as Predicate Masks**
+
+Condition Register Fields perform an additional duty in Simple-V: they are
+used for Predicate Masks.  ARM's Scalar Instruction Set calls single-bit
+predication "Conditional Execution", and utilises Condition Codes for
+exactly this purpose to solve the problem caused by Branch Speculation.
+In a Vector ISA context the concept of Predication is naturally extended
+from single-bit to multi-bit, and the (well-known) benefits become all the
+more critical given that parallel branches in Vector ISAs are impossible
+(even a Vector ISA can only have Scalar branches).
+
+However the Scalar Power ISA does not have Conditional Execution (for
+which, if it had ever been considered, Condition Register bits would be
+a perfect natural fit).  Thus, when adding Predication using CR Fields
+via Simple-V it becomes a somewhat disruptive addition to the Power ISA.
+
+To ameliorate this situation, particularly for pre-existing Hardware
+designs implementing up to Scalar Power ISA v3.1, some rules are set that
+allow those pre-existing designs not to require heavy modification to
+their existing Scalar pipelines.  These rules effectively allow Hardware
+Architects to add the additional CR Fields CR8 to CR127 as if they were
+an **entirely separate register file**.
+
+* any instruction involving more than 1 source 1 destination
+  where one of the operands is a Condition Register is prohibited from
+  using registers from both the CR0-7 group and the CR8-127 group at
+  the same time.
+* any instruction involving 1 source 1 destination where either the
+  source or the destination is a Condition Register is prohibited
+  from setting CR0-7 as a Vector.
+* prohibitions are required to be enforced by raising Illegal Instruction
+  Traps
+
+Examples of permitted instructions:
+
+```
+    sv.crand *cr8.eq, *cr16.le, *cr40.so # all CR8-CR127
+    sv.mfcr cr5, *cr40                   # only one source (CR40) copied to CR5
+    sv.mfcr *cr16, cr40                  # Vector-Splat CR40 onto CR16,17,18...
+    sv.mfcr *cr16, cr3                  # Vector-Splat CR3 onto CR16,17,18...
+```
+
+Examples of prohibited instructions:
+
+```
+    sv.mfcr *cr0, cr40        # Vector-Splat onto CR0,1,2
+    sv.crand cr7, cr9, cr10   # crosses over between CR0-7 and CR8-127
+```
+
 ## Future expansion.
 
 With the way that EXTRA fields are defined and applied to register
@@ -691,6 +814,14 @@ The SUBVL encoding value may be thought of as an inclusive range of a
 sub-vector.  SUBVL=2 represents a vec2, its encoding is 0b01, therefore
 this may be considered to be elements 0b00 to 0b01 inclusive.
 
+Effectively, SUBVL is like a SIMD multiplier: instead of just 1
+element operation issued, SUBVL element operations are issued (as an inner loop).
+The key difference between VL looping and SUBVL looping
+is that predication bits are applied per
+**group**, rather than by individual element.  
+
+Directly related to `subvl` is the `pack` and `unpack` Mode bits of `SVSTATE`.
+
 ## MASK/MASK_SRC & MASKMODE Encoding
 
 One bit (`MASKMODE`) indicates the mode: CR or Int predication.   The two
@@ -715,11 +846,12 @@ used for both src and dest, or different regs (one for src, one for dest).
 Likewise CR based twin predication has a second set of 3 bits, allowing
 a different test to be applied.
 
-Note that it is assumed that Predicate Masks (whether INT or CR) are
-read *before* the operations proceed.  In practice (for CR Fields)
-this creates an unnecessary block on parallelism.  Therefore, it is up
-to the programmer to ensure that the CR fields used as Predicate Masks
-are not being written to by any parallel Vector Loop.  Doing so results
+Note that it cannot necessarily be assumed that Predicate Masks
+(whether INT or CR) are read in full *before* the operations proceed.  In practice (for CR Fields)
+this creates an unnecessary block on parallelism, prohibiting
+"Vector Chaining".  Therefore, it is up
+to the programmer to ensure that the CR field Elements used as Predicate Masks
+are not overwritten by any parallel Vector Loop.  Doing so results
 in **UNDEFINED** behaviour, according to the definition outlined in the
 Power ISA v3.0B Specification.
 
@@ -728,6 +860,14 @@ of individual CR fields until the actual predicated element operation
 needs to take place, safe in the knowledge that no programmer will have
 issued a Vector Instruction where previous elements could have overwritten
 (destroyed) not-yet-executed CR-Predicated element operations.
+This particularly is an issue when using REMAP, as the order in
+which CR-Field-based Predicate Mask bits could be read on a per-element
+execution basis could well conflict with the order in which prior
+elements wrote to the very same CR Field.
+
+Additionally Programmers should avoid using r3 r10 or r30
+as destination registers when these are also used as a Predicate
+Mask. Doing so is again UNDEFINED behaviour.
 
 ### Integer Predication (MASKMODE=0)
 
@@ -751,6 +891,7 @@ following meaning:
 r10 and r30 are at the high end of temporary and unused registers,
 so as not to interfere with register allocation from ABIs.
 
+
 ### CR-based Predication (MASKMODE=1)
 
 When the predicate mode bit is one the 3 bits are interpreted as below.