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>
* manual/string.texi (XPG basename): Fix prototype.

View File

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

View File

@ -1800,6 +1800,8 @@
(r) = -(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) \
? ({ \
int _FP_FROM_INT_lz; \
@ -1808,17 +1810,15 @@
X##_e = (_FP_EXPBIAS_##fs + _FP_W_TYPE_SIZE - 1 \
- _FP_FROM_INT_lz); \
}) \
: (((rsize) <= 2 * _FP_W_TYPE_SIZE) \
? ({ \
int _FP_FROM_INT_lz; \
__FP_CLZ_2 (_FP_FROM_INT_lz, \
(_FP_W_TYPE) (_FP_FROM_INT_ur \
>> _FP_W_TYPE_SIZE), \
(_FP_W_TYPE) _FP_FROM_INT_ur); \
X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
- _FP_FROM_INT_lz); \
}) \
: ({ abort (); 0; }))); \
: ({ \
int _FP_FROM_INT_lz; \
__FP_CLZ_2 (_FP_FROM_INT_lz, \
(_FP_W_TYPE) (_FP_FROM_INT_ur \
>> _FP_W_TYPE_SIZE), \
(_FP_W_TYPE) _FP_FROM_INT_ur); \
X##_e = (_FP_EXPBIAS_##fs + 2 * _FP_W_TYPE_SIZE - 1 \
- _FP_FROM_INT_lz); \
})); \
\
if ((rsize) - 1 + _FP_EXPBIAS_##fs >= _FP_EXPMAX_##fs \
&& X##_e >= _FP_EXPMAX_##fs) \
@ -1876,12 +1876,18 @@
#define _FP_EXTEND_CNAN(dfs, sfs, dwc, swc, D, S, check_nan) \
do \
{ \
if (_FP_FRACBITS_##dfs < _FP_FRACBITS_##sfs \
|| (_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
< _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs) \
|| (_FP_EXPBIAS_##dfs < _FP_EXPBIAS_##sfs + _FP_FRACBITS_##sfs - 1 \
&& _FP_EXPBIAS_##dfs != _FP_EXPBIAS_##sfs)) \
abort (); \
_FP_STATIC_ASSERT (_FP_FRACBITS_##dfs >= _FP_FRACBITS_##sfs, \
"destination mantissa narrower than source"); \
_FP_STATIC_ASSERT ((_FP_EXPMAX_##dfs - _FP_EXPBIAS_##dfs \
>= _FP_EXPMAX_##sfs - _FP_EXPBIAS_##sfs), \
"destination max exponent smaller" \
" 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; \
_FP_FRAC_COPY_##dwc##_##swc (D, S); \
if (_FP_EXP_NORMAL (sfs, swc, S)) \
@ -1944,10 +1950,14 @@
#define FP_TRUNC(dfs, sfs, dwc, swc, D, S) \
do \
{ \
if (_FP_FRACBITS_##sfs < _FP_FRACBITS_##dfs \
|| (_FP_EXPBIAS_##sfs < _FP_EXPBIAS_##dfs + _FP_FRACBITS_##dfs - 1 \
&& _FP_EXPBIAS_##sfs != _FP_EXPBIAS_##dfs)) \
abort (); \
_FP_STATIC_ASSERT (_FP_FRACBITS_##sfs >= _FP_FRACBITS_##dfs, \
"destination mantissa wider than source"); \
_FP_STATIC_ASSERT (((_FP_EXPBIAS_##sfs \
>= (_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; \
if (_FP_EXP_NORMAL (sfs, swc, S)) \
{ \
@ -2036,14 +2046,18 @@
# define __FP_CLZ(r, x) \
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)) \
(r) = __builtin_clz (x); \
else if (sizeof (_FP_W_TYPE) == sizeof (unsigned long)) \
(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); \
else \
abort (); \
} \
while (0)
#endif /* ndef __FP_CLZ */

View File

@ -60,6 +60,17 @@
# define _FP_UNREACHABLE abort ()
#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
uses different kinds of unpacking and packing depending on the
instruction being emulated, meaning it is not readily visible to
@ -340,10 +351,4 @@ typedef USItype UHWtype;
# endif
#endif
#ifdef _LIBC
# include <stdlib.h>
#else
extern void abort (void);
#endif
#endif /* !SOFT_FP_H */

View File

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