soft-fp: Define and use _FP_STATIC_ASSERT.

This patch makes soft-fp use static assertions in place of conditional
calls to abort, in places where there are checks for conditions (on
the types for which a macro is used) that the code is not prepared to
handle.  The fallback definition of _FP_STATIC_ASSERT (for kernel use
only, as only relevant to compilers not supported for building glibc)
is as in misc/sys/cdefs.h.

This means that soft-fp only ever calls abort for _FP_UNREACHABLE
calls in builds with GCC versions before 4.5.  Thus, there is no need
for an abort declaration or <stdlib.h> include, since the kernel code
handles defining abort as a macro itself - and so this avoids any need
for an __KERNEL__ condition on the abort declaration to avoid it
breaking with the kernel's macro definition.  That is, this patch is
intended to make glibc's soft-fp code suitable for kernel use with no
kernel-local changes to the soft-fp code needed at all.

Tested for powerpc-nofpu that installed stripped shared libraries are
unchanged by the patch.  One explicit <stdlib.h> include had to be
added to a file that was relying on the include from soft-fp.h.

	* soft-fp/soft-fp.h (_FP_STATIC_ASSERT): New macro.
	[_LIBC]: Do not include <stdlib.h>.
	[!_LIBC] (abort): Remove declaration.
	* soft-fp/op-2.h (_FP_MUL_MEAT_2_120_240_double): Use
	_FP_STATIC_ASSERT instead of conditionally calling abort.
	* soft-fp/op-common.h (_FP_FROM_INT): Likewise.
	(_FP_EXTEND_CNAN): Likewise.
	(FP_TRUNC): Likewise.
	(__FP_CLZ): Likewise.
	* sysdeps/powerpc/nofpu/flt-rounds.c: Include <stdlib.h>.
This commit is contained in:
Joseph Myers 2015-03-12 18:43:21 +00:00
parent af85ebcdf7
commit 7d67a196b6
5 changed files with 66 additions and 32 deletions

View File

@ -1,3 +1,16 @@
2015-03-12 Joseph Myers <joseph@codesourcery.com>
* soft-fp/soft-fp.h (_FP_STATIC_ASSERT): New macro.
[_LIBC]: Do not include <stdlib.h>.
[!_LIBC] (abort): Remove declaration.
* soft-fp/op-2.h (_FP_MUL_MEAT_2_120_240_double): Use
_FP_STATIC_ASSERT instead of conditionally calling abort.
* soft-fp/op-common.h (_FP_FROM_INT): Likewise.
(_FP_EXTEND_CNAN): Likewise.
(FP_TRUNC): Likewise.
(__FP_CLZ): Likewise.
* sysdeps/powerpc/nofpu/flt-rounds.c: Include <stdlib.h>.
2015-03-12 Yaakov Selkowitz <yselkowi@redhat.com> 2015-03-12 Yaakov Selkowitz <yselkowi@redhat.com>
* manual/string.texi (XPG basename): Fix prototype. * manual/string.texi (XPG basename): Fix prototype.

View File

@ -458,8 +458,8 @@
_p240, _q240, _r240, _s240; \ _p240, _q240, _r240, _s240; \
UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \ UDItype _t240, _u240, _v240, _w240, _x240, _y240 = 0; \
\ \
if ((wfracbits) < 106 || (wfracbits) > 120) \ _FP_STATIC_ASSERT ((wfracbits) >= 106 && (wfracbits) <= 120, \
abort (); \ "wfracbits out of range"); \
\ \
setfetz; \ setfetz; \
\ \

View File

@ -1800,6 +1800,8 @@
(r) = -(rtype) (r); \ (r) = -(rtype) (r); \
\ \
_FP_FROM_INT_ur = (rtype) (r); \ _FP_FROM_INT_ur = (rtype) (r); \
_FP_STATIC_ASSERT ((rsize) <= 2 * _FP_W_TYPE_SIZE, \
"rsize too large"); \
(void) (((rsize) <= _FP_W_TYPE_SIZE) \ (void) (((rsize) <= _FP_W_TYPE_SIZE) \
? ({ \ ? ({ \
int _FP_FROM_INT_lz; \ int _FP_FROM_INT_lz; \
@ -1808,17 +1810,15 @@
X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 \ X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 \
- _FP_FROM_INT_lz); \ - _FP_FROM_INT_lz); \
}) \ }) \
: (((rsize) <= 2 * _FP_W_TYPE_SIZE) \ : ({ \
? ({ \ int _FP_FROM_INT_lz; \
int _FP_FROM_INT_lz; \ __FP_CLZ_2 (_FP_FROM_INT_lz, \
__FP_CLZ_2 (_FP_FROM_INT_lz, \ (_FP_W_TYPE) (_FP_FROM_INT_ur \
(_FP_W_TYPE) (_FP_FROM_INT_ur \ >> _FP_W_TYPE_SIZE), \
>> _FP_W_TYPE_SIZE), \ (_FP_W_TYPE) _FP_FROM_INT_ur); \
(_FP_W_TYPE) _FP_FROM_INT_ur); \ X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \ - _FP_FROM_INT_lz); \
- _FP_FROM_INT_lz); \ })); \
}) \
: ({ abort (); 0; }))); \
\ \
if ((rsize) - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \ if ((rsize) - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
&& X##_e >= _FP_EXPMAX_##fs) \ && X##_e >= _FP_EXPMAX_##fs) \
@ -1876,12 +1876,18 @@
#define _FP_EXTEND_CNAN(dfs, sfs, dwc, swc, D, S, check_nan) \ #define _FP_EXTEND_CNAN(dfs, sfs, dwc, swc, D, S, check_nan) \
do \ do \
{ \ { \
if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \ _FP_STATIC_ASSERT (_FP_FRACBITS_##dfs >= _FP_FRACBITS_##sfs, \
|| (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \ "destination mantissa narrower than source"); \
< _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \ _FP_STATIC_ASSERT ((_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
|| (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \ >= _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs), \
&& _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \ "destination max exponent smaller" \
abort (); \ " than source"); \
_FP_STATIC_ASSERT (((_FP_EXPBIAS_##dfs \
>= (_FP_EXPBIAS_##sfs \
+ _FP_FRACBITS_##sfs - 1)) \
|| (_FP_EXPBIAS_##dfs == _FP_EXPBIAS_##sfs)), \
"source subnormals do not all become normal," \
" but bias not the same"); \
D##_s = S##_s; \ D##_s = S##_s; \
_FP_FRAC_COPY_##dwc##_##swc (D, S); \ _FP_FRAC_COPY_##dwc##_##swc (D, S); \
if (_FP_EXP_NORMAL (sfs, swc, S)) \ if (_FP_EXP_NORMAL (sfs, swc, S)) \
@ -1944,10 +1950,14 @@
#define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \ #define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \
do \ do \
{ \ { \
if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \ _FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs, \
|| (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \ "destination mantissa wider than source"); \
&& _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \ _FP_STATIC_ASSERT (((_FP_EXPBIAS_##sfs \
abort (); \ >= (_FP_EXPBIAS_##dfs \
+ _FP_FRACBITS_##dfs - 1)) \
|| _FP_EXPBIAS_##sfs == _FP_EXPBIAS_##dfs), \
"source subnormals do not all become same," \
" but bias not the same"); \
D##_s = S##_s; \ D##_s = S##_s; \
if (_FP_EXP_NORMAL (sfs, swc, S)) \ if (_FP_EXP_NORMAL (sfs, swc, S)) \
{ \ { \
@ -2036,14 +2046,18 @@
# define __FP_CLZ(r, x) \ # define __FP_CLZ(r, x) \
do \ do \
{ \ { \
_FP_STATIC_ASSERT ((sizeof (_FP_W_TYPE) == sizeof (unsigned int) \
|| (sizeof (_FP_W_TYPE) \
== sizeof (unsigned long)) \
|| (sizeof (_FP_W_TYPE) \
== sizeof (unsigned long long))), \
"_FP_W_TYPE size unsupported for clz"); \
if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \ if (sizeof (_FP_W_TYPE) == sizeof (unsigned int)) \
(r) = __builtin_clz (x); \ (r) = __builtin_clz (x); \
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \ else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
(r) = __builtin_clzl (x); \ (r) = __builtin_clzl (x); \
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long long)) \ else /* sizeof (_FP_W_TYPE) == sizeof (unsigned long long). */ \
(r) = __builtin_clzll (x); \ (r) = __builtin_clzll (x); \
else \
abort (); \
} \ } \
while (0) while (0)
#endif /* ndef __FP_CLZ */ #endif /* ndef __FP_CLZ */

View File

@ -60,6 +60,17 @@
# define _FP_UNREACHABLE abort () # define _FP_UNREACHABLE abort ()
#endif #endif
#if ((defined __GNUC__ \
&& (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))) \
|| (defined __STDC_VERSION__ && __STDC_VERSION__ >= 201112L))
# define _FP_STATIC_ASSERT(expr, msg) \
_Static_assert ((expr), msg)
#else
# define _FP_STATIC_ASSERT(expr, msg) \
extern int (*__Static_assert_function (void)) \
[!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
#endif
/* In the Linux kernel, some architectures have a single function that /* In the Linux kernel, some architectures have a single function that
uses different kinds of unpacking and packing depending on the uses different kinds of unpacking and packing depending on the
instruction being emulated, meaning it is not readily visible to instruction being emulated, meaning it is not readily visible to
@ -340,10 +351,4 @@ typedef USItype UHWtype;
# endif # endif
#endif #endif
#ifdef _LIBC
# include <stdlib.h>
#else
extern void abort (void);
#endif
#endif /* !SOFT_FP_H */ #endif /* !SOFT_FP_H */

View File

@ -16,6 +16,8 @@
License along with the GNU C Library. If not, see License along with the GNU C Library. If not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include <stdlib.h>
#include "soft-fp.h" #include "soft-fp.h"
#include "soft-supp.h" #include "soft-supp.h"