powerpc: Add optimized ilogb* for POWER9

The instructions xsxexpdp and xsxexpqp introduced on POWER9 extract
the exponent from a double-precision and quad-precision floating-point
respectively, thus they can be used to improve ilogb, ilogbf and ilogbf128.
This commit is contained in:
Raphael Moreira Zinsly 2021-02-23 14:14:37 -03:00
parent 3977477d48
commit 56c81132cc
3 changed files with 59 additions and 1 deletions

View File

@ -25,7 +25,28 @@
#include_next <math_private.h>
#if defined _ARCH_PWR9 && __HAVE_DISTINCT_FLOAT128
#ifdef _ARCH_PWR9
#if __GNUC_PREREQ (8, 0)
# define _GL_HAS_BUILTIN_ILOGB 1
#elif defined __has_builtin
# define _GL_HAS_BUILTIN_ILOGB __has_builtin (__builtin_vsx_scalar_extract_exp)
#else
# define _GL_HAS_BUILTIN_ILOGB 0
#endif
#define __builtin_test_dc_ilogbf __builtin_test_dc_ilogb
#define __builtin_ilogbf __builtin_ilogb
#define __builtin_test_dc_ilogb(x, y) \
__builtin_vsx_scalar_test_data_class_dp(x, y)
#define __builtin_ilogb(x) __builtin_vsx_scalar_extract_exp(x) - 0x3ff
#define __builtin_test_dc_ilogbf128(x, y) \
__builtin_vsx_scalar_test_data_class_qp(x, y)
#define __builtin_ilogbf128(x) __builtin_vsx_scalar_extract_expq(x) - 0x3fff
#if __HAVE_DISTINCT_FLOAT128
extern __always_inline _Float128
__ieee754_sqrtf128 (_Float128 __x)
{
@ -34,5 +55,8 @@ __ieee754_sqrtf128 (_Float128 __x)
return __z;
}
#endif
#else /* !_ARCH_PWR9 */
#define _GL_HAS_BUILTIN_ILOGB 0
#endif
#endif /* _PPC_MATH_PRIVATE_H_ */

View File

@ -0,0 +1,30 @@
#include <math.h>
#include <errno.h>
#include <limits.h>
#include <math_private.h>
#include <fenv.h>
#if _GL_HAS_BUILTIN_ILOGB
int
M_DECL_FUNC (__ilogb) (FLOAT x)
{
int r;
/* Check for exceptional cases. */
if (! M_SUF(__builtin_test_dc_ilogb) (x, 0x7f))
r = M_SUF (__builtin_ilogb) (x);
else
/* Fallback to the generic ilogb if x is NaN, Inf or subnormal. */
r = M_SUF (__ieee754_ilogb) (x);
if (__builtin_expect (r == FP_ILOGB0, 0)
|| __builtin_expect (r == FP_ILOGBNAN, 0)
|| __builtin_expect (r == INT_MAX, 0))
{
__set_errno (EDOM);
__feraiseexcept (FE_INVALID);
}
return r;
}
declare_mgen_alias (__ilogb, ilogb)
#else
#include <math/w_ilogb_template.c>
#endif

View File

@ -0,0 +1,4 @@
/* Skip the optimization for long double as ibm128 does not provide an
optimized builtin. */
#include <math-type-macros-ldouble.h>
#include <math/w_ilogb_template.c>