aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2020-07-03 17:02:47 -0700
committerMax Filippov <jcmvbkbc@gmail.com>2020-08-21 12:48:14 -0700
commitfbcc38e4cb1b539b8615ec9b0adc285351d77628 (patch)
tree48987e869ba351999cfb5ee61754f446de6882e5
parent913602e3ffe6bf50b869a14028a55cb267645ba3 (diff)
softfloat: add xtensa specialization for pickNaNMulAdd
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> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
-rw-r--r--fpu/softfloat-specialize.c.inc26
1 files changed, 26 insertions, 0 deletions
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc
index efbd163a2b..dc4ea33c09 100644
--- a/fpu/softfloat-specialize.c.inc
+++ b/fpu/softfloat-specialize.c.inc
@@ -586,6 +586,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.