From d9e561ab2aacacd26edc19fd45e48e4635be7a2f Mon Sep 17 00:00:00 2001 From: Max Filippov Date: Fri, 26 Feb 2021 12:16:49 -0500 Subject: [PATCH] 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 --- qemu/fpu/softfloat-specialize.inc.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/qemu/fpu/softfloat-specialize.inc.c b/qemu/fpu/softfloat-specialize.inc.c index 28b6865a..0964a542 100644 --- a/qemu/fpu/softfloat-specialize.inc.c +++ b/qemu/fpu/softfloat-specialize.inc.c @@ -578,6 +578,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.