about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAdhemerval Zanella <azanella@linux.vnet.ibm.com>2011-11-11 13:33:38 -0500
committerUlrich Drepper <drepper@gmail.com>2011-11-11 13:33:38 -0500
commit8a6d525522b2fb04cec86b48c5b25818d395bbbd (patch)
tree34e9e7e8b6734ad4d57fa7d3e28d90722cdb329e
parent1d8f7ddc04a4782c1bf2d6f48ce40e7d57caa920 (diff)
downloadglibc-8a6d525522b2fb04cec86b48c5b25818d395bbbd.tar.gz
glibc-8a6d525522b2fb04cec86b48c5b25818d395bbbd.tar.xz
glibc-8a6d525522b2fb04cec86b48c5b25818d395bbbd.zip
PowerPC: Arithmetic function optimizations for POWER
-rw-r--r--ChangeLog11
-rw-r--r--sysdeps/powerpc/fpu/e_sqrt.c1
-rw-r--r--sysdeps/powerpc/fpu/e_sqrtf.c2
-rw-r--r--sysdeps/powerpc/fpu/math_private.h137
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/e_sqrt.c1
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c1
6 files changed, 149 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index cfb381ad8d..0fe09d0b52 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2011-11-07  Adhemerval Zanella  <azanella@linux.vnet.ibm.com>
+
+	* sysdeps/powerpc/fpu/math_private.h: Using inline assembly version
+	of math functions ceil, trunc, floor, round, and sqrt, when
+	avaliable on the platform.
+	* sysdeps/powerpc/fpu/e_sqrt.c: Undefine __ieee754_sqrt to avoid
+	name clash.
+	* sysdeps/powerpc/fpu/e_sqrtf.c: Likewise.
+	* sysdeps/powerpc/powerpc64/fpu/e_sqrt.c: Likewise.
+	* sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c: Likewise.
+
 2011-10-30  Marek Polacek  <mpolacek@redhat.com>
 
 	* libio/wfileops.c (_IO_wfile_underflow_mmap): Remove unused variable.
diff --git a/sysdeps/powerpc/fpu/e_sqrt.c b/sysdeps/powerpc/fpu/e_sqrt.c
index f9ded25717..d59bd08d5c 100644
--- a/sysdeps/powerpc/fpu/e_sqrt.c
+++ b/sysdeps/powerpc/fpu/e_sqrt.c
@@ -154,6 +154,7 @@ __slow_ieee754_sqrt (double x)
   return f_wash (x);
 }
 
+#undef __ieee754_sqrt
 double
 __ieee754_sqrt (double x)
 {
diff --git a/sysdeps/powerpc/fpu/e_sqrtf.c b/sysdeps/powerpc/fpu/e_sqrtf.c
index 965faee842..9c6b860c96 100644
--- a/sysdeps/powerpc/fpu/e_sqrtf.c
+++ b/sysdeps/powerpc/fpu/e_sqrtf.c
@@ -130,7 +130,7 @@ __slow_ieee754_sqrtf (float x)
   return f_washf (x);
 }
 
-
+#undef __ieee754_sqrtf
 float
 __ieee754_sqrtf (float x)
 {
diff --git a/sysdeps/powerpc/fpu/math_private.h b/sysdeps/powerpc/fpu/math_private.h
index 90021c6d3c..c4dd217d1d 100644
--- a/sysdeps/powerpc/fpu/math_private.h
+++ b/sysdeps/powerpc/fpu/math_private.h
@@ -1,5 +1,5 @@
 /* Private inline math functions for powerpc.
-   Copyright (C) 2006
+   Copyright (C) 2006, 2011
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -25,12 +25,145 @@
 #include <ldsodefs.h>
 #include <dl-procinfo.h>
 
+#include <math/math_private.h>
+
 # if __WORDSIZE == 64 || defined _ARCH_PWR4
 #  define __CPU_HAS_FSQRT 1
+
+#ifndef __ieee754_sqrt
+# define __ieee754_sqrt(x)		\
+  ({ double __z;			\
+     __asm __volatile (			\
+	"	fsqrt %0,%1\n"		\
+		: "=f" (__z)		\
+		: "f"(x));		\
+     __z; })
+#endif
+#ifndef __ieee754_sqrtf
+# define __ieee754_sqrtf(x)		\
+  ({ float __z;				\
+     __asm __volatile (			\
+	"	fsqrts %0,%1\n"		\
+		: "=f" (__z)		\
+		: "f"(x));		\
+     __z; })
+#endif
+
 # else
 #  define __CPU_HAS_FSQRT ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+# endif	// __WORDSIZE == 64 || defined _ARCH_PWR4
+
+
+#if defined _ARCH_PWR5X
+
+# ifndef __round
+#  define __round(x)			\
+    ({ double __z;			\
+      __asm __volatile (		\
+	"	frin %0,%1\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+# ifndef __roundf
+#  define __roundf(x)			\
+    ({ float __z;			\
+     __asm __volatile (			\
+	"	frin %0,%1\n"		\
+	"	frsp %0,%0\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+
+# ifndef __trunc
+#  define __trunc(x)			\
+    ({ double __z;			\
+     __asm __volatile (			\
+	"	friz %0,%1\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+# ifndef __truncf
+#  define __truncf(x)			\
+    ({ float __z;			\
+     __asm __volatile (			\
+	"	friz %0,%1\n"		\
+	"	frsp %0,%0\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+
+# ifndef __ceil
+#  define __ceil(x)			\
+    ({ double __z;			\
+     __asm __volatile (			\
+	"	frip %0,%1\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+# ifndef __ceilf
+#  define __ceilf(x)			\
+    ({ float __z;			\
+     __asm __volatile (			\
+	"	frip %0,%1\n"		\
+	"	frsp %0,%0\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
 # endif
 
+# ifndef __floor
+#  define __floor(x)			\
+    ({ double __z;			\
+     __asm __volatile (			\
+	"	frim %0,%1\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+# ifndef __floorf
+#  define __floorf(x)			\
+    ({ float __z;			\
+     __asm __volatile (			\
+	"	frim %0,%1\n"		\
+	"	frsp %0,%0\n"		\
+		: "=f" (__z)		\
+		: "f" (x));		\
+     __z; })
+# endif
+
+#endif	/* defined _ARCH_PWR5X */
+
+
+#if defined _ARCH_PWR6
+
+# ifndef __copysign
+#  define __copysign(x, y)		\
+    ({ double __z;			\
+     __asm __volatile (			\
+	"	fcpsgn %0,%1,%2\n"	\
+		: "=f" (__z)		\
+		: "f" (y), "f" (x));	\
+     __z; })
+# endif
+# ifndef __copysignf
+#  define __copysignf(x, y)		\
+    ({ float __z;			\
+     __asm __volatile (			\
+	"	fcpsgn %0,%1,%2\n"	\
+	"	frsp %0,%0\n"		\
+		: "=f" (__z)		\
+		: "f" (y), "f" (x));	\
+     __z; })
+# endif
+
+#endif /* defined _ARCH_PWR6 */
+
+
 # ifndef __LIBC_INTERNAL_MATH_INLINES
 extern double __slow_ieee754_sqrt (double);
 __inline double
@@ -78,6 +211,4 @@ __ieee754_sqrtf (float __x)
 }
 #endif /* __LIBC_INTERNAL_MATH_INLINES */
 
-#include <math/math_private.h>
-
 #endif /* _PPC_MATH_PRIVATE_H_ */
diff --git a/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c b/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
index 314abba3b2..66d04ceb77 100644
--- a/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
+++ b/sysdeps/powerpc/powerpc64/fpu/e_sqrt.c
@@ -20,6 +20,7 @@
 #include <math.h>
 #include <math_private.h>
 
+#undef __ieee754_sqrt
 double
 __ieee754_sqrt (double x)
 {
diff --git a/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c b/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
index 7157214394..847a2e4ad6 100644
--- a/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/e_sqrtf.c
@@ -20,6 +20,7 @@
 #include <math.h>
 #include <math_private.h>
 
+#undef __ieee754_sqrtf
 float
 __ieee754_sqrtf (float x)
 {