(no commit message)
[libreriscv.git] / openpower / sv / normal.mdwn
1 # Normal SVP64 Modes, for Arithmetic and Logical Operations
2
3 * <https://bugs.libre-soc.org/show_bug.cgi?id=574>
4 * <https://bugs.libre-soc.org/show_bug.cgi?id=558#c47>
5 * <https://bugs.libre-soc.org/show_bug.cgi?id=936> write on failfirst
6 * [[svp64]]
7
8 Normal SVP64 Mode covers Arithmetic and Logical operations
9 to provide suitable additional behaviour. The Mode
10 field is bits 19-23 of the [[svp64]] RM Field.
11
12 Table of contents:
13
14 [[!toc]]
15
16 ## Mode
17
18 Mode is an augmentation of SV behaviour, providing additional
19 functionality. Some of these alterations are element-based (saturation),
20 others are Vector-based (mapreduce, fail-on-first).
21
22 [[sv/ldst]], [[sv/cr_ops]] and [[sv/branches]] are covered separately:
23 the following Modes apply to Arithmetic and Logical SVP64 operations:
24
25 * **simple** mode is straight vectorization. No augmentations: the
26 vector comprises an array of independently created results.
27 * **ffirst** or data-dependent fail-on-first: see separate section.
28 The vector may be truncated depending on certain criteria.
29 *VL is altered as a result*.
30 * **sat mode** or saturation: clamps each element result to a min/max
31 rather than overflows / wraps. Allows signed and unsigned clamping
32 for both INT and FP.
33 * **reduce mode**. If used correctly, a mapreduce (or a prefix sum)
34 is performed. See [[svp64/appendix]].
35 Note that there are comprehensive caveats when using this mode,
36 and it should not be confused with the Parallel Reduction [[sv/remap]].
37 Also care is needed with `hphint`.
38
39 Note that ffirst and reduce modes are not anticipated to be
40 high-performance in some implementations. ffirst due to interactions
41 with VL, and reduce due to it creating overlapping operations in
42 many of its uses. simple and saturate are however inter-element
43 independent and may easily be parallelised to give high performance,
44 regardless of the value of VL.
45
46 The Mode table for Arithmetic and Logical operations,
47 being bits 19-23 of SVP64 `RM`, is laid out as
48 follows:
49
50 | 0-1 | 2 | 3 4 | description |
51 | ------ | --- |---------|----------------------------------|
52 | 0 0 | 0 | dz sz | simple mode |
53 | 0 0 | 1 | RG 0 | scalar reduce mode (mapreduce) |
54 | 0 0 | 1 | / 1 | reserved |
55 | 1 0 | N | dz sz | sat mode: N=0/1 u/s |
56 | VLi 1 | inv | CR-bit | Rc=1: ffirst CR sel |
57 | VLi 1 | inv | zz RC1 | Rc=0: ffirst z/nonz |
58
59 Fields:
60
61 * **sz / dz** source-zeroing, destination-zeroing.
62 if predication is enabled will put zeros into the dest
63 (or as src in the case of twin pred) when the predicate bit is zero.
64 Otherwise the element is ignored or skipped, depending on context.
65 * **zz**: both sz and dz are set equal to this flag
66 * **inv CR bit** just as in branches (BO) these bits allow testing of
67 a CR bit and whether it is set (inv=0) or unset (inv=1)
68 * **RG** inverts the Vector Loop order (VL-1 downto 0) rather
69 than the normal 0..VL-1
70 * **N** sets signed/unsigned saturation.
71 * **RC1** as if Rc=1, on operations that do not have it (typically Logical)
72 * **VLi** VL inclusive: in fail-first mode, the truncation of
73 VL *includes* the current element at the failure point rather
74 than excludes it from the count.
75
76 For LD/ST Modes, see [[sv/ldst]]. For Condition Registers see
77 [[sv/cr_ops]]. 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 for example that audio quality is not compromised by
84 overflow, "saturation" is provided, as well as a way to detect when
85 saturation occurred if desired (Rc=1). When Rc=1 there will be a *vector*
86 of CRs, one CR per element in the result (Note: this is different from
87 VSX which 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
99 the element, to indicate whether saturation occurred. Note that
100 due to the hugely detrimental effect it has on parallel processing,
101 XER.SO is **ignored** completely and is **not** brought into play here.
102 The CR overflow bit is therefore simply set to zero if saturation did
103 not occur, and to one if it did. This behaviour (ignoring XER.SO) is
104 actually optional in the SFFS Compliancy Subset: for SVP64 it is made
105 mandatory *but only on Vectorized instructions*.
106
107 Note also that saturate on operations that set OE=1 must raise an Illegal
108 Instruction due to the conflicting use of the CR.so bit for storing
109 if saturation occurred. Vectorized Integer Operations that produce a
110 Carry-Out (CA, CA32): these two bits will be `UNDEFINED` if saturation
111 is also requested.
112
113 Note that the operation takes place at the maximum bitwidth (max of
114 src and dest elwidth) and that truncation occurs to the range of the
115 dest elwidth.
116
117 *Programmer's Note: Post-analysis of the Vector of CRs to find out if any
118 given element hit saturation may be done using a mapreduced CR op (cror),
119 or by using the new crrweird instruction with Rc=1, which will transfer
120 the required CR bits to a scalar integer and update CR0, which will allow
121 testing the scalar integer for nonzero. See [[sv/cr_int_predication]].
122 Alternatively, a Data-Dependent Fail-First may be used to truncate the
123 Vector Length to non-saturated elements, greatly increasing the productivity
124 of parallelised inner hot-loops.*
125
126 ## Reduce mode
127
128 Reduction in SVP64 is similar in essence to other Vector Processing ISAs,
129 but leverages the underlying scalar Base v3.0B operations. Thus it is
130 more a convention that the programmer may utilise to give the appearance
131 and effect of a Horizontal Vector Reduction. Due to the unusual decoupling
132 it is also possible to perform prefix-sum (Fibonacci Series) in certain
133 circumstances. Details are in the [[svp64/appendix]]
134
135 Reduce Mode should not be confused with Parallel Reduction [[sv/remap]].
136 As explained in the [[sv/svp64/appendix]] Reduce Mode switches off the check
137 which would normally stop looping if the result register is scalar.
138 Thus, the result scalar register, if also used as a source scalar,
139 may be used to perform sequential accumulation. This *deliberately*
140 sets up a chain of Register Hazard Dependencies
141 (which advanced hardware may optimise out), whereas Parallel Reduce
142 [[sv/remap]] deliberately issues a Tree-Schedule of operations that may
143 be parallelised.
144
145 *Hardware architectural note: implementations may optimise out the Hazard
146 Dependency chain as long as Sequential Program Execution Order is preserved.
147 Easy examples include Reduction on Logical OR or AND operations.*
148
149 **Horizontal Parallelism Hint**
150
151 `SVSTATE.hphint` declares to hardware that groups of elements up to this
152 size are 100% independent (free of all Hazards inter-element but not inter-group).
153 With Reduction literally creating Dependency
154 Hazards on every element-level sub-instruction it is pretty clear that setting
155 `hphint` *at all* would cause data corruption. However `sv.add *r0, *r4, *r0`
156 for example clearly leaves room for four parallel elements. Programmers must
157 be aware of this and exercise caution.
158
159 ## Data-dependent Fail-on-first
160
161 Data-dependent fail-on-first is CR-field-driven and is completely separate
162 and distinct from LD/ST Fail-First (also known as Fault-First). Note in
163 each case the assumption is that vector elements are required to appear
164 to be executed in sequential Program Order. When REMAP is not active,
165 element 0 would be the first.
166
167 Arithmetic/Logical Data-driven (CR-field-driven) fail-on-first performs a
168 test ofvthe result, similar to
169 Branch-Conditional `BO` field testing, and if the test fails, the
170 Vector Loop operation terminates, and VL is truncated to either the *previous*
171 element or the current one, depending on whether VLi (VL "inclusive")
172 is clear or set, respectively.
173
174 Thus the new VL comprises a contiguous vector of results, all of which
175 pass the testing criteria (equal to zero, less than zero etc as defined
176 by the CR-bit test). When Rc=1 the Condition Regster Field for
177 the element just tested is always written out (regardless of VLi).
178
179 * **VLi=0** Only elements that passed the test are written out. When Rc=1
180 the co-result CR Field element is written out (even if the current test failed).
181 Vector length is truncated to "elements that passed"
182 * **VLi=1** Elements that were *tested* are written out. When Rc=1
183 the co-result CR Field element is written out.
184 Vector length is truncated to "elements tested up to the first fail point"
185
186 *Note: when VLi is clear, the behaviour at first seems counter-intuitive.
187 A result is calculated but if the test fails it is prohibited from being
188 actually written. This becomes intuitive again when it is remembered
189 that the length that VL is set to is the number of *written* elements, and
190 only when VLI is set will the current element be included in that count.*
191
192 The CR-based data-driven fail-on-first is "new" and not found in ARM SVE
193 or RVV. At the same time it is "old" because it is almost identical to
194 a generalised form of Z80's `CPIR` instruction. It is extremely useful
195 for reducing instruction count, however requires speculative execution
196 involving modifications of VL to get high performance implementations.
197 An additional mode (RC1=1) allows instructions that would not normally
198 have an Rc=1 mode to at least be tested for zero or non-zero.
199 The CR is stored (and the
200 CR.eq bit tested against the `inv` field). If the CR.eq bit is equal to
201 `inv` then the Vector is truncated and the loop ends.
202
203 VLi is only available as an option when `Rc=0` (or for instructions
204 which do not have Rc). When set, the current element is always also
205 included in the count (the new length that VL will be set to). This may
206 be useful in combination with "inv" to truncate the Vector to *exclude*
207 elements that fail a test, or, in the case of implementations of strncpy,
208 to include the terminating zero.
209
210 In CR-based data-driven fail-on-first there is only the option to select
211 and test one bit of each CR (just as with branch BO). For more complex
212 tests this may be insufficient. If that is the case, a vectorized crop
213 such as crand, cror or [[sv/cr_int_predication]] crweirder may be used,
214 and ffirst applied to the crop instead of to the arithmetic vector. Note
215 that crops are covered by the [[sv/cr_ops]] Mode format.
216
217 Use of Fail-on-first with Vertical-First Mode is not prohibited but is
218 not really recommended. The effect of truncating VL
219 may have unintended and unexpected consequences on subsequent instructions.
220 VLi set will be fine: it is when VLi is clear that problems may be faced.
221
222 *Programmer's note: `VLi` is only accessible in normal operations which in
223 turn limits the CR field bit-testing to only `EQ/NE`. [[sv/cr_ops]] are
224 not so limited. Thus it is possible to use for example `sv.cror/ff=gt/vli
225 *0,*0,*0`, which is not a `nop` because it allows Fail-First Mode to
226 perform a test and truncate VL.*
227
228 *Hardware implementor's note: effective Sequential Program Order must
229 be preserved. Speculative Execution is perfectly permitted as long as
230 the speculative elements are held back from writing to register files
231 (kept in Resevation Stations), until such time as the relevant CR Field
232 bit(s) has been analysed. All Speculative elements sequentially beyond
233 the test-failure point **MUST** be cancelled. This is no different from
234 standard Out-of-Order Execution and the modification effort to efficiently
235 support Data-Dependent Fail-First within a pre-existing Multi-Issue
236 Out-of-Order Engine is anticipated to be minimal. In-Order systems on
237 the other hand are expected, unavoidably, to be low-performance unless they
238 also make use of `SVSTATE.hphint` and exploit it to safely implement rudimentary
239 Shadow-Commit-Hold normally only found in Out-of-Order systems*.
240
241 Two extremely important aspects of ffirst are:
242
243 * LDST ffirst may never set VL equal to zero. This because on the first
244 element an exception must be raised "as normal".
245 * CR-based data-dependent ffirst on the other hand **can** set VL equal
246 to zero. When VL is set
247 zero due to the first element failing the CR bit-test, all subsequent
248 vectorized operations are effectively `nops` which is
249 *precisely the desired and intended behaviour*.
250
251 The second crucial aspect, compared to LDST Ffirst:
252
253 * LD/ST Failfirst may (beyond the initial first element
254 conditions) truncate VL for any architecturally suitable reason. Beyond
255 the first element LD/ST Failfirst is arbitrarily speculative and 100%
256 non-deterministic.
257 * CR-based data-dependent first on the other hand MUST NOT truncate VL
258 arbitrarily to a length decided by the hardware: VL MUST only be
259 truncated based explicitly on whether a test fails. This because it is
260 a precise Deterministic test on which algorithms can and will rely.
261
262 **Floating-point Exceptions**
263
264 When Floating-point exceptions are enabled VL must be truncated at
265 the point where the Exception appears not to have occurred. If `VLi`
266 is set then VL must include the faulting element, and thus the faulting
267 element will always raise its exception. If however `VLi` is clear then
268 VL **excludes** the faulting element and thus the exception will **never**
269 be raised.
270
271 Although very strongly discouraged the Exception Mode that permits
272 Floating Point Exception notification to arrive too late to unwind
273 is permitted (under protest, due it violating the otherwise 100%
274 Deterministic nature of Data-dependent Fail-first).
275
276 **Use of lax FP Exception Notification Mode could result in parallel
277 computations proceeding with invalid results that have to be explicitly
278 detected, whereas with the strict FP Execption Mode enabled, FFirst
279 truncates VL, allows subsequent parallel computation to avoid the
280 exceptions entirely**
281
282 ## Data-dependent fail-first on CR operations (crand etc)
283
284 Operations that actually produce or alter CR Field as a result have
285 their own SVP64 Mode, described in [[sv/cr_ops]].
286
287 [[!tag standards]]
288
289 --------
290
291 \newpage{}
292