This patchset does the same thing we already did for pickNaN() to
pickNaNMulAdd() -- it replaces the compile-time ifdef ladder that
selected target-specific NaN propagation behaviour with checking some
runtime selectable settings in the float_status. The motivation is:
* 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
The current ifdef ladder merges two different kinds of
implementation-specific behaviour:
* handling of the (inf * zero) + NaN special case
* selection of a NaN to propagate when more than one input is a NaN
The refactoring splits these out into two different settings, because
what a target chose for one of them isn't correlated with its
choice on the other one.
Mostly this series is not intended to have any guest visible behaviour
changes. There is one exception: the "default implementation" at the
bottom of the old ifdef ladder did not raise Invalid for the (0 * inf)
+ NaN case. This is definitely not correct, and basically any targets
using that part of the ifdef ladder had a bug because they didn't
implement their actual correct behaviour. The architectures using the
default case are i386, hppa, sh4 and tricore, and they will now raise
the Invalid exception in this case. (I checked the architecture manuals
for those architectures and they all say it should raise Invalid.)
Fixing this bug in the first patch means we don't need to have runtime
selection of a behaviour that's not actually what these targets do.
(It also means we can reorder the code to avoid calling pickNaNMulAdd()
for any target which sets default_nan_mode, as we do for pickNaN().)
The rest of the patchset is structured like the pickNaN() refactoring
-- introduce the runtime selection field in the float_status word, but
leave the ifdef ladder in place as fallback, then convert each target
one at at time. We do the info-zero-nan setting first, then the NaN
propagation order setting.
Finally, once we're done we can remove the use_first_nan field, which
was an Xtensa-specific way to select the NaN propagation rules at
runtime.
Tested with 'make check-functional' and 'make check-avocado'
and 'make check-tcg'.
thanks
-- PMM
Peter Maydell (25):
fpu: handle raising Invalid for infzero in pick_nan_muladd
fpu: Check for default_nan_mode before calling pickNaNMulAdd
softfloat: Allow runtime choice of inf * 0 + NaN result
tests/fp: Explicitly set inf-zero-nan rule
target/arm: Set FloatInfZeroNaNRule explicitly
target/s390: Set FloatInfZeroNaNRule explicitly
target/ppc: Set FloatInfZeroNaNRule explicitly
target/mips: Set FloatInfZeroNaNRule explicitly
target/sparc: Set FloatInfZeroNaNRule explicitly
target/xtensa: Set FloatInfZeroNaNRule explicitly
target/x86: Set FloatInfZeroNaNRule explicitly
target/loongarch: Set FloatInfZeroNaNRule explicitly
target/hppa: Set FloatInfZeroNaNRule explicitly
softfloat: Allow runtime choice of NaN propagation for muladd
tests/fp: Explicitly set 3-NaN propagation rule
target/arm: Set Float3NaNPropRule explicitly
target/loongarch: Set Float3NaNPropRule explicitly
target/ppc: Set Float3NaNPropRule explicitly
target/s390x: Set Float3NaNPropRule explicitly
target/sparc: Set Float3NaNPropRule explicitly
target/mips: Set Float3NaNPropRule explicitly
target/xtensa: Set Float3NaNPropRule explicitly
target/i386: Set Float3NaNPropRule explicitly
target/hppa: Set Float3NaNPropRule explicitly
fpu: Remove use_first_nan field from float_status
include/fpu/softfloat-helpers.h | 27 +++-
include/fpu/softfloat-types.h | 61 ++++++++-
target/mips/fpu_helper.h | 13 ++
target/arm/cpu.c | 8 ++
target/hppa/fpu_helper.c | 10 ++
target/i386/tcg/fpu_helper.c | 9 ++
target/loongarch/tcg/fpu_helper.c | 6 +
target/mips/msa.c | 7 +
target/ppc/cpu_init.c | 15 +++
target/s390x/cpu.c | 3 +
target/sparc/cpu.c | 4 +
target/xtensa/cpu.c | 2 +
target/xtensa/fpu_helper.c | 3 +-
tests/fp/fp-bench.c | 6 +
tests/fp/fp-test.c | 6 +
fpu/softfloat-parts.c.inc | 19 ++-
fpu/softfloat-specialize.c.inc | 206 ++++++++----------------------
17 files changed, 236 insertions(+), 169 deletions(-)
--
2.34.1