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.

Backports commit fbcc38e4cb1b539b8615ec9b0adc285351d77628 from qemu
This commit is contained in:
Max Filippov 2021-02-26 12:16:49 -05:00 committed by Lioncash
parent fee4c62fe4
commit d9e561ab2a

View file

@ -578,6 +578,32 @@ static int pickNaNMulAdd(FloatClass a_cls, FloatClass b_cls, FloatClass c_cls,
} else { } else {
return 1; 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 #else
/* A default implementation: prefer a to b to c. /* A default implementation: prefer a to b to c.
* This is unlikely to actually match any real implementation. * This is unlikely to actually match any real implementation.