fix form
[libreriscv.git] / openpower / transcendentals.mdwn
1 # DRAFT Scalar Transcendentals
2
3 Summary:
4
5 *This proposal extends Power ISA scalar floating point operations to
6 add IEEE754 transcendental functions (pow, log etc) and trigonometric
7 functions (sin, cos etc). These functions are also 98% shared with the
8 Khronos Group OpenCL Extended Instruction Set.*
9
10 Authors/Contributors:
11
12 * Luke Kenneth Casson Leighton
13 * Jacob Lifshay
14 * Dan Petroski
15 * Mitch Alsup
16 * Allen Baum
17 * Andrew Waterman
18 * Luis Vitorio Cargnini
19
20 [[!toc levels=2]]
21
22 See:
23
24 * <http://bugs.libre-soc.org/show_bug.cgi?id=127>
25 * <https://bugs.libre-soc.org/show_bug.cgi?id=899> transcendentals in simulator
26 * <https://bugs.libre-soc.org/show_bug.cgi?id=923> under review
27 * <https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html>
28 * [[power_trans_ops]] for opcode listing.
29
30 Extension subsets:
31
32 TODO: rename extension subsets -- we're not on RISC-V anymore.
33
34 * **Zftrans**: standard transcendentals (best suited to 3D)
35 * **ZftransExt**: extra functions (useful, not generally needed for 3D,
36 can be synthesised using Ztrans)
37 * **Ztrigpi**: trig. xxx-pi sinpi cospi tanpi
38 * **Ztrignpi**: trig non-xxx-pi sin cos tan
39 * **Zarctrigpi**: arc-trig. a-xxx-pi: atan2pi asinpi acospi
40 * **Zarctrignpi**: arc-trig. non-a-xxx-pi: atan2, asin, acos
41 * **Zfhyp**: hyperbolic/inverse-hyperbolic. sinh, cosh, tanh, asinh,
42 acosh, atanh (can be synthesised - see below)
43 * **ZftransAdv**: much more complex to implement in hardware
44 * **Zfrsqrt**: Reciprocal square-root.
45 * **Zfminmax**: Min/Max.
46
47 Minimum recommended requirements for 3D: Zftrans, Ztrignpi,
48 Zarctrignpi, with Ztrigpi and Zarctrigpi as augmentations.
49
50 Minimum recommended requirements for Mobile-Embedded 3D:
51 Ztrignpi, Zftrans, with Ztrigpi as an augmentation.
52
53 The Platform Requirements for 3D are driven by cost competitive
54 factors and it is the Trademarked Vulkan Specification that provides
55 clear direction for 3D GPU markets, but nothing else (IEEE754).
56 Implementors must note that minimum
57 Compliance with the Third Party Vulkan Specification (for power-area competitive
58 reasons with other 3D GPU manufacturers) will not qualify for strict IEEE754 accuracy Compliance or vice-versa.
59
60 Implementors **must** make it clear which accuracy level is implemented and provide a switching mechanism and throw Illegal Instruction traps if fully compliant accuracy cannot be achieved.
61 It is also the Implementor's responsibility to comply with all Third Party Certification Marks and Trademarks (Vulkan, OpenCL). Nothing in this specification in any way implies that any Third Party Certification Mark Compliance is granted, nullified, altered or overridden by this document.
62
63
64 # TODO:
65
66 * Decision on accuracy, moved to [[zfpacc_proposal]]
67 <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-August/002355.html>
68 * Errors **MUST** be repeatable.
69 * How about four Platform Specifications? 3DUNIX, UNIX, 3DEmbedded and Embedded?
70 <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-August/002361.html>
71 Accuracy requirements for dual (triple) purpose implementations must
72 meet the higher standard.
73 * Reciprocal Square-root is in its own separate extension (Zfrsqrt) as
74 it is desirable on its own by other implementors. This to be evaluated.
75
76 # Requirements <a name="requirements"></a>
77
78 This proposal is designed to meet a wide range of extremely diverse
79 needs, allowing implementors from all of them to benefit from the tools
80 and hardware cost reductions associated with common standards adoption
81 in Power ISA (primarily IEEE754 and Vulkan).
82
83 **The use-cases are**:
84
85 * 3D GPUs
86 * Numerical Computation
87 * (Potentially) A.I. / Machine-learning (1)
88
89 (1) although approximations suffice in this field, making it more likely
90 to use a custom extension. High-end ML would inherently definitely
91 be excluded.
92
93 **The power and die-area requirements vary from**:
94
95 * Ultra-low-power (smartwatches where GPU power budgets are in milliwatts)
96 * Mobile-Embedded (good performance with high efficiency for battery life)
97 * Desktop Computing
98 * Server / HPC / Supercomputing
99
100 **The software requirements are**:
101
102 * Full public integration into GNU math libraries (libm)
103 * Full public integration into well-known Numerical Computation systems (numpy)
104 * Full public integration into upstream GNU and LLVM Compiler toolchains
105 * Full public integration into Khronos OpenCL SPIR-V compatible Compilers
106 seeking public Certification and Endorsement from the Khronos Group
107 under their Trademarked Certification Programme.
108
109 # Proposed Opcodes vs Khronos OpenCL vs IEEE754-2019<a name="khronos_equiv"></a>
110
111 This list shows the (direct) equivalence between proposed opcodes,
112 their Khronos OpenCL equivalents, and their IEEE754-2019 equivalents.
113 98% of the opcodes in this proposal that are in the IEEE754-2019 standard
114 are present in the Khronos Extended Instruction Set.
115
116 See
117 <https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html>
118 and <https://ieeexplore.ieee.org/document/8766229>
119
120 * Special FP16 opcodes are *not* being proposed, except by indirect / inherent
121 use of elwidth overrides that is already present in the SVP64 Specification.
122 * "Native" opcodes are *not* being proposed: implementors will be expected
123 to use the (equivalent) proposed opcode covering the same function.
124 * "Fast" opcodes are *not* being proposed, because the Khronos Specification
125 fast\_length, fast\_normalise and fast\_distance OpenCL opcodes require
126 vectors (or can be done as scalar operations using other Power ISA
127 instructions).
128
129 The OpenCL FP32 opcodes are **direct** equivalents to the proposed opcodes.
130 Deviation from conformance with the Khronos Specification - including the
131 Khronos Specification accuracy requirements - is not an option, as it
132 results in non-compliance, and the vendor may not use the Trademarked words
133 "Vulkan" etc. in conjunction with their product.
134
135 IEEE754-2019 Table 9.1 lists "additional mathematical operations".
136 Interestingly the only functions missing when compared to OpenCL are
137 compound, exp2m1, exp10m1, log2p1, log10p1, pown (integer power) and powr.
138
139 |opcode |OpenCL FP32|OpenCL FP16|OpenCL native|IEEE754 |Power ISA |My 66000 ISA |
140 |------------|-----------|-----------|-------------|-------------- |------------------------|-------------|
141 |fsin |sin |half\_sin |native\_sin |sin |NONE |sin |
142 |fcos |cos |half\_cos |native\_cos |cos |NONE |cos |
143 |ftan |tan |half\_tan |native\_tan |tan |NONE |tan |
144 |NONE (1) |sincos |NONE |NONE |NONE |NONE | |
145 |fasin |asin |NONE |NONE |asin |NONE |asin |
146 |facos |acos |NONE |NONE |acos |NONE |acos |
147 |fatan |atan |NONE |NONE |atan |NONE |atan |
148 |fsinpi |sinpi |NONE |NONE |sinPi |NONE |sinpi |
149 |fcospi |cospi |NONE |NONE |cosPi |NONE |cospi |
150 |ftanpi |tanpi |NONE |NONE |tanPi |NONE |tanpi |
151 |fasinpi |asinpi |NONE |NONE |asinPi |NONE |asinpi |
152 |facospi |acospi |NONE |NONE |acosPi |NONE |acospi |
153 |fatanpi |atanpi |NONE |NONE |atanPi |NONE |atanpi |
154 |fsinh |sinh |NONE |NONE |sinh |NONE | |
155 |fcosh |cosh |NONE |NONE |cosh |NONE | |
156 |ftanh |tanh |NONE |NONE |tanh |NONE | |
157 |fasinh |asinh |NONE |NONE |asinh |NONE | |
158 |facosh |acosh |NONE |NONE |acosh |NONE | |
159 |fatanh |atanh |NONE |NONE |atanh |NONE | |
160 |fatan2 |atan2 |NONE |NONE |atan2 |NONE |atan2 |
161 |fatan2pi |atan2pi |NONE |NONE |atan2pi |NONE |atan2pi |
162 |frsqrt |rsqrt |half\_rsqrt|native\_rsqrt|rSqrt |fsqrte, fsqrtes (4) |rsqrt |
163 |fcbrt |cbrt |NONE |NONE |NONE (2) |NONE | |
164 |fexp2 |exp2 |half\_exp2 |native\_exp2 |exp2 |NONE |exp2 |
165 |flog2 |log2 |half\_log2 |native\_log2 |log2 |NONE |ln2 |
166 |fexpm1 |expm1 |NONE |NONE |expm1 |NONE |expm1 |
167 |flog1p |log1p |NONE |NONE |logp1 |NONE |logp1 |
168 |fexp |exp |half\_exp |native\_exp |exp |NONE |exp |
169 |flog |log |half\_log |native\_log |log |NONE |ln |
170 |fexp10 |exp10 |half\_exp10|native\_exp10|exp10 |NONE |exp10 |
171 |flog10 |log10 |half\_log10|native\_log10|log10 |NONE |log |
172 |fpow |pow |NONE |NONE |pow |NONE |pow |
173 |fpown |pown |NONE |NONE |pown |NONE | |
174 |fpowr |powr |half\_powr |native\_powr |powr |NONE | |
175 |frootn |rootn |NONE |NONE |rootn |NONE | |
176 |fhypot |hypot |NONE |NONE |hypot |NONE | |
177 |frecip |NONE |half\_recip|native\_recip|NONE (3) |fre, fres (4) |rcp |
178 |NONE |NONE |NONE |NONE |compound |NONE | |
179 |fexp2m1 |NONE |NONE |NONE |exp2m1 |NONE |exp2m1 |
180 |fexp10m1 |NONE |NONE |NONE |exp10m1 |NONE |exp10m1 |
181 |flog2p1 |NONE |NONE |NONE |log2p1 |NONE |ln2p1 |
182 |flog10p1 |NONE |NONE |NONE |log10p1 |NONE |logp1 |
183 |fminnum08 |fmin |fmin |NONE |minNum |xsmindp (5) | |
184 |fmaxnum08 |fmax |fmax |NONE |maxNum |xsmaxdp (5) | |
185 |fmin19 |fmin |fmin |NONE |minimum |NONE |fmin |
186 |fmax19 |fmax |fmax |NONE |maximum |NONE |fmax |
187 |fminnum19 |fmin |fmin |NONE |minimumNumber |vminfp (6), xsminjdp (5)| |
188 |fmaxnum19 |fmax |fmax |NONE |maximumNumber |vmaxfp (6), xsmaxjdp (5)| |
189 |fminc |fmin |fmin |NONE |NONE |xsmincdp (5) |fmin* |
190 |fmaxc |fmax |fmax |NONE |NONE |xsmaxcdp (5) |fmax* |
191 |fminmagnum08|minmag |minmag |NONE |minNumMag |NONE | |
192 |fmaxmagnum08|maxmag |maxmag |NONE |maxNumMag |NONE | |
193 |fminmag19 |minmag |minmag |NONE |minimumMagnitude |NONE | |
194 |fmaxmag19 |maxmag |maxmag |NONE |maximumMagnitude |NONE | |
195 |fminmagnum19|minmag |minmag |NONE |minimumMagnitudeNumber|NONE | |
196 |fmaxmagnum19|maxmag |maxmag |NONE |maximumMagnitudeNumber|NONE | |
197 |fminmagc |minmag |minmag |NONE |NONE |NONE | |
198 |fmaxmagc |maxmag |maxmag |NONE |NONE |NONE | |
199 |fmod |fmod |fmod | |NONE |NONE | |
200 |fremainder |remainder |remainder | |remainder |NONE | |
201
202 from Mitch Alsup:
203
204 * Brian's LLVM compiler converts fminc and fmaxc into fmin and fmax instructions
205 These are all IEEE 754-2019 compliant
206 These are native instructions not extensions
207 All listed functions are available in both F32 and F64 formats.
208 THere is some confusion (in my head) abouot fmin and fmax. I intend both instruction to perform 754-2019 semantics--
209 but I don know if this is minimum/maximum or minimumNumber/maximumNumber.
210 fmad and remainder are a 2-instruction sequence--don't know how to "edit it in"
211
212
213 Note (1) fsincos is macro-op fused (see below).
214
215 Note (2) synthesised in IEEE754-2019 as "rootn(x, 3)"
216
217 Note (3) synthesised in IEEE754-2019 using "1.0 / x"
218
219 Note (4) these are estimate opcodes that help accelerate
220 software emulation
221
222 Note (5) f64-only (though can be used on f32 stored in f64 format), requires VSX.
223
224 Note (6) 4xf32-only, requires VMX.
225
226 ## List of 2-arg opcodes
227
228 | opcode | Description | pseudocode | Extension |
229 | ------ | ---------------- | ---------------- | ----------- |
230 | fatan2 | atan2 arc tangent | FRT = atan2(FRB, FRA) | Zarctrignpi |
231 | fatan2pi | atan2 arc tangent / pi | FRT = atan2(FRB, FRA) / pi | Zarctrigpi |
232 | fpow | x power of y | FRT = pow(FRA, FRB) | ZftransAdv |
233 | fpown | x power of n (n int) | FRT = pow(FRA, RB) | ZftransAdv |
234 | fpowr | x power of y (x +ve) | FRT = exp(FRA log(FRB)) | ZftransAdv |
235 | frootn | x power 1/n (n integer) | FRT = pow(FRA, 1/RB) | ZftransAdv |
236 | fhypot | hypotenuse | FRT = sqrt(FRA^2 + FRB^2) | ZftransAdv |
237 | fminnum08 | IEEE 754-2008 minNum | FRT = minNum(FRA, FRB) (1) | Zfminmax |
238 | fmaxnum08 | IEEE 754-2008 maxNum | FRT = maxNum(FRA, FRB) (1) | Zfminmax |
239 | fmin19 | IEEE 754-2019 minimum | FRT = minimum(FRA, FRB) | Zfminmax |
240 | fmax19 | IEEE 754-2019 maximum | FRT = maximum(FRA, FRB) | Zfminmax |
241 | fminnum19 | IEEE 754-2019 minimumNumber | FRT = minimumNumber(FRA, FRB) | Zfminmax |
242 | fmaxnum19 | IEEE 754-2019 maximumNumber | FRT = maximumNumber(FRA, FRB) | Zfminmax |
243 | fminc | C ternary-op minimum | FRT = FRA \< FRB ? FRA : FRB | Zfminmax |
244 | fmaxc | C ternary-op maximum | FRT = FRA > FRB ? FRA : FRB | Zfminmax |
245 | fminmagnum08 | IEEE 754-2008 minNumMag | FRT = minmaxmag(FRA, FRB, False, fminnum08) (2)| Zfminmax |
246 | fmaxmagnum08 | IEEE 754-2008 maxNumMag | FRT = minmaxmag(FRA, FRB, True, fmaxnum08) (2) | Zfminmax |
247 | fminmag19 | IEEE 754-2019 minimumMagnitude | FRT = minmaxmag(FRA, FRB, False, fmin19) (2) | Zfminmax |
248 | fmaxmag19 | IEEE 754-2019 maximumMagnitude | FRT = minmaxmag(FRA, FRB, True, fmax19) (2) | Zfminmax |
249 | fminmagnum19 | IEEE 754-2019 minimumMagnitudeNumber | FRT = minmaxmag(FRA, FRB, False, fminnum19) (2)| Zfminmax |
250 | fmaxmagnum19 | IEEE 754-2019 maximumMagnitudeNumber | FRT = minmaxmag(FRA, FRB, True, fmaxnum19) (2) | Zfminmax |
251 | fminmagc | C ternary-op minimum magnitude | FRT = minmaxmag(FRA, FRB, False, fminc) (2) | Zfminmax |
252 | fmaxmagc | C ternary-op maximum magnitude | FRT = minmaxmag(FRA, FRB, True, fmaxc) (2) | Zfminmax |
253 | fmod | modulus | FRT = fmod(FRA, FRB) | ZftransExt |
254 | fremainder | IEEE 754 remainder | FRT = remainder(FRA, FRB) | ZftransExt |
255
256 Note (1): for the purposes of minNum/maxNum, -0.0 is defined to be less than +0.0. This is left unspecified in IEEE 754-2008.
257
258 Note (2): minmaxmag(x, y, cmp, fallback) is defined as:
259
260 ```python
261 def minmaxmag(x, y, is_max, fallback):
262 a = abs(x) < abs(y)
263 b = abs(x) > abs(y)
264 if is_max:
265 a, b = b, a # swap
266 if a:
267 return x
268 if b:
269 return y
270 # equal magnitudes, or NaN input(s)
271 return fallback(x, y)
272 ```
273
274 ## List of 1-arg transcendental opcodes
275
276 | opcode | Description | pseudocode | Extension |
277 | ------ | ---------------- | ---------------- | ---------- |
278 | frsqrt | Reciprocal Square-root | FRT = sqrt(FRA) | Zfrsqrt |
279 | fcbrt | Cube Root | FRT = pow(FRA, 1.0 / 3) | ZftransAdv |
280 | frecip | Reciprocal | FRT = 1.0 / FRA | Zftrans |
281 | fexp2m1 | power-2 minus 1 | FRT = pow(2, FRA) - 1.0 | ZftransExt |
282 | flog2p1 | log2 plus 1 | FRT = log(2, 1 + FRA) | ZftransExt |
283 | fexp2 | power-of-2 | FRT = pow(2, FRA) | Zftrans |
284 | flog2 | log2 | FRT = log(2. FRA) | Zftrans |
285 | fexpm1 | exponential minus 1 | FRT = pow(e, FRA) - 1.0 | ZftransExt |
286 | flog1p | log plus 1 | FRT = log(e, 1 + FRA) | ZftransExt |
287 | fexp | exponential | FRT = pow(e, FRA) | ZftransExt |
288 | flog | natural log (base e) | FRT = log(e, FRA) | ZftransExt |
289 | fexp10m1 | power-10 minus 1 | FRT = pow(10, FRA) - 1.0 | ZftransExt |
290 | flog10p1 | log10 plus 1 | FRT = log(10, 1 + FRA) | ZftransExt |
291 | fexp10 | power-of-10 | FRT = pow(10, FRA) | ZftransExt |
292 | flog10 | log base 10 | FRT = log(10, FRA) | ZftransExt |
293
294 ## List of 1-arg trigonometric opcodes
295
296 | opcode | Description | pseudocode | Extension |
297 | -------- | ------------------------ | ------------------------ | ----------- |
298 | fsin | sin (radians) | FRT = sin(FRA) | Ztrignpi |
299 | fcos | cos (radians) | FRT = cos(FRA) | Ztrignpi |
300 | ftan | tan (radians) | FRT = tan(FRA) | Ztrignpi |
301 | fasin | arcsin (radians) | FRT = asin(FRA) | Zarctrignpi |
302 | facos | arccos (radians) | FRT = acos(FRA) | Zarctrignpi |
303 | fatan | arctan (radians) | FRT = atan(FRA) | Zarctrignpi |
304 | fsinpi | sin times pi | FRT = sin(pi * FRA) | Ztrigpi |
305 | fcospi | cos times pi | FRT = cos(pi * FRA) | Ztrigpi |
306 | ftanpi | tan times pi | FRT = tan(pi * FRA) | Ztrigpi |
307 | fasinpi | arcsin / pi | FRT = asin(FRA) / pi | Zarctrigpi |
308 | facospi | arccos / pi | FRT = acos(FRA) / pi | Zarctrigpi |
309 | fatanpi | arctan / pi | FRT = atan(FRA) / pi | Zarctrigpi |
310 | fsinh | hyperbolic sin (radians) | FRT = sinh(FRA) | Zfhyp |
311 | fcosh | hyperbolic cos (radians) | FRT = cosh(FRA) | Zfhyp |
312 | ftanh | hyperbolic tan (radians) | FRT = tanh(FRA) | Zfhyp |
313 | fasinh | inverse hyperbolic sin | FRT = asinh(FRA) | Zfhyp |
314 | facosh | inverse hyperbolic cos | FRT = acosh(FRA) | Zfhyp |
315 | fatanh | inverse hyperbolic tan | FRT = atanh(FRA) | Zfhyp |
316
317 [[!inline pages="openpower/power_trans_ops" raw=yes ]]
318
319 # Subsets
320
321 The full set is based on the Khronos OpenCL opcodes. If implemented
322 entirely it would be too much for both Embedded and also 3D.
323
324 The subsets are organised by hardware complexity, need (3D, HPC), however
325 due to synthesis producing inaccurate results at the range limits,
326 the less common subsets are still required for IEEE754 HPC.
327
328 MALI Midgard, an embedded / mobile 3D GPU, for example only has the
329 following opcodes:
330
331 28 - fmin
332 2C - fmax
333 E8 - fatan_pt2
334 F0 - frcp (reciprocal)
335 F2 - frsqrt (inverse square root, 1/sqrt(x))
336 F3 - fsqrt (square root)
337 F4 - fexp2 (2^x)
338 F5 - flog2
339 F6 - fsin1pi
340 F7 - fcos1pi
341 F9 - fatan_pt1
342
343 These in FP32 and FP16 only: no FP64 hardware, at all.
344
345 Vivante Embedded/Mobile 3D (etnaviv
346 <https://github.com/laanwj/etna_viv/blob/master/rnndb/isa.xml>)
347 only has the following:
348
349 fmin/fmax (implemented using SELECT)
350 sin, cos2pi
351 cos, sin2pi
352 log2, exp
353 sqrt and rsqrt
354 recip.
355
356 It also has fast variants of some of these, as a CSR Mode.
357
358 AMD's R600 GPU (R600\_Instruction\_Set\_Architecture.pdf) and the
359 RDNA ISA (RDNA\_Shader\_ISA\_5August2019.pdf, Table 22, Section 6.3) have:
360
361 MIN/MAX/MIN_DX10/MAX_DX10
362 COS2PI (appx)
363 EXP2
364 LOG (IEEE754)
365 RECIP
366 RSQRT
367 SQRT
368 SIN2PI (appx)
369
370 AMD RDNA has F16 and F32 variants of all the above, and also has F64
371 variants of SQRT, RSQRT, MIN, MAX, and RECIP. It is interesting that even the
372 modern high-end AMD GPU does not have TAN or ATAN, where MALI Midgard
373 does.
374
375 Also a general point, that customised optimised hardware targetting
376 FP32 3D with less accuracy simply can neither be used for IEEE754 nor
377 for FP64 (except as a starting point for hardware or software driven
378 Newton Raphson or other iterative method).
379
380 Also in cost/area sensitive applications even the extra ROM lookup tables
381 for certain algorithms may be too costly.
382
383 These wildly differing and incompatible driving factors lead to the
384 subset subdivisions, below.
385
386 ## Transcendental Subsets
387
388 ### Zftrans
389
390 LOG2 EXP2 RECIP RSQRT
391
392 Zftrans contains the minimum standard transcendentals best suited to
393 3D. They are also the minimum subset for synthesising log10, exp10,
394 exp1m, log1p, the hyperbolic trigonometric functions sinh and so on.
395
396 They are therefore considered "base" (essential) transcendentals.
397
398 ### ZftransExt
399
400 LOG, EXP, EXP10, LOG10, LOGP1, EXP1M, fmod, fremainder
401
402 These are extra transcendental functions that are useful, not generally
403 needed for 3D, however for Numerical Computation they may be useful.
404
405 Although they can be synthesised using Ztrans (LOG2 multiplied
406 by a constant), there is both a performance penalty as well as an
407 accuracy penalty towards the limits, which for IEEE754 compliance is
408 unacceptable. In particular, LOG(1+FRA) in hardware may give much better
409 accuracy at the lower end (very small FRA) than LOG(FRA).
410
411 Their forced inclusion would be inappropriate as it would penalise
412 embedded systems with tight power and area budgets. However if they
413 were completely excluded the HPC applications would be penalised on
414 performance and accuracy.
415
416 Therefore they are their own subset extension.
417
418 ### Zfhyp
419
420 SINH, COSH, TANH, ASINH, ACOSH, ATANH
421
422 These are the hyperbolic/inverse-hyperbolic functions. Their use in 3D
423 is limited.
424
425 They can all be synthesised using LOG, SQRT and so on, so depend
426 on Zftrans. However, once again, at the limits of the range, IEEE754
427 compliance becomes impossible, and thus a hardware implementation may
428 be required.
429
430 HPC and high-end GPUs are likely markets for these.
431
432 ### ZftransAdv
433
434 CBRT, POW, POWN, POWR, ROOTN
435
436 These are simply much more complex to implement in hardware, and typically
437 will only be put into HPC applications.
438
439 Note that `pow` is commonly used in Blinn-Phong shading (the shading model used
440 by OpenGL 1.0 and commonly used by shader authors that need basic 3D graphics
441 with specular highlights), however it can be sufficiently emulated using
442 `pow(b, n) = exp2(n*log2(b))`.
443
444 * **Zfrsqrt**: Reciprocal square-root.
445
446 ## Trigonometric subsets
447
448 ### Ztrigpi vs Ztrignpi
449
450 * **Ztrigpi**: SINPI COSPI TANPI
451 * **Ztrignpi**: SIN COS TAN
452
453 Ztrignpi are the basic trigonometric functions through which all others
454 could be synthesised, and they are typically the base trigonometrics
455 provided by GPUs for 3D, warranting their own subset.
456
457 (programmerjake: actually, all other GPU ISAs mentioned in this document have sinpi/cospi or equivalent, and often not sin/cos, because sinpi/cospi are actually *waay* easier to implement because range reduction is simply a bitwise mask, whereas for sin/cos range reduction is a full division by pi)
458
459 (Mitch: My patent USPTO 10,761,806 shows that the above statement is no longer true.)
460
461
462 In the case of the Ztrigpi subset, these are commonly used in for loops
463 with a power of two number of subdivisions, and the cost of multiplying
464 by PI inside each loop (or cumulative addition, resulting in cumulative
465 errors) is not acceptable.
466
467 In for example CORDIC the multiplication by PI may be moved outside of
468 the hardware algorithm as a loop invariant, with no power or area penalty.
469
470 Again, therefore, if SINPI (etc.) were excluded, programmers would be
471 penalised by being forced to divide by PI in some circumstances. Likewise
472 if SIN were excluded, programmers would be penaslised by being forced
473 to *multiply* by PI in some circumstances.
474
475 Thus again, a slightly different application of the same general argument
476 applies to give Ztrignpi and Ztrigpi as subsets. 3D GPUs will almost
477 certainly provide both.
478
479 ### Zarctrigpi and Zarctrignpi
480
481 * **Zarctrigpi**: ATAN2PI ASINPI ACOSPI
482 * **Zarctrignpi**: ATAN2 ACOS ASIN
483
484 These are extra trigonometric functions that are useful in some
485 applications, but even for 3D GPUs, particularly embedded and mobile class
486 GPUs, they are not so common and so are typically synthesised, there.
487
488 Although they can be synthesised using Ztrigpi and Ztrignpi, there is,
489 once again, both a performance penalty as well as an accuracy penalty
490 towards the limits, which for IEEE754 compliance is unacceptable, yet
491 is acceptable for 3D.
492
493 Therefore they are their own subset extensions.
494
495 ### Zfminmax
496
497 * fminnum08 fmaxnum08
498 * fmin19 fmax19
499 * fminnum19 fmaxnum19
500 * fminc fmaxc
501 * fminmagnum08 fmaxmagnum08
502 * fminmag19 fmaxmag19
503 * fminmagnum19 fmaxmagnum19
504 * fminmagc fmaxmagc
505
506 These are commonly used for vector reductions, where having them be a single
507 instruction is critical. They are also commonly used in GPU shaders, HPC, and
508 general-purpose FP algorithms.
509
510 These min and max operations are quite cheap to implement hardware-wise,
511 being comparable in cost to fcmp + some muxes. They're all in one extension
512 because once you implement some of them, the rest require only slightly more
513 hardware complexity.
514
515 Therefore they are their own subset extension.
516
517 # Synthesis, Pseudo-code ops and macro-ops
518
519 The pseudo-ops are best left up to the compiler rather than being actual
520 pseudo-ops, by allocating one scalar FP register for use as a constant
521 (loop invariant) set to "1.0" at the beginning of a function or other
522 suitable code block.
523
524 * fsincos - fused macro-op between fsin and fcos (issued in that order).
525 * fsincospi - fused macro-op between fsinpi and fcospi (issued in that order).
526
527 fatanpi example pseudo-code:
528
529 fmvis ft0, 0x3F80 // upper bits of f32 1.0 (BF16)
530 fatan2pis FRT, FRA, ft0
531
532 Hyperbolic function example (obviates need for Zfhyp except for
533 high-performance or correctly-rounding):
534
535 ASINH( x ) = ln( x + SQRT(x**2+1))
536
537 `pow` sufficient for 3D Graphics:
538
539 pow(b, x) = exp2(x * log2(b))
540
541 # Evaluation and commentary
542
543 Moved to [[discussion]]
544