(no commit message)
[libreriscv.git] / openpower / sv / branches.mdwn
index 6a437e5fa9cc28a92cf763b61cdcdd0054dc5dcb..d4487dba9b0d077ee128e2883df3301dcc3316be 100644 (file)
@@ -16,38 +16,56 @@ Links
 * [[openpower/isa/branch]]
 
 Scalar 3.0B Branch Conditional operations, `bc`, `bctar` etc. test a
-Condition Register.  When doing so in a Vector Context, it is quite
-reasonable and logical to test and Branch on a *Vector* of CR Fields
-which have just been calculated from a *Vector* of results. In 3D Shader
+Condition Register.  However for parallel processing it is simply impossible
+to perform multiple independent branches: the Program Counter simply
+cannot branch to multiple destinations based on multiple conditions.
+The best that can be done is
+to test multiple Conditions and make a decision of a *single* branch,
+based on analysis of a *Vector* of CR Fields
+which have just been calculated from a *Vector* of results.
+
+In 3D Shader
 binaries, which are inherently parallelised and predicated, testing all or
 some results and branching based on multiple tests is extremely common,
-and a fundamental part of Shader Compilers.  Therefore, `sv.bc` and
+and a fundamental part of Shader Compilers.  Example:
+without such multi-condition
+test-and-branch, if a predicate mask is all zeros a large batch of
+instructions may be masked out to `nop`, and it would waste
+CPU cycles not only to run them but also to load the predicate
+mask repeatedly for each one.  3D GPU ISAs can test for this scenario
+and jump over the fully-masked-out operations, by spotting that
+*all* Conditions are false. Or, conversely, they only call the function if at least
+one Condition) is set.
+Therefore, in order to be commercially competitive, `sv.bc` and
 other Vector-aware Branch Conditional instructions are a high priority
-for 3D GPUs.
+for 3D GPU workloads.
 
 The `BI` field of Branch Conditional operations is five bits, in scalar
-v3.0B this would select one bit of the 32 bit CR.  In SVP64 there are
+v3.0B this would select one bit of the 32 bit CR,
+comprising eight CR Fields of 4 bits each.  In SVP64 there are
 16 32 bit CRs, containing 128 4-bit CR Fields.  Therefore, the 2 LSBs of
 `BI` select the bit from the CR Field (EQ LT GT SO), and the top 3 bits
 are extended to either scalar or vector and to select CR Fields 0..127
 as specified in SVP64 [[sv/svp64/appendix]].
 
-When considering an "array" of branches, there are four useful modes:
+When considering an "array" of branch-tests, there are four useful modes:
 AND, OR, NAND and NOR of all Conditions.
 NAND and NOR may be synthesised by
 inverting `BO[2]` which just leaves two modes:
 
-* Branch takes place on the first CR test to succeed
+* Branch takes place on the first CR Field test to succeed
   (a Great Big OR of all condition tests)
-* Branch takes place only if **all** CR tests succeed:
+* Branch takes place only if **all** CR field tests succeed:
   a Great Big AND of all condition tests
   (including those where the predicate is masked out
    and the corresponding CR Field is considered to be
    set to `SNZ`)
 
-When the CR Fields selected by SVP64 Augmented `BI` is marked as scalar,
-then as usual the loop ends at the first element tested, after taking
-predication into consideration. Thus, as usual, when `sz` is zero, srcstep
+When the CR Fields selected by SVP64-Augmented `BI` is marked as scalar,
+then as the usual SVP64 rules apply,
+the loop ends at the first element tested, after taking
+predication into consideration. Thus, also as usual, when a predicate mask is
+given, and `BI` marked as scalar, and `sz` is zero, srcstep
 skips forward to the first non-zero predicated element, and only that
 one element is tested.
 
@@ -64,31 +82,28 @@ a little unusual to consider in an ISA that is designed for Parallel
 Vector Processing. The reason is to have strictly-defined guaranteed
 behaviour*)
 
-In Vertical-First Mode, the `ALL` bit still applies, but to the elements
-that are executed up to the Hint length, in parallel batches. See
-[[sv/setvl]] for the definition of Vertical-First Hint.
-
-In `svstep` mode, srcstep and dststep are incremented, and then
-tested exactly as in  [[sv/svstep]]. When Rc=1 the test results
-are wtitten into the whole CR Field (the exact same one
-about to be tested by the Branch Condition). Following the svstep
-update, the
-Branch Conditional instruction proceeds as normal (reading and testing
-the CR bit just updated, if the relevant `BO` bit is set).  Note that
-the SVSTATE srcstep and dststep fields are still updated
-and the CR field still updated, even if `BO[0]` is set.
+In Vertical-First Mode, setting the `ALL` bit results in `UNDEFINED` 
+behaviour. Given that only one element is being tested at a time
+in Vertical-First Mode, a test designed to be done on multiple
+bits is meaningless.
 
 Predication in both INT and CR modes may be applied to `sv.bc` and other
 SVP64 Branch Conditional operations, exactly as they may be applied to
 other SVP64 operations.  When `sz` is zero, any masked-out Branch-element
-operations are not executed, exactly like all other SVP64 operations.
-
-However when `sz` is non-zero, this normally requests insertion of a zero
+operations are not included in condition testing, exactly like all other
+SVP64 operations, *including* side-effects such as potentially updating
+LR or CTR, which will also be skipped. There is *one* exception here,
+which is when
+`BO[2]=0, sz=0, CTR-test=0, CTi=1` and the relevant element
+predicate mask bit is also zero:
+under these special circumstances CTR will also decrement.
+
+When `sz` is non-zero, this normally requests insertion of a zero
 in place of the input data, when the relevant predicate mask bit is zero.
 This would mean that a zero is inserted in place of `CR[BI+32]` for
 testing against `BO`, which may not be desirable in all circumstances.
 Therefore, an extra field is provided `SNZ`, which, if set, will insert
-a **one** in place of a masked-out element instead of a zero.
+a **one** in place of a masked-out element, instead of a zero.
 
 (*Note: Both options are provided because it is useful to deliberately
 cause the Branch-Conditional Vector testing to fail at a specific point,
@@ -96,14 +111,15 @@ controlled by the Predicate mask. This is particularly useful in `VLSET`
 mode, which will truncate SVSTATE.VL at the point of the first failed
 test.*)
 
-SVP64 RM `MODE` (includes `ELWIDTH` and `ELWIDTH_SRC` bits) for Branch Conditional:
+SVP64 RM `MODE` (includes `ELWIDTH` and `ELWIDTH_SRC` bits) for Branch
+Conditional:
 
-| 4 | 5 | 6 | 7 | 19 | 20 |  21 | 22   23 |  description        |
-| - | - | - | - | -- | -- | --- |---------|-------------------- |
-|ALL|LRu| / | / | 0  | 0  | /   |  SNZ sz | normal mode         |
-|ALL|LRu| / |VSb| 0  | 1  | VLI |  SNZ sz | VLSET mode          |
-|ALL|LRu|BRc| / | 1  | 0  | /   |  SNZ sz | svstep mode         |
-|ALL|LRu|BRc|VSb| 1  | 1  | VLI |  SNZ sz | svstep+VLSET mode   |
+| 4 | 5 | 6 | 7 | 19 | 20 |  21 | 22   23 |  description     |
+| - | - | - | - | -- | -- | --- |---------|----------------- |
+|ALL|LRu| / | / | 0  | 0  | /   |  SNZ sz | normal mode      |
+|ALL|LRu| / |VSb| 0  | 1  | VLI |  SNZ sz | VLSET mode       |
+|ALL|LRu|CTi| / | 1  | 0  | /   |  SNZ sz | CTR-test mode         |
+|ALL|LRu|CTi|VSb| 1  | 1  | VLI |  SNZ sz | CTR-test+VLSET mode   |
 
 Fields:
 
@@ -111,10 +127,11 @@ Fields:
   the src CR Field when the predicate bit is zero.  otherwise the element
   is ignored or skipped, depending on context.
 * **ALL** when set, all branch conditional tests must pass in order for
-  the branch to succeed.
-* **VLI** Identical to Data-dependent Fail-First mode.
+  the branch to succeed. When clear, it is the first sequentially
+  encountered successful test that causes the branch to succeed.
+* **VLI** VLSET is identical to Data-dependent Fail-First mode.
   In VLSET mode, VL is set equal (truncated) to the first point
-  where, assuming Conditions are tested sequentially, the  branch succeeds
+  where, assuming Conditions are tested sequentially, the branch succeeds
   *or fails* depending if VSb is set.
   If VLI (Vector Length Inclusive) is clear,
   VL is truncated to *exclude* the current element, otherwise it is
@@ -123,34 +140,57 @@ Fields:
   only be updated if the Branch Condition succeeds. This avoids
   destruction of LR during loops (particularly Vertical-First
   ones).
-* **BRc** Branch variant of Rc. Instructs svstep testing to overwrite
-  the CR Field about to be tested. Only takes effect in svstep mode
 * **VSb** is most relevant for Vertical-First VLSET Mode. After testing,
   if VSb is set, VL is truncated if the branch succeeds.  If VSb is clear,
   VL is truncated if the branch did **not** take place.
-
-svstep mode will run an increment of SVSTATE srcstep and dststep
-(which is still useful in Horizontal First Mode).  Unlike `svstep.`
-however which updates only CR0 with the testing of REMAP loop progress,
-the CR Field is taken from the branch `BI` field, and, if `BRc`
-is set, updated prior to
-proceeding to each element branch conditional testing.
-* This implies that the prior contents of the CR Vector are ignored*
-when `BRc` is set.
-
-Note that, interestingly, due to the useful side-effects of `VLSET` mode
-and `svstep` mode it is actually useful to use Branch Conditional even
+* **CTi** CTR inversion. CTR Mode normally decrements per element
+  tested. CTR inversion decrements if a test *fails*.
+
+Normally, CTR mode will decrement once per Condition Test, resulting
+under normal circumstances that CTR reduces by up to VL in Horizontal-First
+Mode. Just as when v3.0B Branch-Conditional saves at
+least one instruction on tight inner loops through auto-decrementation
+of CTR, likewise it is also possible to save instruction count for
+SVP64 loops in both Vertical-First and Horizontal-First Mode, particularly
+in circumstances where there is conditional interaction between the
+element computation and testing, and the continuation (or otherwise)
+of a given loop. The potential combinations of interactions is why CTR
+testing options have been added.
+
+If both CTR-test and VLSET Modes are requested, then because the CTR decrement is on a per element basis, the total amount that CTR is decremented
+by will end up being VL *after* truncation (should that occur). In
+other words, the order is (as can be seen in pseudocode, below):
+
+1. compute the test
+2. (optionally) decrement CTR
+3. (optionally) truncate VL
+4. decide (based on step 1) whether to terminate looping
+   (including not executing step 5)
+5. decide whether to branch.
+
+CTR-test mode and CTi interaction is as follows: note that
+`BO[2]` is still required to be clear for decrements to be
+considered.
+
+* **CTR-test=0, CTi=0**: CTR decrements on a per-element basis
+  if `BO[2]` is zero. Masked-out elements when `sz=0` are
+  skipped.
+* **CTR-test=0, CTi=1**: CTR decrements on a per-element basis
+  if `BO[2]` is zero and a masked-out element is skipped
+  (`sz=0` and predicate bit is zero). This one special case is the
+  **opposite** of other combinations.
+* **CTR-test=1, CTi=0**: CTR decrements on a per-element basis
+  if `BO[2]` is zero and the Condition Test succeeds.
+  Masked-out elements when `sz=0` are skipped.
+* **CTR-test=1, CTi=1**: CTR decrements on a per-element basis
+  if `BO[2]` is zero and the Condition Test *fails*.
+  Masked-out elements when `sz=0` are skipped.
+
+Note that, interestingly, due to the side-effects of `VLSET` mode
+it is actually useful to use Branch Conditional even
 to perform no actual branch operation, i.e to point to the instruction
-after the branch.
-
-In particular, svstep mode is still useful for Horizontal-First Mode
-particularly in combination with REMAP. All "loop end" conditions
-will be tested on a per-element basis and placed into a Vector of CRs
-starting from the point specified by the Branch `BI` field.  This Vector
-of CR Fields may then be subsequently used as a Predicate Mask, and,
-furthermore, if VLSET mode was requested, VL will have been set to the
-length of one of the loop endpoints, again as specified by the bit from
-the Branch `BI` field.
+after the branch. Truncation of VL would thus conditionally occur yet control
+flow alteration would not.
 
 Also, the unconditional bit `BO[0]` is still relevant when Predication
 is applied to the Branch because in `ALL` mode all nonmasked bits have
@@ -159,16 +199,16 @@ may still be decremented by the total number of nonmasked elements.
 In short, Vectorised Branch becomes an extremely powerful tool.
 
 `VLSET` mode with Vertical-First is particularly unusual. Vertical-First
-is used for explicit looping, where the looping is to terminate if
-the end of the Vector, VL, is reached. If however that loop is terminated
-early because VL is truncated, VLSET with Vertical-First becomes
-meaningless.  Therefore, the option to decide whether truncation should
-occur if the branch succeeds *or* if the branch condition fails allows
-for flexibility required.
+is used for explicit looping, where the looping is to terminate if the end
+of the Vector, VL, is reached. If however that loop is terminated early
+because VL is truncated, VLSET with Vertical-First becomes meaningless.
+Therefore, with `VSb`, the option to decide whether truncation should occur if the
+branch succeeds *or* if the branch condition fails allows for flexibility
+required.
 
-`VLSET` mode with Horizontal-First when `VSb` is clear is still useful,
-because it can be used to truncate VL to the first predicated (non-masked-out)
-element.
+`VLSET` mode with Horizontal-First when `VSb` is clear is still
+useful, because it can be used to truncate VL to the first predicated
+(non-masked-out) element.
 
 Available options to combine:
 
@@ -183,8 +223,13 @@ Available options to combine:
   `OR` of all tests, respectively.
 
 In addition to the above, it is necessary to select whether, in `svstep`
-mode, the Vector CR Field is to be overwritten or not: in some cases
-it is useful to know but in others all that is needed is the branch itself.
+mode, the Vector CR Field is to be overwritten or not: in some cases it
+is useful to know but in others all that is needed is the branch itself.
+
+*Programming note: One important point is that SVP64 instructions are 64 bit.
+(8 bytes not 4). This needs to be taken into consideration when computing
+branch offsets: the offset is relative to the start of the instruction,
+which includes the SVP64 Prefix*
 
 Pseudocode for Horizontal-First Mode:
 
@@ -195,15 +240,13 @@ for srcstep in range(VL):
     if predicate[srcstep]:
         # get SVP64 extended CR field 0..127
         SVCRf = SVP64EXTRA(BI>>2)
-        if svstep_mode then
-            new_srcstep, CRbits = SVSTATE_NEXT(srcstep)
-            if BRc = 1 then # CR Vectorised overwritr
-                CR{SVCRf+srcstep} = CRbits
-        else
-            CRbits = CR{SVCRf}
+        CRbits = CR{SVCRf}
         testbit = CRbits[BI & 0b11]
         # testbit = CR[BI+32+srcstep*4]
     else if not SVRMmode.sz:
+      # inverted CTR test skip mode
+      if ¬BO[2] & CTRtest & ¬CTI then
+         CTR = CTR - 1
         continue
     else
         testbit = SVRMmode.SNZ
@@ -228,8 +271,6 @@ for srcstep in range(VL):
     else
         if el_cond_ok:
             break
-    if svstep_mode then
-        SVSTATE.srcstep = new_srcstep
     if SVCRf.scalar:
        break
 ```
@@ -239,16 +280,16 @@ Pseudocode for Vertical-First Mode:
 ```
 # get SVP64 extended CR field 0..127
 SVCRf = SVP64EXTRA(BI>>2)
-if svstep_mode then
-    new_srcstep, CRbits = SVSTATE_NEXT(srcstep)
-else
-    CRbits = CR{SVCRf}
+CRbits = CR{SVCRf}
 # select predicate bit or zero/one
 if predicate[srcstep]:
     if BRc = 1 then # CR0 vectorised
         CR{SVCRf+srcstep} = CRbits
     testbit = CRbits[BI & 0b11]
 else if not SVRMmode.sz:
+    # inverted CTR test skip mode
+    if ¬BO[2] & CTRtest & ¬CTI then
+       CTR = CTR - 1
     SVSTATE.srcstep = new_srcstep
     exit # no branch testing
 else
@@ -261,8 +302,25 @@ if VLSET and cond_ok = VSb then
         SVSTATE.VL = new_srcstep+1
     else
         SVSTATE.VL = new_srcstep
-if svstep_mode then
-    SVSTATE.srcstep = new_srcstep
+```
+
+v3.0B branch pseudocode including LRu and CTR skipping
+
+```
+if (mode_is_64bit) then M <- 0
+else M <- 32
+cond_ok <- BO[0] | ¬(CR[BI+32] ^ BO[1])
+ctrdec = ¬BO[2]
+if CTRtest & (cond_ok ^ CTi) then
+   ctrdec = 0b0
+if ctrdec then CTR <- CTR - 1
+ctr_ok <- BO[2] | ((CTR[M:63] != 0) ^ BO[3])
+lr_ok <- SVRMmode.LRu
+if ctr_ok & cond_ok then
+  if AA then NIA <-iea EXTS(BD || 0b00)
+  else       NIA <-iea CIA + EXTS(BD || 0b00)
+  lr_ok <- 0b1
+if LK & lr_ok then LR <-iea CIA + 4
 ```
 
 # Example Shader code