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>
This commit is contained in:
Max Filippov 2020-07-03 17:02:47 -07:00
parent 913602e3ff
commit fbcc38e4cb
1 changed files with 26 additions and 0 deletions

View File

@ -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.