Message ID | 20241202131347.498124-29-peter.maydell@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | fpu: Remove pickNaNMulAdd, default-NaN ifdefs | expand |
On 12/2/24 07:13, Peter Maydell wrote: > We create our 128-bit default NaN by calling parts64_default_nan() > and then adjusting the result. We can do the same trick for creating > the floatx80 default NaN, which lets us drop a target ifdef. > > floatx80 is used only by: > i386 > m68k > arm nwfpe old floating-point emulation emulation support > (which is essentially dead, especially the parts involving floatx80) > PPC (only in the xsrqpxp instruction, which just rounds an input > value by converting to floatx80 and back, so will never generate > the default NaN) > > The floatx80 default NaN as currently implemented is: > m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1 > i386: sign = 1, exp = 1...1, int = 1, frac = 10...0 > > These are the same as the parts64_default_nan for these architectures. > > This is technically a possible behaviour change for arm linux-user > nwfpe emulation emulation, because the default NaN will now have the > sign bit clear. But we were already generating a different floatx80 > default NaN from the real kernel emulation we are supposedly > following, which appears to use an all-bits-1 value: > https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267 > > This won't affect the only "real" use of the nwfpe emulation, which > is ancient binaries that used it as part of the old floating point > calling convention; that only uses loads and stores of 32 and 64 bit > floats, not any of the floatx80 behaviour the original hardware had. > We also get the nwfpe float64 default NaN value wrong: > https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166 > so if we ever cared about this obscure corner the right fix would be > to correct that so nwfpe used its own default-NaN setting rather > than the Arm VFP one. > > Signed-off-by: Peter Maydell<peter.maydell@linaro.org> > --- > fpu/softfloat-specialize.c.inc | 20 ++++++++++---------- > 1 file changed, 10 insertions(+), 10 deletions(-) Reviewed-by: Richard Henderson <richard.henderson@linaro.org> r~
diff --git a/fpu/softfloat-specialize.c.inc b/fpu/softfloat-specialize.c.inc index 5fbc953e71e..9f913ce20ab 100644 --- a/fpu/softfloat-specialize.c.inc +++ b/fpu/softfloat-specialize.c.inc @@ -227,17 +227,17 @@ static void parts128_silence_nan(FloatParts128 *p, float_status *status) floatx80 floatx80_default_nan(float_status *status) { floatx80 r; + /* + * Extrapolate from the choices made by parts64_default_nan to fill + * in the floatx80 format. We assume that floatx80's explicit + * integer bit is always set (this is true for i386 and m68k, + * which are the only real users of this format). + */ + FloatParts64 p64; + parts64_default_nan(&p64, status); - /* None of the targets that have snan_bit_is_one use floatx80. */ - assert(!snan_bit_is_one(status)); -#if defined(TARGET_M68K) - r.low = UINT64_C(0xFFFFFFFFFFFFFFFF); - r.high = 0x7FFF; -#else - /* X86 */ - r.low = UINT64_C(0xC000000000000000); - r.high = 0xFFFF; -#endif + r.high = 0x7FFF | (p64.sign << 15); + r.low = (1ULL << DECOMPOSED_BINARY_POINT) | p64.frac; return r; }
We create our 128-bit default NaN by calling parts64_default_nan() and then adjusting the result. We can do the same trick for creating the floatx80 default NaN, which lets us drop a target ifdef. floatx80 is used only by: i386 m68k arm nwfpe old floating-point emulation emulation support (which is essentially dead, especially the parts involving floatx80) PPC (only in the xsrqpxp instruction, which just rounds an input value by converting to floatx80 and back, so will never generate the default NaN) The floatx80 default NaN as currently implemented is: m68k: sign = 0, exp = 1...1, int = 1, frac = 1....1 i386: sign = 1, exp = 1...1, int = 1, frac = 10...0 These are the same as the parts64_default_nan for these architectures. This is technically a possible behaviour change for arm linux-user nwfpe emulation emulation, because the default NaN will now have the sign bit clear. But we were already generating a different floatx80 default NaN from the real kernel emulation we are supposedly following, which appears to use an all-bits-1 value: https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L267 This won't affect the only "real" use of the nwfpe emulation, which is ancient binaries that used it as part of the old floating point calling convention; that only uses loads and stores of 32 and 64 bit floats, not any of the floatx80 behaviour the original hardware had. We also get the nwfpe float64 default NaN value wrong: https://elixir.bootlin.com/linux/v6.12/source/arch/arm/nwfpe/softfloat-specialize#L166 so if we ever cared about this obscure corner the right fix would be to correct that so nwfpe used its own default-NaN setting rather than the Arm VFP one. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> --- fpu/softfloat-specialize.c.inc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-)