[PATCH v2] MIPS: NaN encoding fixes and IEEE 754-2008 updates

Jeff Johnston jjohnstn@redhat.com
Fri Mar 21 21:29:00 GMT 2014

Patch applied with slight modification to use #if __GNUC_PREREQ(3,3)
macro to specify version requirements for nan functions as suggested
in a previous comment.


-- Jeff J.

----- Original Message -----
> From: "Maciej W. Rozycki" <macro@codesourcery.com>
> To: newlib@sourceware.org
> Sent: Friday, March 21, 2014 4:19:55 PM
> Subject: [PATCH v2] MIPS: NaN encoding fixes and IEEE 754-2008 updates
> Hi,
>  As many of you have been aware it has been a long practice for software
> using IEEE 754 floating-point arithmetic run on MIPS processors to use an
> encoding of Not-a-Number (NaN) data different to one used by software run
> on other processors.  And as of IEEE 754-2008 revision this encoding does
> not follow one recommended in the standard, as specified in section 6.2.1,
> where it is stated that quiet NaNs should have the first bit (d1) of their
> significand set to 1 while signalling NaNs should have that bit set to 0,
> but MIPS software interprets the two bits in the opposite manner.
>  A recent MIPS Architecture revision[1][2] provides for processors that
> support the IEEE 754-2008 preferred NaN encoding format.  As the two
> formats (further referred to as "legacy NaN" and "2008 NaN") are
> incompatible to each other, tools have been updated to provide support for
> the two formats to help people avoid using incompatible binary modules.
> In particular GCC versions that produce the 2008 NaN encoding predefine
> the `__mips_nan2008' macro that can be used to select code to compile at
> the preprocessor level.
>  This change corrects inconsistencies for the MIPS target in NaN encodings
> between endiannesses and makes sure the correct encodings are used both in
> the legacy-NaN and the 2008-NaN mode.
>  This code unconditionally expects floating-point types having the
> significand field width of 24, 53, 64 and 113 bits to be present.
> Additionally the 64-bit format expects the leading significand bit to be
> explicitly encoded as in Intel x86/x87 FPUs.  Having no better choice I
> have implemented the handling of these extra data types as they might be
> reasonably implemented by MIPS hardware.  Ideally this code should be
> audited and dead pieces disabled for targets that do not use them.
>  Furthermore some macros are present that encode constants comprising
> whole or parts of NaN data of different widths.  They use different
> encodings and data formats between endiannesses, apparently implying the
> Intel x86/x87 format for the little endianness and Motorola M68k format
> for the big endianness.  Neither fully applies for MIPS targets, so I have
> added separate definitions for the values that make sense and are actually
> referred to from code elsewhere.  Any future references to the currently
> unused macros defined for non-MIPS targets to support a long double data
> type will cause a build failure on MIPS, which is exactly what we want.
>  For nan and nanf I decided to switch to __builtin_nan and __builtin_nanf
> respectively as the implementation where available -- which is always true
> for GCC versions that support the 2008-NaN encoding on the MIPS target.
> These built-ins guarantee the correct NaN encoding for all platforms and
> compilation options and are already used elsewhere in Newlib (which is
> where I copied the preprocessor condition from).
>  For MIPS, additionally, in many cases they produce slightly better or at
> worst identical code; unfortunately in some other ones GCC misses the
> opportunity to inline the value loaded -- it looks to me like with these
> built-ins the compiler always insists to put the value loaded in memory.
> I don't think this should stop us from using them regardless though, the
> maintainability gain is too high compared to the memory loss, which is on
> the order of 4 to 8 bytes.
>  FWIW I have regression-tested the change with the mips-sde-elf target,
> although I can't say this provides much value as the newlib test suite
> doesn't seem to cover much of IEEE arithmetic.  However this change has
> been used for ~1yr with the Mentor CodeBench toolchain with no problems
> spotted.
>  Please apply.
> 2013-03-21  Maciej W. Rozycki  <macro@codesourcery.com>
> 	newlib/
> 	* libc/stdlib/gd_qnan.h (f_QNAN, d_QNAN0, d_QNAN1): Add MIPS
> 	versions.
> 	(ld_QNAN0, ld_QNAN1, ld_QNAN2, ld_QNAN3): Don't define for MIPS.
> 	(ldus_QNAN0, ldus_QNAN1, ldus_QNAN2, ldus_QNAN3, ldus_QNAN4):
> 	Likewise.
> 	* libc/stdlib/ldtoa.c (nan113, nan64, nan53, nan24): Add MIPS
> 	versions.
> 	(enan): Handle legacy MIPS payloads.
> 	* libm/common/s_nan.c (nan): Use __builtin_nan if supported by
> 	the compiler.
> 	* libm/common/sf_nan.c (nanf): Likewise.
>   Maciej
>  References:
> [1] "MIPS Architecture For Programmers, Volume I-A: Introduction to the
>      MIPS32 Architecture", MIPS Technologies, Inc., Document Number:
>      MD00082, Revision 5.03, Sept. 9, 2013, Section "Quiet
>      Non-Number (QNaN)", p. 71,
> [2] "MIPS Architecture For Programmers, Volume I-A: Introduction to the
>      MIPS64 Architecture", MIPS Technologies, Inc., Document Number:
>      MD00083, Revision 5.03, Sept. 9, 2013, Section "Quiet
>      Non-Number (QNaN)", p. 74.

More information about the Newlib mailing list