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:
parent
913602e3ff
commit
fbcc38e4cb
@ -586,6 +586,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.
|
||||||
|
Loading…
Reference in New Issue
Block a user