clarify notation on _RT in ls008
[libreriscv.git] / openpower / sv / rfc / ls008.mdwn
index 3ae2a815b52768de60e9d60d201f99e5da22ccf7..252270c5d00cec69b0255aa1095a8c1c3ab9e476 100644 (file)
@@ -5,7 +5,7 @@
 * <https://libre-soc.org/openpower/sv/>
 * <https://libre-soc.org/openpower/sv/rfc/ls008/>
 * <https://bugs.libre-soc.org/show_bug.cgi?id=1040>
-* <https://git.openpower.foundation/isa/PowerISA/issues/87>
+* <https://git.openpower.foundation/isa/PowerISA/issues/123>
 
 **Severity**: Major
 
 ```
     setvl    - Cray-style "Set Vector Length" instruction
     svstep   - Vertical-First Mode explicit Step and Status
-    svremap  - Re-Mapping of Register Element Offsets
-    svindex  - General-purpose setting of SHAPEs to be re-mapped
-    svshape  - Hardware-level setting of SHAPEs for element re-mapping
-    svshape2 - Hardware-level setting of SHAPEs for element re-mapping (v2)
 ```
 
 **Submitter**: Luke Leighton (Libre-SOC)
@@ -45,7 +41,7 @@
 **Impact on processor**:
 
 ```
-    Addition of six new "Zero-Overhead-Loop-Control" DSP-style Vector-style
+    Addition of two new "Zero-Overhead-Loop-Control" DSP-style Vector-style
     Management Instructions which can be implemented extremely efficiently
     and effectively by inserting an additional phase between Decode and Issue.
     More complex designs are NOT adversely impacted and in fact greatly benefit
@@ -102,325 +98,19 @@ Add the following entries to:
 
 # Notation, Section 1.3.2
 
-When register operands (RA, RT, BF) are prefixed by a single underscore
-(_RT, _RA, _BF) the variable contains the contents of the instruction field
-not the contents of the Register File referenced *by* that field. Example:
-`_RT` contains the contents of bits 5 thru 10. The relationship
-`RT = GPR(_RT)` is thus always true. Uses include making alternative
-decisions within an instruction based on whether the operand field
-is zero or non-zero.
+When destination register operands (`RT, RS`) are prefixed by a single
+underscore (`_RT, _RS`) the variable also contains the contents of the
+instruction field.
+This avoids confusion in pseudocode when a destination register is
+assigned (`RT <- x`) but earlier it was the operand bits that were
+checked (`if RT = 0`)
 
 ----------------
 
 \newpage{}
 
-# svstep: Vertical-First Stepping and status reporting
-
-SVL-Form
-
-* svstep RT,SVi,vf (Rc=0)
-* svstep. RT,SVi,vf (Rc=1)
-
-| 0-5|6-10|11.15|16..22| 23-25    | 26-30 |31|   Form   |
-|----|----|-----|------|----------|-------|--|--------- |
-|PO  | RT | /   | SVi  |  / / vf  | XO    |Rc| SVL-Form |
-
-Pseudo-code:
-
-```
-    if SVi[3:4] = 0b11 then
-        # store pack and unpack in SVSTATE
-        SVSTATE[53] <- SVi[5]
-        SVSTATE[54] <- SVi[6]
-        RT <- [0]*62 || SVSTATE[53:54]
-    else
-        # Vertical-First explicit stepping.
-        step <- SVSTATE_NEXT(SVi, vf)
-        RT <- [0]*57 || step
-```
-
-Special Registers Altered:
-
-    CR0                     (if Rc=1)
-
-**Description**
-
-svstep may be used
-to enquire about the REMAP Schedule and it may be used to alter Vectorisation
-State.  When `vf=1` then stepping occurs.
-When `vf=0` the enquiry is performed without altering internal
-state.  If `SVi=0, Rc=0, vf=0` the instruction is a `nop`.
-
-The following Modes exist:
-
-* `SVi=0`: appropriately step srcstep, dststep, subsrcstep and subdststep to the next
-   element, taking pack and unpack into consideration.
-* When `SVi` is 1-4 the REMAP Schedule for a given SVSHAPE may be
-returned in `RT`.  SVi=1 selects SVSHAPE0 current state,
-through to SVi=4 selects SVSHAPE3.
-* When `SVi` is 5, `SVSTATE.srcstep` is returned.
-* When `SVi` is 6, `SVSTATE.dststep` is returned.
-* When `SVi` is 0b1100 pack/unpack in SVSTATE is cleared
-* When `SVi` is 0b1101 pack in SVSTATE is set, unpack is cleared
-* When `SVi` is 0b1110 unpack in SVSTATE is set, pack is cleared
-* When `SVi` is 0b1111 pack/unpack in SVSTATE are set
-
-As this is a Single-Predicated (1P) instruction, predication may be applied
-to skip (or zero) elements. 
-
-* Vertical-First Mode will return the requested index
-  (and move to the next state if `vf=1`)
-* Horizontal-First Mode can be used to return all indices,
-  i.e. walks through all possible states.
-
-**Vectorisation of svstep itself**
-
-As a 32-bit instruction, `svstep` may be itself be Vector-Prefixed, as
-`sv.svstep`. This will work perfectly well in Horizontal-First
-as it will in Vertical-First Mode.
-
-Example: to obtain the full set of possible computed element
-indices use `sv.svstep RT.v,SVI,1` which will store all computed element
-indices, starting from RT.  If Rc=1 then a co-result Vector of CR Fields
-will also be returned, comprising the "loop end-points" of each of the inner
-loops when either Matrix Mode or DCT/FFT is set.  In other words,
-for example, when the `xdim` inner loop reaches the end and on the next
-iteration it will begin again at zero, the CR Field `EQ` will be set.
-With a maximum of three loops within both Matrix and DCT/FFT Modes,
-the CR Field's EQ bit will be set at the end of the first inner loop,
-the LE bit for the second, the GT bit for the outermost loop and the
-SO bit set on the very last element, when all loops reach their maximum
-extent.
-
-*Programmer's note (1): VL in some situations, particularly larger Matrices,
-may exceed 64,
-meaning that `sv.svshape` returning a considerable number of values. Under
-such circumstances `sv.svshape/ew=8` is recommended.*
-
-*Programmer's note (2): having conveniently obtained a pre-computed
-Schedule with `sv.svstep`,
-it may then be used as the input to Indexed REMAP Mode
-to achieve the exact same Schedule. It is evident however that
-before use some of the Indices may be arbitrarily altered as desired.
-`sv.svstep` helps the programmer avoid having to manually recreate
-Indices for certain
-types of common Loop patterns, and in its simplest form, without REMAP
-(SVi=5 or SVi=6),
-is equivalent to the `iota` instruction found in other Vector ISAs*
-
-**Vertical First Mode**
-
-Vertical First is effectively like an implicit single bit predicate
-applied to every SVP64 instruction.  **ONLY** one element in each
-SVP64 Vector instruction is executed; srcstep and dststep do **not**
-increment, and the Program Counter progresses **immediately** to
-the next instruction just as it would for any standard scalar v3.0B
-instruction.
-
-A mode of srcstep (SVi=0) is called which can move srcstep and
-dststep on to the next element, still respecting predicate
-masks.
-
-In other words, where normal SVP64 Vectorisation acts "horizontally"
-by looping first through 0 to VL-1 and only then moving the PC
-to the next instruction, Vertical-First moves the PC onwards
-(vertically) through multiple instructions **with the same
-srcstep and dststep**, then an explict instruction used to
-advance srcstep/dststep. An outer loop is expected to be
-used (branch instruction) which completes a series of
-Vector operations.
-
-Testing any end condition of any loop of any REMAP state allows branches to be
-used to create loops.
-
-Programmer's note: when Predicate Non-Zeroing is used this indicates to
-the underlying hardware that any masked-out element must be skipped.
-*This includes in Vertical-First Mode*, and programmers should be keenly
-aware that srcstep or dststep or both *may* jump by more than one as
-a result, because the actual request under these circumstances was to execute
-on the first available next *non-masked-out* element.
-
-*Programmers should be aware that VL, srcstep and dststep are global in nature.
-Nested looping with different schedules is perfectly possible, as is
-calling of functions, however SVSTATE (and any associated SVSTATE) should
-obviously be stored on the stack in order to achieve this benefit*
-
--------------
-
-\newpage{}
-
-
-# setvl
-
-SVL-Form
-
-| 0-5|6-10|11-15|16-22 | 23 24 25 | 26-30 |31|   FORM   |
-| -- | -- | --- | ---- |----------| ----- |--|----------|
-|PO  | RT | RA  | SVi  | ms vs vf | XO    |Rc| SVL-Form |
-
-* setvl RT,RA,SVi,vf,vs,ms (Rc=0)
-* setvl. RT,RA,SVi,vf,vs,ms (Rc=1)
-
-Pseudo-code:
-
-```
-    overflow <- 0b0    # sets CR.SO if set and if Rc=1
-    VLimm <- SVi + 1
-    # set or get MVL
-    if ms = 1 then MVL <- VLimm[0:6]
-    else           MVL <- SVSTATE[0:6]
-    # set or get VL
-    if vs = 0                then VL <- SVSTATE[7:13]
-    else if _RA != 0         then
-        if (RA) >u 0b1111111 then
-            VL <- 0b1111111
-            overflow <- 0b1
-        else                      VL <- (RA)[57:63]
-    else if _RT = 0          then VL <- VLimm[0:6]
-    else if CTR >u 0b1111111 then
-        VL <- 0b1111111
-        overflow <- 0b1
-    else                          VL <- CTR[57:63]
-    # limit VL to within MVL
-    if VL >u MVL then
-        overflow <- 0b1
-        VL <- MVL
-    SVSTATE[0:6] <- MVL
-    SVSTATE[7:13] <- VL
-    if _RT != 0 then
-       GPR(_RT) <- [0]*57 || VL
-    # MAXVL is a static "state-reset" opportunity so VF is only set then.
-    if ms = 1 then
-         SVSTATE[63] <- vf   # set Vertical-First mode
-         SVSTATE[62] <- 0b0  # clear persist bit
-```
-
-Special Registers Altered:
-
-```
-    CR0                     (if Rc=1)
-```
-
-* `SVi` - bits 16-22 - an immediate operand for setting MVL and/or VL
-* `ms` - bit 23 - allows for setting of MVL
-* `vs` - bit 24 - allows for setting of VL
-* `vf` - bit 25 - sets "Vertical First Mode".
-
-Note that in immediate setting mode VL and MVL start from **one**
-but that this is compensated for in the assembly notation.
-i.e. that an immediate value of 1 in assembler notation
-actually places the value 0b0000000 in the `SVi` field bits:
-on execution the `setvl` instruction adds one to the decoded
-`SVi` field bits, resulting in
-VL/MVL being set to 1. This allows VL to be set to values
-ranging from 1 to 128 with only 7 bits instead of 8.
-Setting VL/MVL
-to 0 would result in all Vector operations becoming `nop`.  If this is
-truly desired (nop behaviour) then setting VL and MVL to zero is to be
-done via the [[SVSTATE SPR|sv/sprs]].
-
-Note that setmvli is a pseudo-op, based on RA/RT=0, and setvli likewise
-
-    setvli   VL=8   : setvl  r0, r0, VL=8, vf=0, vs=1, ms=0
-    setvli.  VL=8   : setvl. r0, r0, VL=8, vf=0, vs=1, ms=0
-    setmvli  MVL=8  : setvl  r0, r0, MVL=8, vf=0, vs=0, ms=1
-    setmvli. MVL=8  : setvl. r0, r0, MVL=8, vf=0, vs=0, ms=1
-
-Additional pseudo-op for obtaining VL without modifying it (or any state):
-
-    getvl  r5      : setvl  r5, r0, vf=0, vs=0, ms=0
-    getvl. r5      : setvl. r5, r0, vf=0, vs=0, ms=0
-
-Note that whilst it is possible to set both MVL and VL from the same
-immediate, it is not possible to set them to different immediates in
-the same instruction.  Doing so would require two instructions.
-
-**Selecting sources for VL**
-
-There is considerable opcode pressure, consequently to set MVL and VL
-from different sources is as follows:
-
-| condition           | effect         |
-| - | - |
-| `vs=1, RA=0, RT!=0` | VL,RT set to MIN(MVL, CTR)  |
-| `vs=1, RA=0, RT=0`  | VL set to MIN(MVL, SVi+1)  |
-| `vs=1, RA!=0, RT=0` | VL set to MIN(MVL, RA)  |
-| `vs=1, RA!=0, RT!=0` | VL,RT set to MIN(MVL, RA)  |
-
-The reasoning here is that the opportunity to set RT equal to the
-immediate `SVi+1` is sacrificed in favour of setting from CTR.
-
-# Unusual Rc=1 behaviour
-
-Normally, the return result from an instruction is in `RT`. With
-it being possible for `RT=0` to mean that `CTR` mode is to be read,
-some different semantics are needed.
-
-CR Field 0, when `Rc=1`, may be set even if `RT=0`. The reason is that
-overflow may occur: `VL`, if set either from an immediate or from `CTR`,
-may not exceed `MAXVL`, and if it is, `CR0.SO` must be set.
-
-Additionally, in reality it is **`VL`** being set. Therefore, rather
-than `CR0` testing `RT` when `Rc=1`, CR0.EQ is set if `VL=0`, CR0.GE
-is set if `VL` is non-zero.
-
-**SUBVL**
-
-Sub-vector elements are not be considered "Vertical". The vec2/3/4
-is to be considered as if the "single element".  Caveats exist for
-[[sv/mv.swizzle]] and [[sv/mv.vec]] when Pack/Unpack is enabled,
-due to the order in which VL and SUBVL loops are applied being
-swapped (outer-inner becomes inner-outer)
-
-# Examples
-
-## Core concept loop
-
-```
-loop:
-    setvl a3, a0, MVL=8    #  update a3 with vl
-                           # (# of elements this iteration)
-                           # set MVL to 8
-    # do vector operations at up to 8 length (MVL=8)
-    # ...
-    sub a0, a0, a3   # Decrement count by vl
-    bnez a0, loop    # Any more?
-```
-
-## Loop using Rc=1
-
-    my_fn:
-      li r3, 1000
-      b test
-    loop:
-      sub r3, r3, r4
-      ...
-    test:
-      setvli. r4, r3, MVL=64
-      bne cr0, loop
-    end:
-      blr
-
-## Load/Store-Multi (selective)
-
-Up to 64 FPRs will be loaded, here.  `r3` is set one per bit
-for each FP register required to be loaded.  The block of memory
-from which the registers are loaded is contiguous (no gaps):
-any FP register which has a corresponding zero bit in `r3`
-is *unaltered*.  In essence this is a selective LD-multi with
-"Scatter" capability.
-
-    setvli r0, MVL=64, VL=64
-    sv.fld/dm=r3 *r0, 0(r30) # selective load 64 FP registers
-
-Up to 64 FPRs will be saved, here.  Again, `r3` 
-
-    setvli r0, MVL=64, VL=64
-    sv.stfd/sm=r3 *fp0, 0(r30) # selective store 64 FP registers
-
--------------
-
-\newpage{}
+[[!inline pages="openpower/sv/svstep" raw=yes ]]
+[[!inline pages="openpower/sv/setvl" raw=yes ]]
 
 # SVSTATE SPR