IEEE 758 does not define a fixed rule for which NaN to pick as the
result if both operands of a 3-operand fused multiply-add operation
are NaNs. As a result different architectures have ended up with
different rules for propagating NaNs.
QEMU currently hardcodes the NaN propagation logic into the binary
because pickNaNMulAdd() has an ifdef ladder for different targets.
We want to make the propagation rule instead be selectable at
runtime, because:
* this will let us have multiple targets in one QEMU binary
* the Arm FEAT_AFP architectural feature includes letting
the guest select a NaN propagation rule at runtime
In this commit we add an enum for the propagation rule, the field in
float_status, and the corresponding getters and setters. We change
pickNaNMulAdd to honour this, but because all targets still leave
this field at its default 0 value, the fallback logic will pick the
rule type with the old ifdef ladder.
It's valid not to set a propagation rule if default_nan_mode is
enabled, because in that case there's no need to pick a NaN; all the
callers of pickNaNMulAdd() catch this case and skip calling it.
Signed-off-by: Peter Maydell<peter.maydell@linaro.org>
---
include/fpu/softfloat-helpers.h | 11 +++
include/fpu/softfloat-types.h | 55 +++++++++++
fpu/softfloat-specialize.c.inc | 167 ++++++++------------------------
3 files changed, 107 insertions(+), 126 deletions(-)