mbox series

[for-10.0,00/25] fpu: Make pickNaNMulAdd behaviour runtime selected

Message ID 20241128104310.3452934-1-peter.maydell@linaro.org (mailing list archive)
Headers show
Series fpu: Make pickNaNMulAdd behaviour runtime selected | expand

Message

Peter Maydell Nov. 28, 2024, 10:42 a.m. UTC
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(-)