(no commit message)
[libreriscv.git] / openpower / transcendentals.mdwn
index 9af18c8a236cd33b87ccb96bd478db408fd73a2e..48b0b898baeea6c56395509a60ba490a665a4bcb 100644 (file)
@@ -1,10 +1,8 @@
-# Transcendental operations
-
-To be updated to OpenPOWER.
+# DRAFT Scalar Transcendentals
 
 Summary:
 
-*This proposal extends OpenPOWER scalar floating point operations to
+*This proposal extends Power ISA scalar floating point operations to
 add IEEE754 transcendental functions (pow, log etc) and trigonometric
 functions (sin, cos etc). These functions are also 98% shared with the
 Khronos Group OpenCL Extended Instruction Set.*
@@ -22,11 +20,9 @@ With thanks to:
 
 See:
 
-* <http://bugs.libre-riscv.org/show_bug.cgi?id=127>
+* <http://bugs.libre-soc.org/show_bug.cgi?id=127>
 * <https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html>
-* Discussion: <http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-August/002342.html>
-* [[rv_major_opcode_1010011]] for opcode listing.
-* [[zfpacc_proposal]] for accuracy settings proposal
+* [[power_trans_ops]] for opcode listing.
 
 Extension subsets:
 
@@ -45,7 +41,19 @@ Extension subsets:
 Minimum recommended requirements for 3D: Zftrans, Ztrignpi,
 Zarctrignpi, with Ztrigpi and Zarctrigpi as augmentations.
 
-Minimum recommended requirements for Mobile-Embedded 3D: Ztrignpi, Zftrans, with Ztrigpi as an augmentation.
+Minimum recommended requirements for Mobile-Embedded 3D:
+Ztrignpi, Zftrans, with Ztrigpi as an augmentation.
+
+The Platform Requirements for 3D are driven by cost competitive 
+factors and it is the Trademarked Vulkan Specification that provides
+clear direction for 3D GPU markets, but nothing else (IEEE754).
+Implementors must note that minimum
+Compliance with the Third Party Vulkan Specification (for power-area competitive
+reasons with other 3D GPU manufacturers) will not qualify for strict IEEE754 accuracy Compliance or vice-versa.
+
+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.
+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.
+
 
 # TODO:
 
@@ -61,16 +69,10 @@ Minimum recommended requirements for Mobile-Embedded 3D: Ztrignpi, Zftrans, with
 
 # Requirements <a name="requirements"></a>
 
-This proposal is designed to meet a wide range of extremely diverse needs,
-allowing implementors from all of them to benefit from the tools and hardware
-cost reductions associated with common standards adoption in RISC-V (primarily IEEE754 and Vulkan).
-
-**There are *four* different, disparate platform's needs (two new)**:
-
-* 3D Embedded Platform (new)
-* Embedded Platform
-* 3D UNIX Platform (new)
-* UNIX Platform
+This proposal is designed to meet a wide range of extremely diverse
+needs, allowing implementors from all of them to benefit from the tools
+and hardware cost reductions associated with common standards adoption
+in Power ISA (primarily IEEE754 and Vulkan).
 
 **The use-cases are**:
 
@@ -87,10 +89,7 @@ be excluded.
 * Ultra-low-power (smartwatches where GPU power budgets are in milliwatts)
 * Mobile-Embedded (good performance with high efficiency for battery life)
 * Desktop Computing
-* Server / HPC (2)
-
-(2) Supercomputing is left out of the requirements as it is traditionally
-covered by Supercomputer Vectorisation Standards (such as RVV).
+* Server / HPC / Supercomputing
 
 **The software requirements are**:
 
@@ -101,20 +100,6 @@ covered by Supercomputer Vectorisation Standards (such as RVV).
   seeking public Certification and Endorsement from the Khronos Group
   under their Trademarked Certification Programme.
 
-**The "contra"-requirements are**:
-
-  Ultra Low Power Embedded platforms (smart watches) are sufficiently
-  resource constrained that Vectorisation (of any kind) is likely to be
-  unnecessary and inappropriate.
-* The requirements are **not** for the purposes of developing a full custom
-  proprietary GPU with proprietary firmware driven by *hardware* centric
-  optimised design decisions as a priority over collaboration.
-* A full custom proprietary GPU ASIC Manufacturer *may* benefit from
-  this proposal however the fact that they typically develop proprietary
-  software that is not shared with the rest of the community likely to
-  use this proposal means that they have completely different needs.
-* This proposal is for *sharing* of effort in reducing development costs
-
 # Proposed Opcodes vs Khronos OpenCL vs IEEE754-2019<a name="khronos_equiv"></a>
 
 This list shows the (direct) equivalence between proposed opcodes,
@@ -122,20 +107,18 @@ their Khronos OpenCL equivalents, and their IEEE754-2019 equivalents.
 98% of the opcodes in this proposal that are in the IEEE754-2019 standard
 are present in the Khronos Extended Instruction Set.
 
-For RISCV opcode encodings see [[rv_major_opcode_1010011]]
-**TODO** replace with OpenPOWER
-
 See
 <https://www.khronos.org/registry/spir-v/specs/unified1/OpenCL.ExtendedInstructionSet.100.html>
 and <https://ieeexplore.ieee.org/document/8766229>
 
 * Special FP16 opcodes are *not* being proposed, except by indirect / inherent
-  use of the "fmt" field that is already present in the RISC-V Specification.
+  use of elwidth overrides that is already present in the SVP64 Specification.
 * "Native" opcodes are *not* being proposed: implementors will be expected
   to use the (equivalent) proposed opcode covering the same function.
 * "Fast" opcodes are *not* being proposed, because the Khronos Specification
   fast\_length, fast\_normalise and fast\_distance OpenCL opcodes require
-  vectors (or can be done as scalar operations using other RISC-V instructions).
+  vectors (or can be done as scalar operations using other Power ISA
+  instructions).
 
 The OpenCL FP32 opcodes are **direct** equivalents to the proposed opcodes.
 Deviation from conformance with the Khronos Specification - including the
@@ -147,51 +130,50 @@ IEEE754-2019 Table 9.1 lists "additional mathematical operations".
 Interestingly the only functions missing when compared to OpenCL are
 compound, exp2m1, exp10m1, log2p1, log10p1, pown (integer power) and powr.
 
-[[!table data="""
-opcode   | OpenCL FP32 | OpenCL FP16 | OpenCL native | OpenCL fast | IEEE754  | Power ISA |
-FSIN     | sin         | half\_sin   | native\_sin   | NONE        | sin      |           |
-FCOS     | cos         | half\_cos   | native\_cos   | NONE        | cos      |           |
-FTAN     | tan         | half\_tan   | native\_tan   | NONE        | tan      |           |
-NONE (1) | sincos      | NONE        | NONE          | NONE        | NONE     |           |
-FASIN    | asin        | NONE        | NONE          | NONE        | asin     |           |
-FACOS    | acos        | NONE        | NONE          | NONE        | acos     |           |
-FATAN    | atan        | NONE        | NONE          | NONE        | atan     |           |
-FSINPI   | sinpi       | NONE        | NONE          | NONE        | sinPi    |           |
-FCOSPI   | cospi       | NONE        | NONE          | NONE        | cosPi    |           |
-FTANPI   | tanpi       | NONE        | NONE          | NONE        | tanPi    |           |
-FASINPI  | asinpi      | NONE        | NONE          | NONE        | asinPi   |           |
-FACOSPI  | acospi      | NONE        | NONE          | NONE        | acosPi   |           |
-FATANPI  | atanpi      | NONE        | NONE          | NONE        | atanPi   |           |
-FSINH    | sinh        | NONE        | NONE          | NONE        | sinh     |           |
-FCOSH    | cosh        | NONE        | NONE          | NONE        | cosh     |           |
-FTANH    | tanh        | NONE        | NONE          | NONE        | tanh     |           |
-FASINH   | asinh       | NONE        | NONE          | NONE        | asinh    |           |
-FACOSH   | acosh       | NONE        | NONE          | NONE        | acosh    |           |
-FATANH   | atanh       | NONE        | NONE          | NONE        | atanh    |           |
-FATAN2   | atan2       | NONE        | NONE          | NONE        | atan2    |           |
-FATAN2PI | atan2pi     | NONE        | NONE          | NONE        | atan2pi  |           |
-FRSQRT   | rsqrt       | half\_rsqrt | native\_rsqrt | NONE        | rSqrt    |           |
-FCBRT    | cbrt        | NONE        | NONE          | NONE        | NONE (2) |           |
-FEXP2    | exp2        | half\_exp2  | native\_exp2  | NONE        | exp2     |           |
-FLOG2    | log2        | half\_log2  | native\_log2  | NONE        | log2     |           |
-FEXPM1   | expm1       | NONE        | NONE          | NONE        | expm1    |           |
-FLOG1P   | log1p       | NONE        | NONE          | NONE        | logp1    |           |
-FEXP     | exp         | half\_exp   | native\_exp   | NONE        | exp      |           |
-FLOG     | log         | half\_log   | native\_log   | NONE        | log      |           |
-FEXP10   | exp10       | half\_exp10 | native\_exp10 | NONE        | exp10    |           |
-FLOG10   | log10       | half\_log10 | native\_log10 | NONE        | log10    |           |
-FPOW     | pow         | NONE        | NONE          | NONE        | pow      |           |
-FPOWN    | pown        | NONE        | NONE          | NONE        | pown     |           |
-FPOWR    | powr        | half\_powr  | native\_powr  | NONE        | powr     |           |
-FROOTN   | rootn       | NONE        | NONE          | NONE        | rootn    |           |
-FHYPOT   | hypot       | NONE        | NONE          | NONE        | hypot    |           |
-FRECIP   | NONE        | half\_recip | native\_recip | NONE        | NONE (3) |           |
-NONE     | NONE        | NONE        | NONE          | NONE        | compound |           |
-NONE     | NONE        | NONE        | NONE          | NONE        | exp2m1   |           |
-NONE     | NONE        | NONE        | NONE          | NONE        | exp10m1  |           |
-NONE     | NONE        | NONE        | NONE          | NONE        | log2p1   |           |
-NONE     | NONE        | NONE        | NONE          | NONE        | log10p1  |           |
-"""]]
+|opcode  |OpenCL FP32|OpenCL FP16|OpenCL native|OpenCL fast|IEEE754 |Power ISA |
+|------- |-----------|-----------|-------------|-----------|------- |--------- |
+|FSIN    |sin        |half\_sin  |native\_sin  |NONE       |sin     |NONE      |
+|FCOS    |cos        |half\_cos  |native\_cos  |NONE       |cos     |NONE      |
+|FTAN    |tan        |half\_tan  |native\_tan  |NONE       |tan     |NONE      |
+|NONE (1)|sincos     |NONE       |NONE         |NONE       |NONE    |NONE      |
+|FASIN   |asin       |NONE       |NONE         |NONE       |asin    |NONE      |
+|FACOS   |acos       |NONE       |NONE         |NONE       |acos    |NONE      |
+|FATAN   |atan       |NONE       |NONE         |NONE       |atan    |NONE      |
+|FSINPI  |sinpi      |NONE       |NONE         |NONE       |sinPi   |NONE      |
+|FCOSPI  |cospi      |NONE       |NONE         |NONE       |cosPi   |NONE      |
+|FTANPI  |tanpi      |NONE       |NONE         |NONE       |tanPi   |NONE      |
+|FASINPI |asinpi     |NONE       |NONE         |NONE       |asinPi  |NONE      |
+|FACOSPI |acospi     |NONE       |NONE         |NONE       |acosPi  |NONE      |
+|FATANPI |atanpi     |NONE       |NONE         |NONE       |atanPi  |NONE      |
+|FSINH   |sinh       |NONE       |NONE         |NONE       |sinh    |NONE      |
+|FCOSH   |cosh       |NONE       |NONE         |NONE       |cosh    |NONE      |
+|FTANH   |tanh       |NONE       |NONE         |NONE       |tanh    |NONE      |
+|FASINH  |asinh      |NONE       |NONE         |NONE       |asinh   |NONE      |
+|FACOSH  |acosh      |NONE       |NONE         |NONE       |acosh   |NONE      |
+|FATANH  |atanh      |NONE       |NONE         |NONE       |atanh   |NONE      |
+|FATAN2  |atan2      |NONE       |NONE         |NONE       |atan2   |NONE      |
+|FATAN2PI|atan2pi    |NONE       |NONE         |NONE       |atan2pi |NONE      |
+|FRSQRT  |rsqrt      |half\_rsqrt|native\_rsqrt|NONE       |rSqrt   |fsqrte, fsqrtes (4)   |
+|FCBRT   |cbrt       |NONE       |NONE         |NONE       |NONE (2)|NONE      |
+|FEXP2   |exp2       |half\_exp2 |native\_exp2 |NONE       |exp2    |NONE      |
+|FLOG2   |log2       |half\_log2 |native\_log2 |NONE       |log2    |NONE      |
+|FEXPM1  |expm1      |NONE       |NONE         |NONE       |expm1   |NONE      |
+|FLOG1P  |log1p      |NONE       |NONE         |NONE       |logp1   |NONE      |
+|FEXP    |exp        |half\_exp  |native\_exp  |NONE       |exp     |NONE      |
+|FLOG    |log        |half\_log  |native\_log  |NONE       |log     |NONE      |
+|FEXP10  |exp10      |half\_exp10|native\_exp10|NONE       |exp10   |NONE      |
+|FLOG10  |log10      |half\_log10|native\_log10|NONE       |log10   |NONE      |
+|FPOW    |pow        |NONE       |NONE         |NONE       |pow     |NONE      |
+|FPOWN   |pown       |NONE       |NONE         |NONE       |pown    |NONE      |
+|FPOWR   |powr       |half\_powr |native\_powr |NONE       |powr    |NONE      |
+|FROOTN  |rootn      |NONE       |NONE         |NONE       |rootn   |NONE      |
+|FHYPOT  |hypot      |NONE       |NONE         |NONE       |hypot   |NONE      |
+|FRECIP  |NONE       |half\_recip|native\_recip|NONE       |NONE (3)|fre, fres (4)        |
+|NONE    |NONE       |NONE       |NONE         |NONE       |compound|NONE      |
+|FEXP2M1   |NONE       |NONE       |NONE         |NONE       |exp2m1  |NONE      |
+|FEXP10M1   |NONE       |NONE       |NONE         |NONE       |exp10m1 |NONE      |
+|FLOG2P1  |NONE       |NONE       |NONE         |NONE       |log2p1  |NONE      |
+|FLOG10P1  |NONE       |NONE       |NONE         |NONE       |log10p1 |NONE      |
 
 Note (1) FSINCOS is macro-op fused (see below).
 
@@ -199,59 +181,65 @@ Note (2) synthesised in IEEE754-2019 as "pown(x, 3)"
 
 Note (3) synthesised in IEEE754-2019 using "1.0 / x"
 
+Note (4) these are estimate opcodes that help accelerate
+software emulation
+
 ## List of 2-arg opcodes
 
-[[!table  data="""
-opcode    | Description            | pseudocode                 | Extension   |
-FATAN2    | atan2 arc tangent      | rd = atan2(rs2, rs1)       | Zarctrignpi |
-FATAN2PI  | atan2 arc tangent / pi | rd = atan2(rs2, rs1) / pi  | Zarctrigpi  |
-FPOW      | x power of y           | rd = pow(rs1, rs2)         | ZftransAdv  |
-FPOWN     | x power of n (n int)   | rd = pow(rs1, rs2)         | ZftransAdv  |
-FPOWR     | x power of y (x +ve)   | rd = exp(rs1 log(rs2))     | ZftransAdv  |
-FROOTN    | x power 1/n (n integer)| rd = pow(rs1, 1/rs2)       | ZftransAdv  |
-FHYPOT    | hypotenuse             | rd = sqrt(rs1^2 + rs2^2)   | ZftransAdv  |
-"""]]
+| opcode   | Description            | pseudocode                 | Extension   |
+| ------   | ----------------       | ----------------           | ----------- |
+| FATAN2   | atan2 arc tangent      | FRT = atan2(FRB, FRA)       | Zarctrignpi |
+| FATAN2PI | atan2 arc tangent / pi | FRT = atan2(FRB, FRA) / pi  | Zarctrigpi  |
+| FPOW     | x power of y           | FRT = pow(FRA, FRB)         | ZftransAdv  |
+| FPOWN    | x power of n (n int)   | FRT = pow(FRA, RB)         | ZftransAdv  |
+| FPOWR    | x power of y (x +ve)   | FRT = exp(FRA log(FRB))     | ZftransAdv  |
+| FROOTN   | x power 1/n (n integer)| FRT = pow(FRA, 1/RB)       | ZftransAdv  |
+| FHYPOT   | hypotenuse             | FRT = sqrt(FRA^2 + FRB^2)   | ZftransAdv  |
 
 ## List of 1-arg transcendental opcodes
 
-[[!table  data="""
-opcode   | Description              | pseudocode              | Extension  |
-FRSQRT   | Reciprocal Square-root   | rd = sqrt(rs1)          | Zfrsqrt    |
-FCBRT    | Cube Root                | rd = pow(rs1, 1.0 / 3)  | ZftransAdv |
-FRECIP   | Reciprocal               | rd = 1.0 / rs1          | Zftrans    |
-FEXP2    | power-of-2               | rd = pow(2, rs1)        | Zftrans    |
-FLOG2    | log2                     | rd = log(2. rs1)        | Zftrans    |
-FEXPM1   | exponential minus 1      | rd = pow(e, rs1) - 1.0  | ZftransExt |
-FLOG1P   | log plus 1               | rd = log(e, 1 + rs1)    | ZftransExt |
-FEXP     | exponential              | rd = pow(e, rs1)        | ZftransExt |
-FLOG     | natural log (base e)     | rd = log(e, rs1)        | ZftransExt |
-FEXP10   | power-of-10              | rd = pow(10, rs1)       | ZftransExt |
-FLOG10   | log base 10              | rd = log(10, rs1)       | ZftransExt |
-"""]]
+| opcode   | Description            | pseudocode                 | Extension   |
+| ------   | ----------------       | ----------------           | ----------- |
+| FRSQRT   | Reciprocal Square-root   | FRT = sqrt(FRA)          | Zfrsqrt    |
+| FCBRT    | Cube Root                | FRT = pow(FRA, 1.0 / 3)  | ZftransAdv |
+| FRECIP   | Reciprocal               | FRT = 1.0 / FRA          | Zftrans    |
+| FEXP2M1   | power-2 minus 1      | FRT = pow(2, FRA) - 1.0  | ZftransExt |
+| FLOG2P1   | log2 plus 1               | FRT = log(2, 1 + FRA)    | ZftransExt |
+| FEXP2    | power-of-2               | FRT = pow(2, FRA)        | Zftrans    |
+| FLOG2    | log2                     | FRT = log(2. FRA)        | Zftrans    |
+| FEXPM1   | exponential minus 1      | FRT = pow(e, FRA) - 1.0  | ZftransExt |
+| FLOG1P   | log plus 1               | FRT = log(e, 1 + FRA)    | ZftransExt |
+| FEXP     | exponential              | FRT = pow(e, FRA)        | ZftransExt |
+| FLOG     | natural log (base e)     | FRT = log(e, FRA)        | ZftransExt |
+| FEXP10M1   | power-10 minus 1      | FRT = pow(10, FRA) - 1.0  | ZftransExt |
+| FLOG10P1   | log10 plus 1               | FRT = log(10, 1 + FRA)    | ZftransExt |
+| FEXP10   | power-of-10              | FRT = pow(10, FRA)       | ZftransExt |
+| FLOG10   | log base 10              | FRT = log(10, FRA)       | ZftransExt |
 
 ## List of 1-arg trigonometric opcodes
 
-[[!table  data="""
-opcode      | Description              | pseudo-code             | Extension |
-FSIN        | sin (radians)            | rd = sin(rs1)           | Ztrignpi    |
-FCOS        | cos (radians)            | rd = cos(rs1)           | Ztrignpi    |
-FTAN        | tan (radians)            | rd = tan(rs1)           | Ztrignpi    |
-FASIN       | arcsin (radians)         | rd = asin(rs1)          | Zarctrignpi |
-FACOS       | arccos (radians)         | rd = acos(rs1)          | Zarctrignpi |
-FATAN       | arctan (radians)         | rd = atan(rs1)          | Zarctrignpi |
-FSINPI      | sin times pi             | rd = sin(pi * rs1)      | Ztrigpi |
-FCOSPI      | cos times pi             | rd = cos(pi * rs1)      | Ztrigpi |
-FTANPI      | tan times pi             | rd = tan(pi * rs1)      | Ztrigpi |
-FASINPI     | arcsin / pi              | rd = asin(rs1) / pi     | Zarctrigpi |
-FACOSPI     | arccos / pi              | rd = acos(rs1) / pi     | Zarctrigpi |
-FATANPI     | arctan / pi              | rd = atan(rs1) / pi     | Zarctrigpi |
-FSINH       | hyperbolic sin (radians) | rd = sinh(rs1)          | Zfhyp |
-FCOSH       | hyperbolic cos (radians) | rd = cosh(rs1)          | Zfhyp |
-FTANH       | hyperbolic tan (radians) | rd = tanh(rs1)          | Zfhyp |
-FASINH      | inverse hyperbolic sin   | rd = asinh(rs1)         | Zfhyp |
-FACOSH      | inverse hyperbolic cos   | rd = acosh(rs1)         | Zfhyp |
-FATANH      | inverse hyperbolic tan   | rd = atanh(rs1)         | Zfhyp |
-"""]]
+| opcode   | Description              | pseudocode               | Extension   |
+| -------- | ------------------------ | ------------------------ | ----------- |
+| FSIN     | sin (radians)            | FRT = sin(FRA)           | Ztrignpi    |
+| FCOS     | cos (radians)            | FRT = cos(FRA)           | Ztrignpi    |
+| FTAN     | tan (radians)            | FRT = tan(FRA)           | Ztrignpi    |
+| FASIN    | arcsin (radians)         | FRT = asin(FRA)          | Zarctrignpi |
+| FACOS    | arccos (radians)         | FRT = acos(FRA)          | Zarctrignpi |
+| FATAN    | arctan (radians)         | FRT = atan(FRA)          | Zarctrignpi |
+| FSINPI   | sin times pi             | FRT = sin(pi * FRA)      | Ztrigpi |
+| FCOSPI   | cos times pi             | FRT = cos(pi * FRA)      | Ztrigpi |
+| FTANPI   | tan times pi             | FRT = tan(pi * FRA)      | Ztrigpi |
+| FASINPI  | arcsin / pi              | FRT = asin(FRA) / pi     | Zarctrigpi |
+| FACOSPI  | arccos / pi              | FRT = acos(FRA) / pi     | Zarctrigpi |
+| FATANPI  | arctan / pi              | FRT = atan(FRA) / pi     | Zarctrigpi |
+| FSINH    | hyperbolic sin (radians) | FRT = sinh(FRA)          | Zfhyp |
+| FCOSH    | hyperbolic cos (radians) | FRT = cosh(FRA)          | Zfhyp |
+| FTANH    | hyperbolic tan (radians) | FRT = tanh(FRA)          | Zfhyp |
+| FASINH   | inverse hyperbolic sin   | FRT = asinh(FRA)         | Zfhyp |
+| FACOSH   | inverse hyperbolic cos   | FRT = acosh(FRA)         | Zfhyp |
+| FATANH   | inverse hyperbolic tan   | FRT = atanh(FRA)         | Zfhyp |
+
+[[!inline pages="openpower/power_trans_ops" raw=yes ]]
 
 # Subsets
 
@@ -275,7 +263,7 @@ following opcodes:
     F7 - fcos1pi
     F9 - fatan_pt1
 
-These in FP32 and FP16 only: no FP32 hardware, at all.
+These in FP32 and FP16 only: no FP64 hardware, at all.
 
 Vivante Embedded/Mobile 3D (etnaviv
 <https://github.com/laanwj/etna_viv/blob/master/rnndb/isa.xml>) 
@@ -338,8 +326,8 @@ needed for 3D, however for Numerical Computation they may be useful.
 Although they can be synthesised using Ztrans (LOG2 multiplied
 by a constant), there is both a performance penalty as well as an
 accuracy penalty towards the limits, which for IEEE754 compliance is
-unacceptable. In particular, LOG(1+rs1) in hardware may give much better
-accuracy at the lower end (very small rs1) than LOG(rs1).
+unacceptable. In particular, LOG(1+FRA) in hardware may give much better
+accuracy at the lower end (very small FRA) than LOG(FRA).
 
 Their forced inclusion would be inappropriate as it would penalise
 embedded systems with tight power and area budgets.  However if they
@@ -427,9 +415,8 @@ suitable code block.
 
 FATANPI example pseudo-code:
 
-    lui t0, 0x3F800 // upper bits of f32 1.0
-    fmv.x.s ft0, t0
-    fatan2pi.s rd, rs1, ft0
+    fmvis ft0, 0x3F800 // upper bits of f32 1.0 (BF16)
+    fatan2pis FRT, FRA, ft0
 
 Hyperbolic function example (obviates need for Zfhyp except for
 high-performance or correctly-rounding):
@@ -438,151 +425,5 @@ high-performance or correctly-rounding):
 
 # Evaluation and commentary
 
-This section will move later to discussion.
-
-## Reciprocal
-
-Used to be an alias. Some implementors may wish to implement divide as
-y times recip(x).
-
-Others may have shared hardware for recip and divide, others may not.
-
-To avoid penalising one implementor over another, recip stays.
-
-## To evaluate: should LOG be replaced with LOG1P (and EXP with EXPM1)?
-
-RISC principle says "exclude LOG because it's covered by LOGP1 plus an ADD".
-Research needed to ensure that implementors are not compromised by such
-a decision
-<http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-August/002358.html>
-
-> > correctly-rounded LOG will return different results than LOGP1 and ADD.
-> > Likewise for EXP and EXPM1
-
-> ok, they stay in as real opcodes, then.
-
-## ATAN / ATAN2 commentary
-
-Discussion starts here:
-<http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-August/002470.html>
-
-from Mitch Alsup:
-
-would like to point out that the general implementations of ATAN2 do a
-bunch of special case checks and then simply call ATAN.
-
-    double ATAN2( double y, double x )
-    {   // IEEE 754-2008 quality ATAN2
-
-        // deal with NANs
-        if( ISNAN( x )             ) return x;
-        if( ISNAN( y )             ) return y;
-
-        // deal with infinities
-        if( x == +∞    && |y|== +∞  ) return copysign(  π/4, y );
-        if( x == +∞                 ) return copysign(  0.0, y );
-        if( x == -∞    && |y|== +∞  ) return copysign( 3π/4, y );
-        if( x == -∞                 ) return copysign(    π, y );
-        if(               |y|== +∞  ) return copysign(  π/2, y );
-
-        // deal with signed zeros
-        if( x == 0.0  &&  y != 0.0 ) return copysign(  π/2, y );
-        if( x >=+0.0  &&  y == 0.0 ) return copysign(  0.0, y );
-        if( x <=-0.0  &&  y == 0.0 ) return copysign(    π, y );
-
-        // calculate ATAN2 textbook style
-        if( x  > 0.0               ) return     ATAN( |y / x| );
-        if( x  < 0.0               ) return π - ATAN( |y / x| );
-    }
-
-
-Yet the proposed encoding makes ATAN2 the primitive and has ATAN invent
-a constant and then call/use ATAN2.
-
-When one considers an implementation of ATAN, one must consider several
-ranges of evaluation::
-
-     x  [  -∞, -1.0]:: ATAN( x ) = -π/2 + ATAN( 1/x );
-     x  (-1.0, +1.0]:: ATAN( x ) =      + ATAN(   x );
-     x  [ 1.0,   +∞]:: ATAN( x ) = +π/2 - ATAN( 1/x );
-
-I should point out that the add/sub of π/2 can not lose significance
-since the result of ATAN(1/x) is bounded 0..π/2
-
-The bottom line is that I think you are choosing to make too many of
-these into OpCodes, making the hardware function/calculation unit (and
-sequencer) more complicated that necessary.
-
---------------------------------------------------------
-
-We therefore I think have a case for bringing back ATAN and including ATAN2.
-
-The reason is that whilst a microcode-like GPU-centric platform would
-do ATAN2 in terms of ATAN, a UNIX-centric platform would do it the other
-way round.
-
-(that is the hypothesis, to be evaluated for correctness. feedback requested).
-
-This because we cannot compromise or prioritise one platfrom's
-speed/accuracy over another. That is not reasonable or desirable, to
-penalise one implementor over another.
-
-Thus, all implementors, to keep interoperability, must both have both
-opcodes and may choose, at the architectural and routing level, which
-one to implement in terms of the other.
-
-Allowing implementors to choose to add either opcode and let traps sort it
-out leaves an uncertainty in the software developer's mind: they cannot
-trust the hardware, available from many vendors, to be performant right
-across the board.
-
-Standards are a pig.
-
----
-
-I might suggest that if there were a way for a calculation to be performed
-and the result of that calculation chained to a subsequent calculation
-such that the precision of the result-becomes-operand is wider than
-what will fit in a register, then you can dramatically reduce the count
-of instructions in this category while retaining
-
-acceptable accuracy:
-
-     z = x / y
-
-can be calculated as::
-
-     z = x * (1/y)
-
-Where 1/y has about 26-to-32 bits of fraction. No, it's not IEEE 754-2008
-accurate, but GPUs want speed and
-
-1/y is fully pipelined (F32) while x/y cannot be (at reasonable area). It
-is also not "that inaccurate" displaying 0.625-to-0.52 ULP.
-
-Given that one has the ability to carry (and process) more fraction bits,
-one can then do high precision multiplies of  π or other transcendental
-radixes.
-
-And GPUs have been doing this almost since the dawn of 3D.
-
-    // calculate ATAN2 high performance style
-    // Note: at this point x != y
-    //
-    if( x  > 0.0             )
-    {
-        if( y < 0.0 && |y| < |x| ) return - π/2 - ATAN( x / y );
-        if( y < 0.0 && |y| > |x| ) return       + ATAN( y / x );
-        if( y > 0.0 && |y| < |x| ) return       + ATAN( y / x );
-        if( y > 0.0 && |y| > |x| ) return + π/2 - ATAN( x / y );
-    }
-    if( x  < 0.0             )
-    {
-        if( y < 0.0 && |y| < |x| ) return + π/2 + ATAN( x / y );
-        if( y < 0.0 && |y| > |x| ) return + π   - ATAN( y / x );
-        if( y > 0.0 && |y| < |x| ) return + π   - ATAN( y / x );
-        if( y > 0.0 && |y| > |x| ) return +3π/2 + ATAN( x / y );
-    }
+Moved to [[discussion]]
 
-This way the adds and subtracts from the constant are not in a precision
-precarious position.