(no commit message)
[libreriscv.git] / openpower / sv / branches.mdwn
1 # SVP64 Branch Conditional behaviour
2
3 Links
4
5 * <https://bugs.libre-soc.org/show_bug.cgi?id=664>
6 * <http://lists.libre-soc.org/pipermail/libre-soc-dev/2021-August/003416.html>
7 * [[openpower/isa/branch]]
8
9 Branch Conditional operations, `bc`, `bctar` etc. test a Condition Register.
10 When doing so, it is quite reasonable and logical to test a *Vector* of
11 CR Fields. In 3D Shader binaries, which are inherently parallelised
12 and predicated, testing all or some results and branching based on
13 multiple tests is extremely common.
14 Therefore, `sv.bc` and other Branch Conditional instructions are worth
15 including.
16
17 The `BI` field of Branch Conditional operations is five bits,
18 in scalar v3.0B this would select one bit of the 32 bit CR.
19 In SVP64 there are 16 32 bit CRs, containing 128 4-bit CR Fields.
20 Therefore, the 2 LSBs of `BI` select the bit from the CR, and the
21 top 3 bits are extended to either scalar or vector and to
22 select CR Fields 0..127 as specified
23 in SVP64 [[sv/svp64/appendix]]
24
25 When considering an "array" of branches, there are two useful modes:
26
27 * Branch takes place on the first CR test to succeed.
28 * Branch takes place only if **all** CR tests succeed
29 (including those where the predicate is masked out
30 and the corresponding CR Field is considered to be
31 set to `SNZ`)
32
33 In Vertical-First Mode, the `ALL` bit should
34 not be used. If set, behaviour is `UNDEFINED`.
35 (*The reason is that Vertical-First hints may permit
36 multiple elements up to hint length to be executed
37 in parallel, however the number is entirely up to
38 implementors. Attempting to test an arbitrary
39 indeterminate number of Conditional tests is impossible
40 to define, and efforts to enforce such defined behaviour
41 interfere with Vertical-First mode parallel behaviour.*)
42
43 `svstep` mode is only meaningful in Vertical-First Mode.
44 The CR Field selected by `BI` is updated based on
45 incrementing srcstep and dststep, and performing the
46 same tests as [[sv/svstep]], following which the Branch
47 Conditional instruction proceeds as normal (reading
48 and testing the CR bit just updated, if the relevant
49 `BO` bit is set). Note that the SVSTATE fields
50 are still updated, and the CR field still updated,
51 even if the `BO` bits do not require CR testing.
52
53 Predication in both INT and CR modes may be applied to
54 `sv.bc` and other SVP64 Branch Conditional operations,
55 exactly as they may be applied to other SVP64 operations.
56 When `sz` is zero, any masked-out Branch-element operations
57 are masked-out (not executed), exactly like all other SVP64
58 operations.
59
60 However when `sz` is non-zero, this normally requests insertion
61 of a zero in place of the input data, when the relevant predicate
62 mask bit is zero. This would mean that a zero is inserted in
63 place of `CR[BI+32]` for testing against `BO`, which may not
64 be desirable in all circumstances. Therefore, an extra field
65 is provided `SNZ`, which, if set, will insert a **one** in
66 place of a masked-out element instead of a zero.
67
68 (*Note: Both options are provided because it is useful to
69 deliberately cause the Branch-Conditional Vector testing
70 to fail at a specific point, controlled by the Predicate
71 mask. This is particularly useful in `VLSET` mode, which
72 will truncate SVSTATE.VL at the point of the first failed
73 test.*)
74
75 SVP64 RM `MODE` for Branch Conditional:
76
77 | 0-1 | 2 | 3 4 | description |
78 | --- | --- |---------|-------------------------- |
79 | 00 | SNZ | ALL sz | normal mode |
80 | 01 | VLI | ALL sz | VLSET mode |
81 | 10 | SNZ | ALL sz | svstep mode |
82 | 11 | VLI | ALL sz | svstep VLSET mode |
83
84 Fields:
85
86 * **sz** if predication is enabled will put 4 copies of `SNZ` in place of the src CR Field when the predicate bit is zero. otherwise the element is ignored or skipped, depending on context.
87 * **ALL** when set, all branch conditional tests must pass in order for
88 the branch to succeed.
89 * **VLI** In VLSET mode, VL is set equal (truncated) to the first branch
90 which succeeds. If VLI (Vector Length Inclusive) is clear, VL is truncated
91 to *exclude* the current element, otherwise it is included. SVSTATE.MVL is not changed.
92
93 svstep mode will run an increment of SVSTATE srcstep and dststep
94 (only meaningful in Vertical First Mode). Unlike `svstep.` however
95 which updates only CR0 with the testing of REMAP loop progress,
96 the CR Field is taken from the branch `BI` field, and updated
97 prior to proceeding to branch conditional testing.
98
99 Note that, interestingly, due to the useful side-effects of `VLSET` mode
100 and `svstep` mode it is actually useful to use Branch Conditional even
101 to perform no actual branch operation, i.e to point to the instruction
102 after the branch.
103
104 Available options to combine:
105
106 * `BO` to select whether the CR bit being tested is zero or nonzero
107 * `R30` and `~R30` and other predicate mask options including CR and
108 inverted CR bit testing
109 * `sz` and `SNZ` to insert either zeros or ones in place of masked-out
110 predicate bits
111 * `ALL` or `ANY` behaviour corresponding to `AND` of all tests and
112 `OR` of all tests, respectively.
113
114 Pseudocode for Horizontal-First Mode:
115
116 ```
117 if BO[0]:
118 cond_ok = 1
119 else
120 cond_ok = not SVRMmode.ALL
121 for srcstep in range(VL):
122 # select predicate bit or zero/one
123 if predicate[srcstep]:
124 testbit = CR[BI+32+srcstep*4]
125 else if not SVRMmode.sz:
126 continue
127 else
128 testbit = SVRMmode.SNZ
129 # actual element test here
130 el_cond_ok <- ¬(testbit ^ BO[1])
131 # merge in the test
132 if SVRMmode.ALL:
133 cond_ok &= el_cond_ok
134 else
135 cond_ok |= el_cond_ok
136 # test for VL to be set (and exit)
137 if ~el_cond_ok and VLSET
138 if SVRMmode.VLI
139 SVSTATE.VL = srcstep+1
140 else
141 SVSTATE.VL = srcstep
142 break
143 # early exit?
144 if SVRMmode.ALL:
145 if ~el_cond_ok:
146 break
147 else
148 if el_cond_ok:
149 break
150 ```