soft-fp: Support floating-point extensions without quieting sNaNs.

One special case needed in soft-fp to replace the old version in the
Linux kernel is extending from a narrower floating-point format to a
wider one without quieting signaling NaNs.  (This is for
arch/powerpc/math-emu/lfs.c, where previously it used the old FP_CONV
which didn't do anything special for NaNs, then handled packing
specially for NaNs to avoid quieting at packing time, and discarded
the exceptions from unpacking.)

This patch accordingly refactors FP_EXTEND, creating a separate
_FP_EXTEND_CNAN that offers a choice of how NaNs are handled, with
FP_EXTEND reimplemented as a wrapper that provides the common case of
the IEEE operation that does quiet signaling NaNs and raise exceptions
for them.

Tested for powerpc (e500) that installed stripped shared libraries are
unchanged by this patch.

	* soft-fp/op-common.h (FP_EXTEND): Rename to _FP_EXTEND_CNAN with
	extra argument CHECK_NAN.  Redefine as wrapper around
	_FP_EXTEND_CNAN.
This commit is contained in:
Joseph Myers 2015-02-06 15:39:17 +00:00
parent 76c109f292
commit 639e42eb90
2 changed files with 16 additions and 4 deletions

View File

@ -1,3 +1,9 @@
2015-02-06 Joseph Myers <joseph@codesourcery.com>
* soft-fp/op-common.h (FP_EXTEND): Rename to _FP_EXTEND_CNAN with
extra argument CHECK_NAN. Redefine as wrapper around
_FP_EXTEND_CNAN.
2015-02-06 Carlos O'Donell <carlos@systemhalted.org> 2015-02-06 Carlos O'Donell <carlos@systemhalted.org>
* version.h (RELEASE): Set to "stable". * version.h (RELEASE): Set to "stable".

View File

@ -1825,8 +1825,10 @@
/* Extend from a narrower floating-point format to a wider one. Input /* Extend from a narrower floating-point format to a wider one. Input
and output are raw. */ and output are raw. If CHECK_NAN, then signaling NaNs are
#define FP_EXTEND(dfs, sfs, dwc, swc, D, S) \ converted to quiet with the "invalid" exception raised; otherwise
signaling NaNs remain signaling with no exception. */
#define _FP_EXTEND_CNAN(dfs, sfs, dwc, swc, D, S, check_nan) \
do \ do \
{ \ { \
if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
@ -1876,18 +1878,22 @@
D##_e = _FP_EXPMAX_##dfs; \ D##_e = _FP_EXPMAX_##dfs; \
if (!_FP_FRAC_ZEROP_##swc (S)) \ if (!_FP_FRAC_ZEROP_##swc (S)) \
{ \ { \
if (_FP_FRAC_SNANP (sfs, S)) \ if (check_nan && _FP_FRAC_SNANP (sfs, S)) \
FP_SET_EXCEPTION (FP_EX_INVALID \ FP_SET_EXCEPTION (FP_EX_INVALID \
| FP_EX_INVALID_SNAN); \ | FP_EX_INVALID_SNAN); \
_FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \ _FP_FRAC_SLL_##dwc (D, (_FP_FRACBITS_##dfs \
- _FP_FRACBITS_##sfs)); \ - _FP_FRACBITS_##sfs)); \
_FP_SETQNAN (dfs, dwc, D); \ if (check_nan) \
_FP_SETQNAN (dfs, dwc, D); \
} \ } \
} \ } \
} \ } \
} \ } \
while (0) while (0)
#define FP_EXTEND(dfs, sfs, dwc, swc, D, S) \
_FP_EXTEND_CNAN (dfs, sfs, dwc, swc, D, S, 1)
/* Truncate from a wider floating-point format to a narrower one. /* Truncate from a wider floating-point format to a narrower one.
Input and output are semi-raw. */ Input and output are semi-raw. */
#define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \ #define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \