[v3,03/21] softfloat: add xtensa specialization for pickNaNMulAdd
diff mbox series

Message ID 20200708222101.24568-4-jcmvbkbc@gmail.com
State New
Headers show
Series
  • target/xtensa: implement double precision FPU
Related show

Commit Message

Max Filippov July 8, 2020, 10:20 p.m. UTC
pickNaNMulAdd logic on Xtensa is to apply pickNaN to the inputs of the
expression (a * b) + c. However if default NaN is produces as a result
of (a * b) calculation it is not considered when c is NaN.
So with two pickNaN variants there must be two pickNaNMulAdd variants.
In addition the invalid flag is always set when (a * b) produces NaN.

Cc: Peter Maydell <peter.maydell@linaro.org>
Cc: "Alex Bennée" <alex.bennee@linaro.org>
Cc: Richard Henderson <richard.henderson@linaro.org>
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
---
Changes v2->v3:
- handle infzero case in pickNaNMulAdd properly and reword commit
  message

 fpu/softfloat-specialize.inc.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Comments

Richard Henderson July 9, 2020, 12:03 a.m. UTC | #1
On 7/8/20 3:20 PM, Max Filippov wrote:
> pickNaNMulAdd logic on Xtensa is to apply pickNaN to the inputs of the
> expression (a * b) + c. However if default NaN is produces as a result
> of (a * b) calculation it is not considered when c is NaN.
> So with two pickNaN variants there must be two pickNaNMulAdd variants.
> In addition the invalid flag is always set when (a * b) produces NaN.
> 
> Cc: Peter Maydell <peter.maydell@linaro.org>
> Cc: "Alex Bennée" <alex.bennee@linaro.org>
> Cc: Richard Henderson <richard.henderson@linaro.org>
> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
> ---
> Changes v2->v3:
> - handle infzero case in pickNaNMulAdd properly and reword commit
>   message

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>


r~

Patch
diff mbox series

diff --git a/fpu/softfloat-specialize.inc.c b/fpu/softfloat-specialize.inc.c
index f519beca1b74..914deac46ecf 100644
--- a/fpu/softfloat-specialize.inc.c
+++ b/fpu/softfloat-specialize.inc.c
@@ -585,6 +585,32 @@  static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
     } else {
         return 1;
     }
+#elif defined(TARGET_XTENSA)
+    /*
+     * For Xtensa, the (inf,zero,nan) case sets InvalidOp and returns
+     * an input NaN if we have one (ie c).
+     */
+    if (infzero) {
+        float_raise(float_flag_invalid, status);
+        return 2;
+    }
+    if (status->use_first_nan) {
+        if (is_nan(a_cls)) {
+            return 0;
+        } else if (is_nan(b_cls)) {
+            return 1;
+        } else {
+            return 2;
+        }
+    } else {
+        if (is_nan(c_cls)) {
+            return 2;
+        } else if (is_nan(b_cls)) {
+            return 1;
+        } else {
+            return 0;
+        }
+    }
 #else
     /* A default implementation: prefer a to b to c.
      * This is unlikely to actually match any real implementation.