mbox series

[v2,for-10.0,00/54] fpu: Remove pickNaNMulAdd, default-NaN ifdefs

Message ID 20241202131347.498124-1-peter.maydell@linaro.org
Headers show
Series fpu: Remove pickNaNMulAdd, default-NaN ifdefs | expand

Message

Peter Maydell Dec. 2, 2024, 1:12 p.m. UTC
(Apologies for this patchset being both big and having a wide CC list;
the good news is that this is the last lot of fpu ifdef cleanup that
needs to touch all the targets.)

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
This is patches 1-26 (which were in the v1 of this series).

It then does a similar thing for making targets select the default
NaN value at runtime rather than relying on a compile-time ifdef.
This is patches 34-54, which are new in v2.

In between those two, patches 27-33 do some minor cleanup:
 * prefer to initialize scratch float_status structs from the target's
   env->fp_status rather than as all-zeroes, so that when we add
   new config fields to float_status we don't need to also remember
   to update half a dozen scratch float_status structs too.
   (Some still remain in target/riscv where plumbing in the env
   pointer through the macro magic seemed more effort than it was worth.)
 * remove an ifdef in floatx80_default_nan() by creating the NaN value
   from parts64_default_nan() in the same way we already do for
   the 128-bit NaN

This is intended to be a no-behaviour-change refactor, except for:
 * the arm linux-user nwfpe handling will change its floatx80
   default NaN value
 * hppa, i386, sh4, tricore now correctly raise Invalid for
   (0 * inf) + NaN

Changes v1->v2:
 * update comments on x86 to include the spec references rather
   than TODO notes to check the spec
 * fixed clash of float_infzeronan_none and float_infzeronan_dnan_never
   values
 * patches 14 and 27-54 are new
 * patch 15 is a rework of the old patch 14 to follow RTH's suggestion
   to make it data driven rather than a big switch statement

(The remaining ifdefs in fpu/ fall into two categories:
 * ones done purely for performance to skip a runtime check,
   which can be removed without any behaviour change, like the
   one in snan_bit_is_one()
 * various ones related to floatx80 behaviour, where currently we
   use ifdefs to select essentially i386 vs m68k handling
I'll probably come back and look at these when this series has
gone upstream.)

thanks
-- PMM

Peter Maydell (54):
  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: Pass have_snan to pickNaNMulAdd
  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
  target/m68k: Don't pass NULL float_status to floatx80_default_nan()
  softfloat: Create floatx80 default NaN from parts64_default_nan
  target/loongarch: Use normal float_status in fclass_s and fclass_d
    helpers
  target/m68k: In frem helper, initialize local float_status from
    env->fp_status
  target/m68k: Init local float_status from env fp_status in gdb get/set
    reg
  target/sparc: Initialize local scratch float_status from
    env->fp_status
  target/ppc: Use env->fp_status in helper_compute_fprf functions
  fpu: Allow runtime choice of default NaN value
  tests/fp: Set default NaN pattern explicitly
  target/microblaze: Set default NaN pattern explicitly
  target/i386: Set default NaN pattern explicitly
  target/hppa: Set default NaN pattern explicitly
  target/alpha: Set default NaN pattern explicitly
  target/arm: Set default NaN pattern explicitly
  target/loongarch: Set default NaN pattern explicitly
  target/m68k: Set default NaN pattern explicitly
  target/mips: Set default NaN pattern explicitly
  target/openrisc: Set default NaN pattern explicitly
  target/ppc: Set default NaN pattern explicitly
  target/sh4: Set default NaN pattern explicitly
  target/rx: Set default NaN pattern explicitly
  target/s390x: Set default NaN pattern explicitly
  target/sparc: Set default NaN pattern explicitly
  target/xtensa: Set default NaN pattern explicitly
  target/hexagon: Set default NaN pattern explicitly
  target/riscv: Set default NaN pattern explicitly
  target/tricore: Set default NaN pattern explicitly
  fpu: Remove default handling for dnan_pattern

 include/fpu/softfloat-helpers.h   |  38 +++-
 include/fpu/softfloat-types.h     |  89 +++++++++-
 target/mips/fpu_helper.h          |  20 +++
 target/sparc/helper.h             |   4 +-
 linux-user/arm/nwfpe/fpa11.c      |   5 +
 target/alpha/cpu.c                |   2 +
 target/arm/cpu.c                  |  10 ++
 target/hexagon/cpu.c              |   2 +
 target/hppa/fpu_helper.c          |  12 ++
 target/i386/tcg/fpu_helper.c      |  12 ++
 target/loongarch/tcg/fpu_helper.c |  14 +-
 target/m68k/cpu.c                 |  14 +-
 target/m68k/fpu_helper.c          |   6 +-
 target/m68k/helper.c              |   6 +-
 target/microblaze/cpu.c           |   2 +
 target/mips/msa.c                 |  10 ++
 target/openrisc/cpu.c             |   2 +
 target/ppc/cpu_init.c             |  19 ++
 target/ppc/fpu_helper.c           |   3 +-
 target/riscv/cpu.c                |   2 +
 target/rx/cpu.c                   |   2 +
 target/s390x/cpu.c                |   5 +
 target/sh4/cpu.c                  |   2 +
 target/sparc/cpu.c                |   6 +
 target/sparc/fop_helper.c         |   8 +-
 target/sparc/translate.c          |   4 +-
 target/tricore/helper.c           |   2 +
 target/xtensa/cpu.c               |   4 +
 target/xtensa/fpu_helper.c        |   3 +-
 tests/fp/fp-bench.c               |   7 +
 tests/fp/fp-test-log2.c           |   1 +
 tests/fp/fp-test.c                |   7 +
 fpu/softfloat-parts.c.inc         |  22 ++-
 fpu/softfloat-specialize.c.inc    | 278 ++++++------------------------
 34 files changed, 357 insertions(+), 266 deletions(-)

Comments

Richard Henderson Dec. 3, 2024, 3:51 a.m. UTC | #1
On 12/2/24 07:12, Peter Maydell wrote:
> (Apologies for this patchset being both big and having a wide CC list;
> the good news is that this is the last lot of fpu ifdef cleanup that
> needs to touch all the targets.)
> 
> 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
> This is patches 1-26 (which were in the v1 of this series).
> 
> It then does a similar thing for making targets select the default
> NaN value at runtime rather than relying on a compile-time ifdef.
> This is patches 34-54, which are new in v2.

Update needed for is_ebf in target/arm/tcg/vec_helper.c.

I think the best choice is to reverse the copy and test, e.g.

     *statusp = env->vfp.fp_status;
     set_default_nan_mode(true, statusp);

     if (ebf) {
         /* EBF=1 needs to do a step with round-to-odd semantics */
         *oddstatusp = *statusp;
         set_float_rounding_mode(float_round_to_odd, oddstatusp);
     } else {
         set_flush_to_zero(true, statusp);
         set_flush_inputs_to_zero(true, statusp);
         set_float_rounding_mode(float_round_to_odd_inf, statusp);
     }


r~