[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 1/7] softfloat: Fix sNaN handling in FP conversi
From: |
Maciej W. Rozycki |
Subject: |
Re: [Qemu-devel] [PATCH 1/7] softfloat: Fix sNaN handling in FP conversion operations |
Date: |
Fri, 6 Feb 2015 14:37:38 +0000 (GMT) |
User-agent: |
Alpine 2.11 (LFD 23 2013-08-11) |
On Thu, 5 Feb 2015, Peter Maydell wrote:
> > Fix sNaN handling in floating-point format conversion operations, that
> > are classified by the IEEE 754-2008 standard as general-computational
> > operations [1]:
> >
> > "5.4 formatOf general-computational operations
> >
> > "5.4.2 Conversion operations for floating-point formats and decimal
> > character sequences
> >
> > "Implementations shall provide the following formatOf conversion
> > operations from all supported floating-point formats to all supported
> > floating-point formats, as well as conversions to and from decimal
> > character sequences. These operations shall not propagate non-canonical
> > results. Some format conversion operations produce results in a
> > different radix than the operands."
> >
> > according to the quietening requirement [2] set by the same standard:
> >
> > "7.2 Invalid operation
> >
> > "For operations producing results in floating-point format, the default
> > result of an operation that signals the invalid operation exception
> > shall be a quiet NaN that should provide some diagnostic information
> > (see 6.2).
> >
> > "These operations are:
> > a) any general-computational or signaling-computational operation
> > on a signaling NaN (see 6.2), except for some conversions (see
> > 5.12)"
> >
> > and the reference above is [3]:
> >
> > "5.12 Details of conversion between floating-point data and external
> > character sequences"
> >
> > so does not apply to conversions a pair of floating-point formats.
> >
> > Therefore quieten any sNaN encountered in floating-point format
> > conversions, in the usual manner.
> >
> > References:
> >
> > [1] "IEEE Standard for Floating-Point Arithmetic", IEEE Computer
> > Society, IEEE Std 754-2008, 29 August 2008, pp. 21-22
> >
> > [2] same, p. 37
> >
> > [3] same, p. 30
> >
> > Signed-off-by: Maciej W. Rozycki <address@hidden>
> > ---
> > This is in particular how MIPS hardware operates, other processors
> > supposedly do the same if they claim compliance to IEEE 754.
>
> ARM currently handles this issue by calling the _maybe_silence_nan()
> function in all target-specific helper functions that call
> float-to-float conversion functions (but that has its own
> issues, see below).
>
> Have you looked at the other architectures that use these
> functions to convert float values to see what their NaN
> handling semantics are? I agree about what the spec says,
> but we may well have targets which are not fully IEEE
> compliant and rely on the current semantics (x86 springs to
> mind).
I think the IEEE 754 standard-compliant behaviour shouldn't be left to
target helpers, it would bound to cause discrepancies and chaos. I
wouldn't expect every target maintainer to be fluent in IEEE 754 arcana,
or even have access to the standard's normative document.
What I think would make sense here is instead of say `float32_to_float64'
making a call to `float64_maybe_silence_nan' directly, we'd have a static
inline function or a macro called say `float64_convert_silence_nan'
invoked where the former is in my patch proposed. That function in turn
would call the former function by default and which could be overridden by
something else for individual targets that require it.
And I think we shouldn't be making our decisions based on x86 despite its
ubiquity -- it is, especially as the x87 implementation is concerned, the
earliest attempt to implement IEEE 754 with all the oddities resulting.
Or more specifically not even that but more of an FP implementation that
(as of the 8087 FPU) Intel wanted to become the basis of the upcoming IEEE
754 standard, and mostly succeeded in principle, but not in some details,
some of which were later corrected with the 80287 and 80387
implementations, and some of which had to stay, for compatibility reasons.
For one the x87 doesn't really implement proper single or double
arithmetic. While there are two precision control bits in its control
register, not all arithmetic operations respect them, making their
calculation unconditionally in the extended precision instead. And even
these that do only respect them for the significand and not the
exponent[1]:
"
* The precision control (PC) bits (bits 9-8) can be used to set the MCP
internal operating precision of the significand at less than the default
of 64 bits (extended precision). This can be useful in providing
compatibility with early generation arithmetic processors of smaller
precision. PC affects only the instructions ADD, SUB, DIV, MUL, and
SQRT. For all other instructions, either the precision is determined by
the opcode or extended precision is used.
"
So I think that any x87 intricacies are best handled either by hooks
similar to `float64_convert_silence_nan' I propose or by individual
implementation of whole operations where the actions required diverge from
the standard so much as to make the use of such hooks infeasible.
Besides are you sure? I see x87 documentation say this[2]:
"
| | Default Action
Exception | Cause | (if exception is masked)
----------+----------------------------------------+-------------------------
Invalid | Operation on a signaling NaN, | Result is a quiet NaN,
Operation | unsupported format, indeterminate form | integer indeterminate,
| (0*Inf, 0/0, (+Inf)+(-Inf), etc.), or | or BCD indefinite
| stack overflow/underflow (SF is also |
| set). |
"
and this[3]:
"
11. FLD single/double precision when the operand is denormal converts the
number to extended precision and signals the denormalized operand
exception. When loading a signaling NaN, FLD single/double precision
signals an invalid-operand exception.
"
so it looks to me conversions do actually quieten an sNaN. Or are you
referring to earlier x87 implementations that did not implement sNaNs[3]:
"
12. The Intel387 DX MCP only generates quiet NaNs (as on the 80287);
however, the Intel387 DX MCP distinguishes between quiet NaNs and
signaling NaNs. Signaling NaNs trigger exceptions when they are used
as operands; quiet NaNs do not (except for FCOM, FIST, and FBSTP which
also raise IE for quiet NaNs).
"
But does QEMU support 16-bit x86 machines? Or at least a configuration
where an 80386 CPU is paired with an 80287 FPU -- which is a bit unusual,
but architecturally supported (see the CR0.ET bit, in later 80386 versions
as well as all newer architecture revisions removed and the bit location
hardwired to 1 instead as for an 80386 CPU paired with an 80387 FPU)?
If so, then even more variance will have to be taken into account here as
far as x87 is considered, and I believe it all can be handled by using
such `float*_convert_silence_nan' hooks proposed.
> Also in this area, ARM has a problem where we don't give the
> correct answers for fp-to-fp conversions from a higher precision
> to a lower precision where the input is a signaling NaN whose
> non-zero mantissa bits are all at the low end such that the
> truncation of the mantissa into the lower precision format
> would drop them all. The result is the wrong value of quiet NaN
> (we return the default NaN, which has the sign bit clear, but the
> FPConvertNaN pseudocode specifies that we should effectively get
> the default NaN but with the same sign bit as the input SNaN).
>
> I think this means that:
> (1) we want to put handling of silencing the signaling NaNs
> into the NaN conversion functions themselves (since it's
> too late to do it correctly once the commonNaNtoFloat16
> function has thrown away data)
> (2) that handling needs to be target specific, as most details
> of quiet vs signaling NaNs are
>
> I note in passing that the float*ToCommonNaN and commonNaNToFloat*
> functions are used only in the back-to-back call sequence of
> return commonNaNToFloatX(floatYToCommonNaN(...))
> for handling the NaN inputs on FP-to-FP conversion.
I believe my proposal addresses your concerns in a burden-free way for
target maintainers who look after processors that implement the IEEE 754
standard as it stands. Of course someone will have to implement it and
it's not entirely clear to me at the moment who that person would be.
References:
[1] "Intel387 DX Math CoProcessor", Intel Corporation, Order Number:
240448-005, March 1992, Section 2.3 "Register Set", Subsection 2.3.5
"Control Word", p. 14
[2] same, Table 2.7 "Exceptions", p. 16
[3] same, Section 2.7 "8087 and 80287 Compatibility", Subsection 2.7.2
"Exceptions", p. 17
Maciej