mirror of
git://sourceware.org/git/glibc.git
synced 2024-11-27 03:41:23 +08:00
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:
parent
af85ebcdf7
commit
7d67a196b6
13
ChangeLog
13
ChangeLog
@ -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.
|
||||
|
@ -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; \
|
||||
\
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user