Message ID | 1575297977-2589-10-git-send-email-stli@linux.ibm.com |
---|---|
State | New |
Headers | show |
Series | Use GCC builtins for some math functions if desired. | expand |
On 02/12/2019 11:46, Stefan Liebler wrote: > This patch is using the corresponding GCC builtin for floorf, floor, > floorl and floorf128 if the USE_FUNCTION_BUILTIN macros are defined to one > in math-use-builtins.h. > > This is the case for s390 if build with at least --march=z196 --mzarch. > Otherwise the generic implementation is used. The code of the generic > implementation is not changed except changes in code style. LGTM with some changes below. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > sysdeps/generic/math-use-builtins.h | 5 ++ > sysdeps/ieee754/dbl-64/s_floor.c | 5 ++ > sysdeps/ieee754/float128/float128_private.h | 3 + > sysdeps/ieee754/flt-32/s_floorf.c | 60 ++++++++----- > sysdeps/ieee754/ldbl-128/s_floorl.c | 97 ++++++++++++++------- > sysdeps/s390/fpu/math-use-builtins.h | 6 ++ > 6 files changed, 121 insertions(+), 55 deletions(-) > > diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h > index 64b4a4bb5b..e1c5df62e4 100644 > --- a/sysdeps/generic/math-use-builtins.h > +++ b/sysdeps/generic/math-use-builtins.h > @@ -31,4 +31,9 @@ > #define USE_RINTL_BUILTIN 0 > #define USE_RINTF128_BUILTIN 0 > > +#define USE_FLOOR_BUILTIN 0 > +#define USE_FLOORF_BUILTIN 0 > +#define USE_FLOORL_BUILTIN 0 > +#define USE_FLOORF128_BUILTIN 0 > + > #endif /* math-use-builtins.h */ Ok. > diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c > index ce0c42bdb6..0ed22795ed 100644 > --- a/sysdeps/ieee754/dbl-64/s_floor.c > +++ b/sysdeps/ieee754/dbl-64/s_floor.c > @@ -35,6 +35,7 @@ > #include <math_private.h> > #include <stdint.h> > #include <libm-alias-double.h> > +#include <math-use-builtins.h> > > /* > * floor(x) > @@ -47,6 +48,9 @@ > double > __floor (double x) > { > +#if USE_FLOOR_BUILTIN > + return __builtin_floor (x); > +#else > int64_t i0; > EXTRACT_WORDS64 (i0, x); > int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; > @@ -74,6 +78,7 @@ __floor (double x) > else if (j0 == 0x400) > return x + x; /* inf or NaN */ > return x; > +#endif /* USE_FLOOR_BUILTIN */ > } > #ifndef __floor > libm_alias_double (__floor, floor) Ok. > diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h > index f458e7b85f..8c8a74a12c 100644 > --- a/sysdeps/ieee754/float128/float128_private.h > +++ b/sysdeps/ieee754/float128/float128_private.h > @@ -144,6 +144,8 @@ > #define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN > #undef USE_RINTL_BUILTIN > #define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN > +#undef USE_FLOORL_BUILTIN > +#define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN > > /* IEEE function renames. */ > #define __ieee754_acoshl __ieee754_acoshf128 > @@ -349,6 +351,7 @@ > #define __builtin_signbitl __builtin_signbit > #define __builtin_nearbyintl __builtin_nearbyintf128 > #define __builtin_rintl __builtin_rintf128 > +#define __builtin_floorl __builtin_floorf128 > > /* Get the constant suffix from bits/floatn-compat.h. */ > #define L(x) __f128 (x) Ok. > diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c > index b34d967f01..39bb570d10 100644 > --- a/sysdeps/ieee754/flt-32/s_floorf.c > +++ b/sysdeps/ieee754/flt-32/s_floorf.c > @@ -24,32 +24,48 @@ > #include <math.h> > #include <math_private.h> > #include <libm-alias-float.h> > +#include <math-use-builtins.h> > > float > -__floorf(float x) > +__floorf (float x) > { > - int32_t i0,j0; > - uint32_t i; > - GET_FLOAT_WORD(i0,x); > - j0 = ((i0>>23)&0xff)-0x7f; > - if(j0<23) { > - if(j0<0) { > - /* return 0*sign(x) if |x|<1 */ > - if(i0>=0) {i0=0;} > - else if((i0&0x7fffffff)!=0) > - { i0=0xbf800000;} > - } else { > - i = (0x007fffff)>>j0; > - if((i0&i)==0) return x; /* x is integral */ > - if(i0<0) i0 += (0x00800000)>>j0; > - i0 &= (~i); > - } > - } else { > - if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ > - else return x; /* x is integral */ > +#if USE_FLOORF_BUILTIN > + return __builtin_floorf (x); > +#else > + int32_t i0, j0; > + uint32_t i; > + GET_FLOAT_WORD (i0, x); > + j0 = ((i0 >> 23) & 0xff) - 0x7f; > + if (j0 < 23) > + { > + if (j0 < 0) > + { > + /* return 0 * sign (x) if |x| < 1 */ > + if (i0 >= 0) > + i0 = 0; > + else if ((i0 & 0x7fffffff) != 0) > + i0 = 0xbf800000; > } > - SET_FLOAT_WORD(x,i0); > - return x; > + else > + { > + i = (0x007fffff) >> j0; > + if ((i0 & i) == 0) > + return x; /* x is integral */ > + if (i0 < 0) > + i0 += (0x00800000) >> j0; > + i0 &= (~i); > + } > + } > + else > + { > + if (__glibc_unlikely (j0 == 0x80)) > + return x + x; /* inf or NaN */ > + else > + return x; /* x is integral */ > + } > + SET_FLOAT_WORD (x, i0); > + return x; > +#endif /* USE_FLOORF_BUILTIN */ > } > #ifndef __floorf > libm_alias_float (__floor, floor) Ok, but fix the indentation in a separated patch. > diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c > index f340a3fbca..8d20a79fec 100644 > --- a/sysdeps/ieee754/ldbl-128/s_floorl.c > +++ b/sysdeps/ieee754/ldbl-128/s_floorl.c > @@ -13,7 +13,9 @@ > * ==================================================== > */ > > -#if defined(LIBM_SCCS) && !defined(lint) > +#include <math-use-builtins.h> > + > +#if ! USE_FLOORL_BUILTIN && defined (LIBM_SCCS) && ! defined (lint) > static char rcsid[] = "$NetBSD: $"; > #endif > > @@ -29,41 +31,70 @@ static char rcsid[] = "$NetBSD: $"; > #include <math_private.h> > #include <libm-alias-ldouble.h> > > -_Float128 __floorl(_Float128 x) > +_Float128 > +__floorl (_Float128 x) > { > - int64_t i0,i1,j0; > - uint64_t i,j; > - GET_LDOUBLE_WORDS64(i0,i1,x); > - j0 = ((i0>>48)&0x7fff)-0x3fff; > - if(j0<48) { > - if(j0<0) { > - /* return 0*sign(x) if |x|<1 */ > - if(i0>=0) {i0=i1=0;} > - else if(((i0&0x7fffffffffffffffLL)|i1)!=0) > - { i0=0xbfff000000000000ULL;i1=0;} > - } else { > - i = (0x0000ffffffffffffULL)>>j0; > - if(((i0&i)|i1)==0) return x; /* x is integral */ > - if(i0<0) i0 += (0x0001000000000000LL)>>j0; > - i0 &= (~i); i1=0; > +#if USE_FLOORL_BUILTIN > + return __builtin_floorl (x); > +#else > + int64_t i0, i1, j0; > + uint64_t i, j; > + GET_LDOUBLE_WORDS64 (i0, i1, x); > + j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; > + if (j0 < 48) > + { > + if (j0 < 0) > + { > + /* return 0 * sign (x) if |x| < 1 */ > + if (i0 >= 0) > + { > + i0 = i1 = 0; > + } > + else if (((i0 & 0x7fffffffffffffffLL) | i1) != 0) > + { > + i0 = 0xbfff000000000000ULL; > + i1 = 0; > } > - } else if (j0>111) { > - if(j0==0x4000) return x+x; /* inf or NaN */ > - else return x; /* x is integral */ > - } else { > - i = -1ULL>>(j0-48); > - if((i1&i)==0) return x; /* x is integral */ > - if(i0<0) { > - if(j0==48) i0+=1; > - else { > - j = i1+(1LL<<(112-j0)); > - if(j<i1) i0 +=1 ; /* got a carry */ > - i1=j; > - } > + } > + else > + { > + i = (0x0000ffffffffffffULL) >> j0; > + if (((i0 & i) | i1) == 0) > + return x; /* x is integral */ > + if (i0 < 0) > + i0 += (0x0001000000000000LL) >> j0; > + i0 &= (~i); > + i1 = 0; > + } > + } > + else if (j0 > 111) > + { > + if (j0 == 0x4000) > + return x + x; /* inf or NaN */ > + else > + return x; /* x is integral */ > + } > + else > + { > + i = -1ULL >> (j0 - 48); > + if ((i1 & i) == 0) > + return x; /* x is integral */ > + if (i0 < 0) > + { > + if (j0 == 48) > + i0 += 1; > + else > + { > + j = i1 + (1LL << (112 - j0)); > + if (j < i1) > + i0 += 1 ; /* got a carry */ > + i1 = j; > } > - i1 &= (~i); > } > - SET_LDOUBLE_WORDS64(x,i0,i1); > - return x; > + i1 &= (~i); > + } > + SET_LDOUBLE_WORDS64 (x, i0, i1); > + return x; > +#endif /* USE_FLOORL_BUILTIN */ > } > libm_alias_ldouble (__floor, floor) Ok, but fix the indentation in a separated patch. > diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h > index 15705fa74a..63cc9d7a23 100644 > --- a/sysdeps/s390/fpu/math-use-builtins.h > +++ b/sysdeps/s390/fpu/math-use-builtins.h > @@ -34,12 +34,18 @@ > # define USE_RINTF_BUILTIN 1 > # define USE_RINTL_BUILTIN 1 > > +# define USE_FLOOR_BUILTIN 1 > +# define USE_FLOORF_BUILTIN 1 > +# define USE_FLOORL_BUILTIN 1 > + > # if __GNUC_PREREQ (8, 1) > # define USE_NEARBYINTF128_BUILTIN 1 > # define USE_RINTF128_BUILTIN 1 > +# define USE_FLOORF128_BUILTIN 1 > # else > # define USE_NEARBYINTF128_BUILTIN 0 > # define USE_RINTF128_BUILTIN 0 > +# define USE_FLOORF128_BUILTIN 0 > # endif > > #else > Ok.
diff --git a/sysdeps/generic/math-use-builtins.h b/sysdeps/generic/math-use-builtins.h index 64b4a4bb5b..e1c5df62e4 100644 --- a/sysdeps/generic/math-use-builtins.h +++ b/sysdeps/generic/math-use-builtins.h @@ -31,4 +31,9 @@ #define USE_RINTL_BUILTIN 0 #define USE_RINTF128_BUILTIN 0 +#define USE_FLOOR_BUILTIN 0 +#define USE_FLOORF_BUILTIN 0 +#define USE_FLOORL_BUILTIN 0 +#define USE_FLOORF128_BUILTIN 0 + #endif /* math-use-builtins.h */ diff --git a/sysdeps/ieee754/dbl-64/s_floor.c b/sysdeps/ieee754/dbl-64/s_floor.c index ce0c42bdb6..0ed22795ed 100644 --- a/sysdeps/ieee754/dbl-64/s_floor.c +++ b/sysdeps/ieee754/dbl-64/s_floor.c @@ -35,6 +35,7 @@ #include <math_private.h> #include <stdint.h> #include <libm-alias-double.h> +#include <math-use-builtins.h> /* * floor(x) @@ -47,6 +48,9 @@ double __floor (double x) { +#if USE_FLOOR_BUILTIN + return __builtin_floor (x); +#else int64_t i0; EXTRACT_WORDS64 (i0, x); int32_t j0 = ((i0 >> 52) & 0x7ff) - 0x3ff; @@ -74,6 +78,7 @@ __floor (double x) else if (j0 == 0x400) return x + x; /* inf or NaN */ return x; +#endif /* USE_FLOOR_BUILTIN */ } #ifndef __floor libm_alias_double (__floor, floor) diff --git a/sysdeps/ieee754/float128/float128_private.h b/sysdeps/ieee754/float128/float128_private.h index f458e7b85f..8c8a74a12c 100644 --- a/sysdeps/ieee754/float128/float128_private.h +++ b/sysdeps/ieee754/float128/float128_private.h @@ -144,6 +144,8 @@ #define USE_NEARBYINTL_BUILTIN USE_NEARBYINTF128_BUILTIN #undef USE_RINTL_BUILTIN #define USE_RINTL_BUILTIN USE_RINTF128_BUILTIN +#undef USE_FLOORL_BUILTIN +#define USE_FLOORL_BUILTIN USE_FLOORF128_BUILTIN /* IEEE function renames. */ #define __ieee754_acoshl __ieee754_acoshf128 @@ -349,6 +351,7 @@ #define __builtin_signbitl __builtin_signbit #define __builtin_nearbyintl __builtin_nearbyintf128 #define __builtin_rintl __builtin_rintf128 +#define __builtin_floorl __builtin_floorf128 /* Get the constant suffix from bits/floatn-compat.h. */ #define L(x) __f128 (x) diff --git a/sysdeps/ieee754/flt-32/s_floorf.c b/sysdeps/ieee754/flt-32/s_floorf.c index b34d967f01..39bb570d10 100644 --- a/sysdeps/ieee754/flt-32/s_floorf.c +++ b/sysdeps/ieee754/flt-32/s_floorf.c @@ -24,32 +24,48 @@ #include <math.h> #include <math_private.h> #include <libm-alias-float.h> +#include <math-use-builtins.h> float -__floorf(float x) +__floorf (float x) { - int32_t i0,j0; - uint32_t i; - GET_FLOAT_WORD(i0,x); - j0 = ((i0>>23)&0xff)-0x7f; - if(j0<23) { - if(j0<0) { - /* return 0*sign(x) if |x|<1 */ - if(i0>=0) {i0=0;} - else if((i0&0x7fffffff)!=0) - { i0=0xbf800000;} - } else { - i = (0x007fffff)>>j0; - if((i0&i)==0) return x; /* x is integral */ - if(i0<0) i0 += (0x00800000)>>j0; - i0 &= (~i); - } - } else { - if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */ - else return x; /* x is integral */ +#if USE_FLOORF_BUILTIN + return __builtin_floorf (x); +#else + int32_t i0, j0; + uint32_t i; + GET_FLOAT_WORD (i0, x); + j0 = ((i0 >> 23) & 0xff) - 0x7f; + if (j0 < 23) + { + if (j0 < 0) + { + /* return 0 * sign (x) if |x| < 1 */ + if (i0 >= 0) + i0 = 0; + else if ((i0 & 0x7fffffff) != 0) + i0 = 0xbf800000; } - SET_FLOAT_WORD(x,i0); - return x; + else + { + i = (0x007fffff) >> j0; + if ((i0 & i) == 0) + return x; /* x is integral */ + if (i0 < 0) + i0 += (0x00800000) >> j0; + i0 &= (~i); + } + } + else + { + if (__glibc_unlikely (j0 == 0x80)) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + SET_FLOAT_WORD (x, i0); + return x; +#endif /* USE_FLOORF_BUILTIN */ } #ifndef __floorf libm_alias_float (__floor, floor) diff --git a/sysdeps/ieee754/ldbl-128/s_floorl.c b/sysdeps/ieee754/ldbl-128/s_floorl.c index f340a3fbca..8d20a79fec 100644 --- a/sysdeps/ieee754/ldbl-128/s_floorl.c +++ b/sysdeps/ieee754/ldbl-128/s_floorl.c @@ -13,7 +13,9 @@ * ==================================================== */ -#if defined(LIBM_SCCS) && !defined(lint) +#include <math-use-builtins.h> + +#if ! USE_FLOORL_BUILTIN && defined (LIBM_SCCS) && ! defined (lint) static char rcsid[] = "$NetBSD: $"; #endif @@ -29,41 +31,70 @@ static char rcsid[] = "$NetBSD: $"; #include <math_private.h> #include <libm-alias-ldouble.h> -_Float128 __floorl(_Float128 x) +_Float128 +__floorl (_Float128 x) { - int64_t i0,i1,j0; - uint64_t i,j; - GET_LDOUBLE_WORDS64(i0,i1,x); - j0 = ((i0>>48)&0x7fff)-0x3fff; - if(j0<48) { - if(j0<0) { - /* return 0*sign(x) if |x|<1 */ - if(i0>=0) {i0=i1=0;} - else if(((i0&0x7fffffffffffffffLL)|i1)!=0) - { i0=0xbfff000000000000ULL;i1=0;} - } else { - i = (0x0000ffffffffffffULL)>>j0; - if(((i0&i)|i1)==0) return x; /* x is integral */ - if(i0<0) i0 += (0x0001000000000000LL)>>j0; - i0 &= (~i); i1=0; +#if USE_FLOORL_BUILTIN + return __builtin_floorl (x); +#else + int64_t i0, i1, j0; + uint64_t i, j; + GET_LDOUBLE_WORDS64 (i0, i1, x); + j0 = ((i0 >> 48) & 0x7fff) - 0x3fff; + if (j0 < 48) + { + if (j0 < 0) + { + /* return 0 * sign (x) if |x| < 1 */ + if (i0 >= 0) + { + i0 = i1 = 0; + } + else if (((i0 & 0x7fffffffffffffffLL) | i1) != 0) + { + i0 = 0xbfff000000000000ULL; + i1 = 0; } - } else if (j0>111) { - if(j0==0x4000) return x+x; /* inf or NaN */ - else return x; /* x is integral */ - } else { - i = -1ULL>>(j0-48); - if((i1&i)==0) return x; /* x is integral */ - if(i0<0) { - if(j0==48) i0+=1; - else { - j = i1+(1LL<<(112-j0)); - if(j<i1) i0 +=1 ; /* got a carry */ - i1=j; - } + } + else + { + i = (0x0000ffffffffffffULL) >> j0; + if (((i0 & i) | i1) == 0) + return x; /* x is integral */ + if (i0 < 0) + i0 += (0x0001000000000000LL) >> j0; + i0 &= (~i); + i1 = 0; + } + } + else if (j0 > 111) + { + if (j0 == 0x4000) + return x + x; /* inf or NaN */ + else + return x; /* x is integral */ + } + else + { + i = -1ULL >> (j0 - 48); + if ((i1 & i) == 0) + return x; /* x is integral */ + if (i0 < 0) + { + if (j0 == 48) + i0 += 1; + else + { + j = i1 + (1LL << (112 - j0)); + if (j < i1) + i0 += 1 ; /* got a carry */ + i1 = j; } - i1 &= (~i); } - SET_LDOUBLE_WORDS64(x,i0,i1); - return x; + i1 &= (~i); + } + SET_LDOUBLE_WORDS64 (x, i0, i1); + return x; +#endif /* USE_FLOORL_BUILTIN */ } libm_alias_ldouble (__floor, floor) diff --git a/sysdeps/s390/fpu/math-use-builtins.h b/sysdeps/s390/fpu/math-use-builtins.h index 15705fa74a..63cc9d7a23 100644 --- a/sysdeps/s390/fpu/math-use-builtins.h +++ b/sysdeps/s390/fpu/math-use-builtins.h @@ -34,12 +34,18 @@ # define USE_RINTF_BUILTIN 1 # define USE_RINTL_BUILTIN 1 +# define USE_FLOOR_BUILTIN 1 +# define USE_FLOORF_BUILTIN 1 +# define USE_FLOORL_BUILTIN 1 + # if __GNUC_PREREQ (8, 1) # define USE_NEARBYINTF128_BUILTIN 1 # define USE_RINTF128_BUILTIN 1 +# define USE_FLOORF128_BUILTIN 1 # else # define USE_NEARBYINTF128_BUILTIN 0 # define USE_RINTF128_BUILTIN 0 +# define USE_FLOORF128_BUILTIN 0 # endif #else