aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/powerpc/fpu
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-03-08 20:26:36 +0000
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2019-06-12 11:46:22 -0300
commit21bd039bb41a59cdbd6c93670433e3b473720653 (patch)
tree4047dcc470c90f96a12f8b2d3e43e726da1f3e8d /sysdeps/powerpc/fpu
parentcfa611447b44d2fa1cb3d8f853b6f3f75ade366a (diff)
downloadglibc-21bd039bb41a59cdbd6c93670433e3b473720653.tar
glibc-21bd039bb41a59cdbd6c93670433e3b473720653.tar.gz
glibc-21bd039bb41a59cdbd6c93670433e3b473720653.tar.bz2
glibc-21bd039bb41a59cdbd6c93670433e3b473720653.zip
powerpc: consolidate rint
This patches consolidates all the powerpc rint{f} implementations on the generic sysdeps/powerpc/fpu/s_rint{f}. Checked on powerpc-linux-gnu (built without --with-cpu, with --with-cpu=power4 and with --with-cpu=power5+ and --disable-multi-arch), powerpc64-linux-gnu (built without --with-cp and with --with-cpu=power5+ and --disable-multi-arch). * sysdeps/powerpc/fpu/round_to_integer.h (set_fenv_mode, round_to_integer_float, round_mode): Add RINT handling. (reset_fenv_mode): New symbol. * sysdeps/powerpc/fpu/s_rint.c (__rint): Use generic implementation. * sysdeps/powerpc/fpu/s_rintf.c (__rintf): Likewise. * sysdeps/powerpc/powerpc32/fpu/s_rint.S: Remove file. * sysdeps/powerpc/powerpc32/fpu/s_rintf.S: Likewise. * sysdeps/powerpc/powerpc64/fpu/s_rint.S: Likewise. * sysdeps/powerpc/powerpc64/fpu/s_rintf.S: Likewise. Reviewed-by: Gabriel F. T. Gomes <gabrielftg@linux.ibm.com>
Diffstat (limited to 'sysdeps/powerpc/fpu')
-rw-r--r--sysdeps/powerpc/fpu/round_to_integer.h37
-rw-r--r--sysdeps/powerpc/fpu/s_rint.c19
-rw-r--r--sysdeps/powerpc/fpu/s_rintf.c19
3 files changed, 32 insertions, 43 deletions
diff --git a/sysdeps/powerpc/fpu/round_to_integer.h b/sysdeps/powerpc/fpu/round_to_integer.h
index 4bbd885f18..c759483230 100644
--- a/sysdeps/powerpc/fpu/round_to_integer.h
+++ b/sysdeps/powerpc/fpu/round_to_integer.h
@@ -27,12 +27,18 @@ enum round_mode
FLOOR,
ROUND,
TRUNC,
- NEARBYINT
+ NEARBYINT,
+ RINT
};
-static inline void
+static inline fenv_t
set_fenv_mode (enum round_mode mode)
{
+ fenv_t fe = 0;
+ if (mode != RINT)
+ /* Save current FPU rounding mode and inexact state. */
+ fe = fegetenv_register ();
+
switch (mode)
{
case CEIL:
@@ -49,6 +55,22 @@ set_fenv_mode (enum round_mode mode)
/* Disable FE_INEXACT exception */
reset_fpscr_bit (FPSCR_XE);
break;
+ case RINT:
+ break;
+ }
+ return fe;
+}
+
+static inline void
+reset_fenv_mode (fenv_t fe, enum round_mode mode)
+{
+ switch (mode)
+ {
+ default:
+ __builtin_mtfsf (0xff, fe);
+ break;
+ case RINT:
+ break;
}
}
@@ -64,9 +86,7 @@ round_to_integer_float (enum round_mode mode, float x)
float r = x;
- /* Save current FPU rounding mode and inexact state. */
- fenv_t fe = fegetenv_register ();
- set_fenv_mode (mode);
+ fenv_t fe = set_fenv_mode (mode);
if (x > 0.0)
{
/* IEEE 1003.1 round function. IEEE specifies "round to the nearest
@@ -91,7 +111,7 @@ round_to_integer_float (enum round_mode mode, float x)
r += 0x1p+23;
r = -fabs (r);
}
- __builtin_mtfsf (0xff, fe);
+ reset_fenv_mode (fe, mode);
return r;
}
@@ -109,8 +129,7 @@ round_to_integer_double (enum round_mode mode, double x)
double r = x;
/* Save current FPU rounding mode and inexact state. */
- fenv_t fe = fegetenv_register ();
- set_fenv_mode (mode);
+ fenv_t fe = set_fenv_mode (mode);
if (x > 0.0)
{
if (mode == ROUND)
@@ -127,7 +146,7 @@ round_to_integer_double (enum round_mode mode, double x)
r += 0x1p+52;
r = -fabs (r);
}
- __builtin_mtfsf (0xff, fe);
+ reset_fenv_mode (fe, mode);
return r;
}
diff --git a/sysdeps/powerpc/fpu/s_rint.c b/sysdeps/powerpc/fpu/s_rint.c
index 8bf43e3efe..062d6b125b 100644
--- a/sysdeps/powerpc/fpu/s_rint.c
+++ b/sysdeps/powerpc/fpu/s_rint.c
@@ -19,26 +19,11 @@
#define NO_MATH_REDIRECT
#include <math.h>
#include <libm-alias-double.h>
+#include <round_to_integer.h>
double
__rint (double x)
{
- static const float TWO52 = 4503599627370496.0;
-
- if (fabs (x) < TWO52)
- {
- if (x > 0.0)
- {
- x += TWO52;
- x -= TWO52;
- }
- else if (x < 0.0)
- {
- x = TWO52 - x;
- x = -(x - TWO52);
- }
- }
-
- return x;
+ return round_to_integer_double (RINT, x);
}
libm_alias_double (__rint, rint)
diff --git a/sysdeps/powerpc/fpu/s_rintf.c b/sysdeps/powerpc/fpu/s_rintf.c
index 03aaec2c85..c29e7a22b4 100644
--- a/sysdeps/powerpc/fpu/s_rintf.c
+++ b/sysdeps/powerpc/fpu/s_rintf.c
@@ -19,26 +19,11 @@
#define NO_MATH_REDIRECT
#include <math.h>
#include <libm-alias-float.h>
+#include <round_to_integer.h>
float
__rintf (float x)
{
- static const float TWO23 = 8388608.0;
-
- if (fabsf (x) < TWO23)
- {
- if (x > 0.0)
- {
- x += TWO23;
- x -= TWO23;
- }
- else if (x < 0.0)
- {
- x = TWO23 - x;
- x = -(x - TWO23);
- }
- }
-
- return x;
+ return round_to_integer_float (RINT, x);
}
libm_alias_float (__rint, rint)