(no commit message)
[libreriscv.git] / openpower / sv / normal.mdwn
1 [[!tag standards]]
2
3 # Normal SVP64 Modes, for Arithmetic and Logical Operations
4
5 * <https://bugs.libre-soc.org/show_bug.cgi?id=574>
6 * <https://bugs.libre-soc.org/show_bug.cgi?id=558#c47>
7 * [[svp64]]
8
9 Normal SVP64 Mode covers Arithmetic and Logical operations
10 to provide suitable additional behaviour. The Mode
11 field is bits 19-23 of the [[svp64]] RM Field.
12
13 Table of contents:
14
15 [[!toc]]
16
17 # Mode
18
19 Mode is an augmentation of SV behaviour, providing additional
20 functionality. Some of these alterations are element-based (saturation), others involve post-analysis (predicate result) and others are Vector-based (mapreduce, fail-on-first).
21
22 [[sv/ldst]],
23 [[sv/cr_ops]] and [[sv/branches]] are covered separately: the following
24 Modes apply to Arithmetic and Logical SVP64 operations:
25
26 * **simple** mode is straight vectorisation. no augmentations: the vector comprises an array of independently created results.
27 * **ffirst** or data-dependent fail-on-first: see separate section. the vector may be truncated depending on certain criteria.
28 *VL is altered as a result*.
29 * **sat mode** or saturation: clamps each element result to a min/max rather than overflows / wraps. allows signed and unsigned clamping for both INT
30 and FP.
31 * **reduce mode**. if used correctly, a mapreduce (or a prefix sum)
32 is performed. see [[svp64/appendix]].
33 note that there are comprehensive caveats when using this mode.
34 * **pred-result** will test the result (CR testing selects a bit of CR and inverts it, just like branch conditional testing) and if the test fails it
35 is as if the
36 *destination* predicate bit was zero even before starting the operation.
37 When Rc=1 the CR element however is still stored in the CR regfile, even if the test failed. See appendix for details.
38 * **Pack/Unpack** mode, only available when SUBVL is vec2/3/4, performs
39 basic structure packing on sub-elements. Bits 4-5 (normally elwidth) are
40 taken up as Pack/Unpack bits. Saturation may be simultaneously enabled.
41
42 Note that ffirst and reduce modes are not anticipated to be high-performance in some implementations. ffirst due to interactions with VL, and reduce due to it requiring additional operations to produce a result. simple, saturate and pred-result are however inter-element independent and may easily be parallelised to give high performance, regardless of the value of VL.
43
44 The Mode table for Arithmetic and Logical operations
45 is laid out as follows:
46
47 | 0-1 | 2 | 3 4 | description |
48 | --- | --- |---------|-------------------------- |
49 | 00 | 0 | dz sz | simple mode |
50 | 00 | 1 | 0 RG | scalar reduce mode (mapreduce), SUBVL=1 |
51 | 00 | 1 | SVM 0 | subvector reduce mode, SUBVL>1 |
52 | 00 | 1 | SVM 1 | Pack/Unpack mode, SUBVL>1 |
53 | 01 | inv | CR-bit | Rc=1: ffirst CR sel |
54 | 01 | inv | VLi RC1 | Rc=0: ffirst z/nonz |
55 | 10 | N | dz sz | sat mode: N=0/1 u/s, SUBVL=1 |
56 | 10 | N | zz 0 | sat mode: N=0/1 u/s, SUBVL>1 |
57 | 10 | N | zz 1 | Pack/Unpack sat mode: N=0/1 u/s, SUBVL>1 |
58 | 11 | inv | CR-bit | Rc=1: pred-result CR sel |
59 | 11 | inv | zz RC1 | Rc=0: pred-result z/nonz |
60
61 Fields:
62
63 * **sz / dz** if predication is enabled will put zeros into the dest (or as src in the case of twin pred) when the predicate bit is zero. otherwise the element is ignored or skipped, depending on context.
64 * **zz**: both sz and dz are set equal to this flag
65 * **inv CR bit** just as in branches (BO) these bits allow testing of a CR bit and whether it is set (inv=0) or unset (inv=1)
66 * **RG** inverts the Vector Loop order (VL-1 downto 0) rather
67 than the normal 0..VL-1
68 * **SVM** sets "subvector" reduce mode
69 * **N** sets signed/unsigned saturation.
70 * **RC1** as if Rc=1, stores CRs *but not the result*
71 * **VLi** VL inclusive: in fail-first mode, the truncation of
72 VL *includes* the current element at the failure point rather
73 than excludes it from the count.
74
75 For LD/ST Modes, see [[sv/ldst]]. For Condition Registers
76 see [[sv/cr_ops]].
77 For Branch modes, see [[sv/branches]].
78
79 # Rounding, clamp and saturate
80
81 See [[av_opcodes]] for relevant opcodes and use-cases.
82
83 To help ensure that audio quality is not compromised by overflow,
84 "saturation" is provided, as well as a way to detect when saturation
85 occurred if desired (Rc=1). When Rc=1 there will be a *vector* of CRs,
86 one CR per element in the result (Note: this is different from VSX which
87 has a single CR per block).
88
89 When N=0 the result is saturated to within the maximum range of an
90 unsigned value. For integer ops this will be 0 to 2^elwidth-1. Similar
91 logic applies to FP operations, with the result being saturated to
92 maximum rather than returning INF, and the minimum to +0.0
93
94 When N=1 the same occurs except that the result is saturated to the min
95 or max of a signed result, and for FP to the min and max value rather
96 than returning +/- INF.
97
98 When Rc=1, the CR "overflow" bit is set on the CR associated with the
99 element, to indicate whether saturation occurred. Note that due to
100 the hugely detrimental effect it has on parallel processing, XER.SO is
101 **ignored** completely and is **not** brought into play here. The CR
102 overflow bit is therefore simply set to zero if saturation did not occur,
103 and to one if it did.
104
105 Note also that saturate on operations that set OE=1 must raise an
106 Illegal Instruction due to the conflicting use of the CR.so bit for
107 storing if
108 saturation occurred. Integer Operations that produce a Carry-Out (CA, CA32):
109 these two bits will be `UNDEFINED` if saturation is also requested.
110
111 Note that the operation takes place at the maximum bitwidth (max of
112 src and dest elwidth) and that truncation occurs to the range of the
113 dest elwidth.
114
115 *Programmer's Note: Post-analysis of the Vector of CRs to find out if any given element hit
116 saturation may be done using a mapreduced CR op (cror), or by using the
117 new crrweird instruction with Rc=1, which will transfer the required
118 CR bits to a scalar integer and update CR0, which will allow testing
119 the scalar integer for nonzero. see [[sv/cr_int_predication]]*
120
121 Pack/Unpack may be enabled at the same time as Saturation,
122 when SUBVL is vec2/3/4. This provides equivalent VSX `vpkpx` and other
123 operations.
124
125 # Reduce mode
126
127 Reduction in SVP64 is similar in essence to other Vector Processing
128 ISAs, but leverages the underlying scalar Base v3.0B operations.
129 Thus it is more a convention that the programmer may utilise to give
130 the appearance and effect of a Horizontal Vector Reduction. Due
131 to the unusual decoupling it is also possible to perform
132 prefix-sum (Fibonacci Series) in certain circumstances. Details are in the [[svp64/appendix]]
133
134 Reduce Mode should not be confused with Parallel Reduction [[sv/remap]].
135 As explained in the [[sv/appendix]] Reduce Mode switches off the check
136 which would normally stop looping if the result register is scalar.
137 Thus, the result scalar register, if also used as a source scalar,
138 may be used to perform sequential accumulation. This *deliberately*
139 sets up a chain
140 of Register Hazard Dependencies, whereas Parallel Reduce [[sv/remap]]
141 deliberately issues a Tree-Schedule of operations that may be parallelised.
142
143 # Fail-on-first
144
145 Data-dependent fail-on-first has two distinct variants: one for LD/ST,
146 the other for arithmetic operations (actually, CR-driven). Note in each
147 case the assumption is that vector elements are required to appear to be
148 executed in sequential Program Order. When REMAP is not active,
149 element 0 would be the first.
150
151 Data-driven (CR-driven) fail-on-first activates when Rc=1 or other
152 CR-creating operation produces a result (including cmp). Similar to
153 branch, an analysis of the CR is performed and if the test fails, the
154 vector operation terminates and discards all element operations at and
155 above the current one, and VL is truncated to either
156 the *previous* element or the current one, depending on whether
157 VLi (VL "inclusive") is set.
158
159 Thus the new VL comprises a contiguous vector of results,
160 all of which pass the testing criteria (equal to zero, less than zero etc
161 as defined by the CR-bit test).
162
163 The CR-based data-driven fail-on-first is "new" and not found in ARM
164 SVE or RVV. At the same time it is "old" because it is almost
165 identical to a generalised form of Z80's `CPIR` instruction.
166 It is extremely useful for reducing instruction count,
167 however requires speculative execution involving modifications of VL
168 to get high performance implementations. An additional mode (RC1=1)
169 effectively turns what would otherwise be an arithmetic operation
170 into a type of `cmp`. The CR is stored (and the CR.eq bit tested
171 against the `inv` field).
172 If the CR.eq bit is equal to `inv` then the Vector is truncated and
173 the loop ends.
174 Note that when RC1=1 the result elements are never stored, only the CR
175 Fields.
176
177 VLi is only available as an option when `Rc=0` (or for instructions
178 which do not have Rc). When set, the current element is always
179 also included in the count (the new length that VL will be set to).
180 This may be useful in combination with "inv" to truncate the Vector
181 to *exclude* elements that fail a test, or, in the case of implementations
182 of strncpy, to include the terminating zero.
183
184 In CR-based data-driven fail-on-first there is only the option to select
185 and test one bit of each CR (just as with branch BO). For more complex
186 tests this may be insufficient. If that is the case, a vectorised crop
187 such as crand, cror or [[sv/cr_int_predication]] crweirder may be used,
188 and ffirst applied to the crop instead of to
189 the arithmetic vector. Note that crops are covered by
190 the [[sv/cr_ops]] Mode format.
191
192 Two extremely important aspects of ffirst are:
193
194 * LDST ffirst may never set VL equal to zero. This because on the first
195 element an exception must be raised "as normal".
196 * CR-based data-dependent ffirst on the other hand **can** set VL equal
197 to zero. This is the only means in the entirety of SV that VL may be set
198 to zero (with the exception of via the SV.STATE SPR). When VL is set
199 zero due to the first element failing the CR bit-test, all subsequent
200 vectorised operations are effectively `nops` which is
201 *precisely the desired and intended behaviour*.
202
203 The second crucial aspect, compared to LDST Ffirst:
204
205 * LD/ST Failfirst may (beyond the initial first element
206 conditions) truncate VL for any architecturally
207 suitable reason. Beyond the first element LD/ST Failfirst is
208 arbitrarily speculative and 100% non-deterministic.
209 * CR-based data-dependent first on the other hand MUST NOT truncate VL
210 arbitrarily to a length decided by the hardware: VL MUST only be
211 truncated based explicitly on whether a test fails.
212 This because it is a precise Deterministic test on which algorithms
213 can and will will rely.
214
215 **Floating-point Exceptions**
216
217 When Floating-point exceptions are enabled VL must be truncated at
218 the point where the Exception appears not to have occurred. If `VLi`
219 is set then VL must include the faulting element. Although very strongly
220 discouraged the Exception Mode that permits Floating Point Exception
221 notification to arrive too late to unwind is permitted
222 (under protest, due it violating
223 the otherwise 100% Deterministic nature of Data-dependent Fail-first).the
224
225 **Use of lax FP Exception Notification Mode could result in parallel
226 computations proceeding with invalid results that have to be explicitly
227 detected, whereas with the strict FP Execption Mode enabled, FFirst
228 truncates VL, allows subsequent parallel computation to avoid
229 the exceptions entirely**
230
231 ## Data-dependent fail-first on CR operations (crand etc)
232
233 Operations that actually produce or alter CR Field as a result
234 have their own SVP64 Mode, described
235 in [[sv/cr_ops]].
236
237 # pred-result mode
238
239 This mode merges common CR testing with predication, saving on instruction
240 count. Below is the pseudocode excluding predicate zeroing and elwidth
241 overrides. Note that the pseudocode for [[sv/cr_ops]] is slightly different.
242
243 for i in range(VL):
244 # predication test, skip all masked out elements.
245 if predicate_masked_out(i):
246 continue
247 result = op(iregs[RA+i], iregs[RB+i])
248 CRnew = analyse(result) # calculates eq/lt/gt
249 # Rc=1 always stores the CR
250 if Rc=1 or RC1:
251 crregs[offs+i] = CRnew
252 # now test CR, similar to branch
253 if RC1 or CRnew[BO[0:1]] != BO[2]:
254 continue # test failed: cancel store
255 # result optionally stored but CR always is
256 iregs[RT+i] = result
257
258 The reason for allowing the CR element to be stored is so that
259 post-analysis of the CR Vector may be carried out. For example:
260 Saturation may have occurred (and been prevented from updating, by the
261 test) but it is desirable to know *which* elements fail saturation.
262
263 Note that RC1 Mode basically turns all operations into `cmp`. The
264 calculation is performed but it is only the CR that is written. The
265 element result is *always* discarded, never written (just like `cmp`).
266
267 Note that predication is still respected: predicate zeroing is slightly
268 different: elements that fail the CR test *or* are masked out are zero'd.
269
270 # Pack/Unpack Mode
271
272 Structured Pack/Unpack is similar to VSX `vpack` and `vunpack` except
273 generalised not only to a Schedule to be applied to any operation but
274 also extended to vec2/3/4.
275
276 Setting this mode changes the meaning of bits 4-5 in `RM` from being
277 `ELWIDTH` to a pair of Pack/Unpack bits. Thus it is not possible
278 to separately override source and destination elwidths at the same
279 time as use Pack/Unpack: the `SRC_ELWIDTH` bits (6-7) must be used as
280 both source and destination elwidth.
281
282 This was considered to be an acceptable
283 compromise. If separate elwidths are required and Pack/Unpack
284 needed without needing to perform a widening or narrowing register
285 move then [[sv/remap]] may be used: Matrix Mode may perform the
286 same operation (but is more costly to set up).
287 See [[sv/svp64/appendix]] for details on how Pack/Unpack
288 is implemented.