summary refs log tree commit diff
path: root/sysdeps/powerpc/fpu
diff options
context:
space:
mode:
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)