summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2008-04-10 19:21:13 +0000
committerJakub Jelinek <jakub@redhat.com>2008-04-10 19:21:13 +0000
commitb0c50524f1fb93adbd52e9950f92650e020b0d59 (patch)
treefd9af5238c7ebb9bb27ffafb3e47be9ed5ca2680 /sysdeps
parent3a2e541ba348de2bbab7b65328694403e61e5dff (diff)
Updated to fedora-glibc-20080410T1907
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/i386/i686/memcpy.S57
-rw-r--r--sysdeps/ieee754/ldbl-128/e_lgammal_r.c6
-rw-r--r--sysdeps/powerpc/fpu/Makefile1
-rw-r--r--sysdeps/powerpc/fpu/test-powerpc-snan.c385
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_isnan.S56
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_isnan.c7
-rw-r--r--sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.S119
-rw-r--r--sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.c62
-rw-r--r--sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.S111
-rw-r--r--sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.c60
-rw-r--r--sysdeps/powerpc/powerpc32/power4/hp-timing.c25
-rw-r--r--sysdeps/powerpc/powerpc32/power4/hp-timing.h152
-rw-r--r--sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S62
-rw-r--r--sysdeps/powerpc/powerpc32/power5/fpu/s_isnanf.S46
-rw-r--r--sysdeps/powerpc/powerpc32/power5/fpu/w_sqrt.S117
-rw-r--r--sysdeps/powerpc/powerpc32/power5/fpu/w_sqrtf.S109
-rw-r--r--sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S62
-rw-r--r--sysdeps/powerpc/powerpc32/power6/fpu/s_isnanf.S46
-rw-r--r--sysdeps/powerpc/powerpc64/dl-machine.h49
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_isnan.S57
-rw-r--r--sysdeps/powerpc/powerpc64/fpu/s_isnan.c7
-rw-r--r--sysdeps/powerpc/powerpc64/hp-timing.h6
-rw-r--r--sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S61
-rw-r--r--sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S60
-rw-r--r--sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S59
-rw-r--r--sysdeps/unix/sysv/linux/i386/vfork.S3
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/makecontext.c26
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/vfork.S3
-rw-r--r--sysdeps/unix/sysv/syscalls.list2
29 files changed, 1634 insertions, 182 deletions
diff --git a/sysdeps/i386/i686/memcpy.S b/sysdeps/i386/i686/memcpy.S
index 00e84ec2e5..ff5c66e9d4 100644
--- a/sysdeps/i386/i686/memcpy.S
+++ b/sysdeps/i386/i686/memcpy.S
@@ -1,7 +1,7 @@
/* Copy memory block and return pointer to beginning of destination block
For Intel 80x86, x>=6.
This file is part of the GNU C Library.
- Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2003, 2004, 2008 Free Software Foundation, Inc.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1999.
The GNU C Library is free software; you can redistribute it and/or
@@ -41,29 +41,64 @@ END (__memcpy_chk)
ENTRY (BP_SYM (memcpy))
ENTER
- movl LEN(%esp), %ecx
movl %edi, %eax
movl DEST(%esp), %edi
movl %esi, %edx
movl SRC(%esp), %esi
- CHECK_BOUNDS_BOTH_WIDE (%edi, DEST(%esp), %ecx)
- CHECK_BOUNDS_BOTH_WIDE (%esi, SRC(%esp), %ecx)
+ movl %edi, %ecx
+ xorl %esi, %ecx
+ andl $3, %ecx
+ movl LEN(%esp), %ecx
cld
- shrl $1, %ecx
- jnc 1f
+ jne .Lunaligned
+
+ cmpl $3, %ecx
+ jbe .Lunaligned
+
+ testl $3, %esi
+ je 1f
movsb
-1: shrl $1, %ecx
- jnc 2f
- movsw
-2: rep
+ decl %ecx
+ testl $3, %esi
+ je 1f
+ movsb
+ decl %ecx
+ testl $3, %esi
+ je 1f
+ movsb
+ decl %ecx
+1: pushl %eax
+ movl %ecx, %eax
+ shrl $2, %ecx
+ rep
movsl
- movl %eax, %edi
+ movl %eax, %ecx
+ andl $3, %ecx
+ rep
+ movsb
+ popl %eax
+
+.Lend: movl %eax, %edi
movl %edx, %esi
movl DEST(%esp), %eax
RETURN_BOUNDED_POINTER (DEST(%esp))
LEAVE
RET_PTR
+
+ /* When we come here the pointers do not have the same
+ alignment or the length is too short. No need to optimize for
+ aligned memory accesses. */
+.Lunaligned:
+ shrl $1, %ecx
+ jnc 1f
+ movsb
+1: shrl $1, %ecx
+ jnc 2f
+ movsw
+2: rep
+ movsl
+ jmp .Lend
END (BP_SYM (memcpy))
libc_hidden_builtin_def (memcpy)
diff --git a/sysdeps/ieee754/ldbl-128/e_lgammal_r.c b/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
index b9302974c0..d080448476 100644
--- a/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
+++ b/sysdeps/ieee754/ldbl-128/e_lgammal_r.c
@@ -772,6 +772,12 @@ __ieee754_lgammal_r (x, signgamp)
if (! __finitel (x))
return x * x;
+ if (x == 0.0L)
+ {
+ if (__signbitl (x))
+ *signgamp = -1;
+ }
+
if (x < 0.0L)
{
q = -x;
diff --git a/sysdeps/powerpc/fpu/Makefile b/sysdeps/powerpc/fpu/Makefile
index 060c952d15..ce67ff87df 100644
--- a/sysdeps/powerpc/fpu/Makefile
+++ b/sysdeps/powerpc/fpu/Makefile
@@ -1,5 +1,6 @@
ifeq ($(subdir),math)
libm-support += fenv_const fe_nomask fe_mask t_sqrt
+libm-tests += test-powerpc-snan
# libm needs ld.so to access dl_hwcap
$(objpfx)libm.so: $(elfobjdir)/ld.so
diff --git a/sysdeps/powerpc/fpu/test-powerpc-snan.c b/sysdeps/powerpc/fpu/test-powerpc-snan.c
new file mode 100644
index 0000000000..93b212abcb
--- /dev/null
+++ b/sysdeps/powerpc/fpu/test-powerpc-snan.c
@@ -0,0 +1,385 @@
+/* Test Signalling NaN in isnan, isinf etc functions.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 2005.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#define _GNU_SOURCE
+#define __USE_GNU
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <string.h>
+#include <math.h>
+#include <float.h>
+#include <fenv.h>
+#include <signal.h>
+#include <setjmp.h>
+#include <errno.h>
+
+int dest_offset;
+char *dest_address;
+double value = 123.456;
+double zero = 0.0;
+
+float SNANf;
+double SNAN;
+long double SNANl;
+
+static sigjmp_buf sigfpe_buf;
+
+void
+init_signaling_nan()
+{
+ union {
+ double _ld16;
+ double _d8;
+ unsigned int _ui4[4];
+ float _f4;
+ } nan_temp;
+
+ nan_temp._ui4[0] = 0x7fa00000;
+ SNANf = nan_temp._f4;
+
+ nan_temp._ui4[0] = 0x7ff40000;
+ nan_temp._ui4[1] = 0x00000000;
+ SNAN = nan_temp._d8;
+
+ nan_temp._ui4[0] = 0x7ff40000;
+ nan_temp._ui4[1] = 0x00000000;
+ nan_temp._ui4[2] = 0x00000000;
+ nan_temp._ui4[3] = 0x00000000;
+ SNANl = nan_temp._ld16;
+}
+
+static float
+snan_float (void)
+{
+ return SNANf;
+}
+
+static double
+snan_double (void)
+{
+ return SNAN;
+}
+
+typedef long double ldouble;
+
+static ldouble
+snan_ldouble (void)
+{
+ return SNANl;
+}
+
+
+void
+myFPsighandler(int signal,
+ siginfo_t *info,
+ void *context)
+{
+ siglongjmp(sigfpe_buf, 0);
+}
+
+int
+set_sigaction_FP(void)
+{
+ struct sigaction sa;
+ /* register RT signal handler via sigaction */
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_sigaction = &myFPsighandler;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, NULL);
+
+ return 0;
+}
+
+int
+remove_sigaction_FP(void)
+{
+ struct sigaction sa;
+ /* restore default RT signal handler via sigaction */
+ sa.sa_flags = SA_SIGINFO;
+ sa.sa_handler = SIG_DFL;
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGFPE, &sa, NULL);
+
+ return 0;
+}
+
+static int errors = 0;
+
+static void
+check (const char *testname, int result)
+{
+ if (!result) {
+ printf ("Failure: %s\n", testname);
+ errors++;
+ }
+}
+
+#define TEST_FUNC(NAME, FLOAT) \
+static void \
+NAME (void) \
+{ \
+ /* Variables are declared volatile to forbid some compiler \
+ optimizations. */ \
+ volatile FLOAT Inf_var, NaN_var, zero_var, one_var, SNaN_var; \
+ fenv_t saved_fenv; \
+ \
+ zero_var = 0.0; \
+ one_var = 1.0; \
+ NaN_var = zero_var / zero_var; \
+ SNaN_var = snan_##FLOAT (); \
+ Inf_var = one_var / zero_var; \
+ \
+ (void) &zero_var; \
+ (void) &one_var; \
+ (void) &NaN_var; \
+ (void) &SNaN_var; \
+ (void) &Inf_var; \
+ \
+ set_sigaction_FP (); \
+ fegetenv(&saved_fenv); \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnan(NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnan (NaN)", isnan (NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnan(-NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnan (-NaN)", isnan (-NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnan(SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnan (SNaN)", isnan (SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnan(-SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnan (-SNaN)", isnan (-SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isinf(NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isinf (NaN)", !isinf (NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isinf(-NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isinf (-NaN)", !isinf (-NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isinf(SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isinf (SNaN)", !isinf (SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isinf(-SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isinf (-SNaN)", !isinf (-SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isfinite(NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isfinite (NaN)", !isfinite (NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isfinite(-NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isfinite (-NaN)", !isfinite (-NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isfinite(SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isfinite (SNaN)", !isfinite (SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isfinite(-SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isfinite (-SNaN)", !isfinite (-SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnormal(NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnormal (NaN)", !isnormal (NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnormal(-NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnormal (-NaN)", !isnormal (-NaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnormal(SNaN) isnormal SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnormal (SNaN)", !isnormal (SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " isnormal(-SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " isnormal (-SNaN)", !isnormal (-SNaN_var)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " fpclassify(NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " fpclassify (NaN)", (fpclassify (NaN_var)==FP_NAN)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " fpclassify(-NaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " fpclassify (-NaN)", (fpclassify (-NaN_var)==FP_NAN)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " fpclassify(SNaN) isnormal SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " fpclassify (SNaN)", (fpclassify (SNaN_var)==FP_NAN)); \
+ } \
+ \
+ feclearexcept(FE_ALL_EXCEPT); \
+ feenableexcept (FE_ALL_EXCEPT); \
+ if (sigsetjmp(sigfpe_buf, 0)) \
+ { \
+ printf (#FLOAT " fpclassify(-SNaN) raised SIGFPE\n"); \
+ errors++; \
+ } else { \
+ check (#FLOAT " fpclassify (-SNaN)", (fpclassify (-SNaN_var)==FP_NAN)); \
+ } \
+ \
+ fesetenv(&saved_fenv); /* restore saved fenv */ \
+ remove_sigaction_FP(); \
+}
+
+TEST_FUNC (float_test, float)
+TEST_FUNC (double_test, double)
+#ifndef NO_LONG_DOUBLE
+TEST_FUNC (ldouble_test, ldouble)
+#endif
+
+static int
+do_test (void)
+{
+ init_signaling_nan();
+
+ float_test();
+ double_test();
+#ifndef NO_LONG_DOUBLE
+ ldouble_test();
+#endif
+
+ return errors != 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
+
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/fpu/s_isnan.S
new file mode 100644
index 0000000000..6e3f396de9
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_isnan.S
@@ -0,0 +1,56 @@
+/* isnan(). PowerPC32 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power4
+EALIGN (__isnan, 4, 0)
+ mffs fp0
+ mtfsb0 4*cr6+lt /* reset_fpscr_bit (FPSCR_VE) */
+ fcmpu cr7,fp1,fp1
+ mtfsf 255,fp0
+ li r3,0
+ beqlr+ cr7 /* (x == x) then not a NAN */
+ li r3,1 /* else must be a NAN */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+/* It turns out that the 'double' version will also always work for
+ single-precision. */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_isnan.c b/sysdeps/powerpc/powerpc32/fpu/s_isnan.c
deleted file mode 100644
index 397717ba9c..0000000000
--- a/sysdeps/powerpc/powerpc32/fpu/s_isnan.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <sysdeps/powerpc/fpu/s_isnan.c>
-#ifndef IS_IN_libm
-# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
-compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
-compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
-# endif
-#endif
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.S b/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.S
new file mode 100644
index 0000000000..6aef4e301b
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.S
@@ -0,0 +1,119 @@
+/* sqrt function. PowerPC32 version.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* double [fp1] sqrt (double x [fp1])
+ Power4 (ISA V2.0) and above implement sqrt in hardware (not optional).
+ The fsqrt instruction generates the correct value for all inputs and
+ sets the appropriate floating point exceptions. Extented checking is
+ only needed to set errno (via __kernel_standard) if the input value
+ is negative.
+
+ The fsqrt will set FPCC and FU (Floating Point Unordered or NaN
+ to indicated that the input value was negative or NaN. Use Move to
+ Condition Register from FPSCR to copy the FPCC field to cr1. The
+ branch on summary overflow transfers control to w_sqrt to process
+ any error conditions. Otherwise we can return the result directly.
+
+ This part of the function is a leaf routine, so no need to stack a
+ frame or execute prologue/epilogue code. This means it is safe to
+ transfer directly to w_sqrt as long as the input value (f1) is
+ preserved. Putting the the sqrt result into f2 (double parameter 2)
+ allows passing both the input value and sqrt result into the extended
+ wrapper so there is no need to recompute.
+
+ This tactic avoids the overhead of stacking a frame for the normal
+ (non-error) case. Until gcc supports prologue shrink-wrapping
+ this is the best we can do. */
+
+ .section ".text"
+ .machine power4
+EALIGN (__sqrt, 5, 0)
+ fsqrt fp2,fp1
+ mcrfs cr1,4
+ bso- cr1,.Lw_sqrt
+ fmr fp1,fp2
+ blr
+ .align 4
+.Lw_sqrt:
+ mflr r0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset(16)
+ fmr fp12,fp2
+ stw r0,20(r1)
+ stw r30,8(r1)
+ cfi_offset(lr,20)
+ cfi_offset(r30,8)
+#ifdef SHARED
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,.LCF1
+.LCF1:
+ mflr r30
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@ha
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@l
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r30
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# endif
+#else
+ lis r9,_LIB_VERSION@ha
+ lwz r0,_LIB_VERSION@l(r9)
+#endif
+/* if (_LIB_VERSION == _IEEE_) return z; */
+ cmpwi cr7,r0,-1
+ beq- cr7,.L4
+/* if (x != x) return z; !isnan*/
+ fcmpu cr7,fp1,fp1
+ bne- cr7,.L4
+/* if (x < 0.0)
+ return __kernel_standard (x, x, 26) */
+ fmr fp2,fp1
+ fabs fp0,fp1
+ li r3,26
+ fcmpu cr7,fp1,fp0
+ bne- cr7,.L11
+.L4:
+ lwz r0,20(r1)
+ fmr fp1,fp12
+ lwz r30,8(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+.L11:
+ bl __kernel_standard@plt
+ fmr fp12,fp1
+ b .L4
+ END (__sqrt)
+
+weak_alias (__sqrt, sqrt)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__sqrt, sqrtl)
+strong_alias (__sqrt, __sqrtl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0)
+#endif
+
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.c b/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.c
deleted file mode 100644
index f59c193934..0000000000
--- a/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrt.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Double-precision floating point square root wrapper.
- Copyright (C) 2004, 2007 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include <math_ldbl_opt.h>
-#include "math.h"
-#include "math_private.h"
-#include <fenv_libc.h>
-
-#ifdef __STDC__
-double
-__sqrt (double x) /* wrapper sqrt */
-#else
-double
-__sqrt (x) /* wrapper sqrt */
- double x;
-#endif
-{
- double z;
-/* Power4 (ISA V2.0) and above implement sqrt in hardware. */
- __asm __volatile (
- " fsqrt %0,%1\n"
- : "=f" (z)
- : "f" (x));
-#ifdef _IEEE_LIBM
- return z;
-#else
- if (__builtin_expect (_LIB_VERSION == _IEEE_, 0))
- return z;
-
- if (__builtin_expect (x != x, 0))
- return z;
-
- if (__builtin_expect (x < 0.0, 0))
- return __kernel_standard (x, x, 26); /* sqrt(negative) */
- else
- return z;
-#endif
-}
-
-weak_alias (__sqrt, sqrt)
-#ifdef NO_LONG_DOUBLE
- strong_alias (__sqrt, __sqrtl) weak_alias (__sqrt, sqrtl)
-#endif
-#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
-compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0);
-#endif
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.S b/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.S
new file mode 100644
index 0000000000..e5b8b9d565
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.S
@@ -0,0 +1,111 @@
+/* sqrtf function. PowerPC32 version.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* float [fp1] sqrts (float x [fp1])
+ Power4 (ISA V2.0) and above implement sqrt in hardware (not optional).
+ The fsqrts instruction generates the correct value for all inputs and
+ sets the appropriate floating point exceptions. Extented checking is
+ only needed to set errno (via __kernel_standard) if the input value
+ is negative.
+
+ The fsqrts will set FPCC and FU (Floating Point Unordered or NaN
+ to indicated that the input value was negative or NaN. Use Move to
+ Condition Register from FPSCR to copy the FPCC field to cr1. The
+ branch on summary overflow transfers control to w_sqrt to process
+ any error conditions. Otherwise we can return the result directly.
+
+ This part of the function is a leaf routine, so no need to stack a
+ frame or execute prologue/epilogue code. This means it is safe to
+ transfer directly to w_sqrt as long as the input value (f1) is
+ preserved. Putting the the sqrt result into f2 (float parameter 2)
+ allows passing both the input value and sqrt result into the extended
+ wrapper so there is no need to recompute.
+
+ This tactic avoids the overhead of stacking a frame for the normal
+ (non-error) case. Until gcc supports prologue shrink-wrapping
+ this is the best we can do. */
+
+ .section ".text"
+ .machine power4
+EALIGN (__sqrtf, 5, 0)
+ fsqrts fp2,fp1
+ mcrfs cr1,4
+ bso- cr1,.Lw_sqrtf
+ fmr fp1,fp2
+ blr
+ .align 4
+.Lw_sqrtf:
+ mflr r0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset(16)
+ fmr fp12,fp2
+ stw r0,20(r1)
+ stw r30,8(r1)
+ cfi_offset(lr,20)
+ cfi_offset(r30,8)
+#ifdef SHARED
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,.LCF1
+.LCF1:
+ mflr r30
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@ha
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@l
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r30
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# endif
+#else
+ lis r9,_LIB_VERSION@ha
+ lwz r0,_LIB_VERSION@l(r9)
+#endif
+/* if (_LIB_VERSION == _IEEE_) return z; */
+ cmpwi cr7,r0,-1
+ beq- cr7,.L4
+/* if (x != x, 0) return z; !isnan */
+ fcmpu cr7,fp1,fp1
+ bne- cr7,.L4
+/* if (x < 0.0)
+ return __kernel_standard (x, x, 126) */
+ fmr fp2,fp1
+ fabs fp0,fp1
+ li r3,126
+ fcmpu cr7,1,0
+ bne- cr7,.L11
+.L4:
+ lwz r0,20(r1)
+ fmr fp1,fp12
+ lwz r30,8(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+.L11:
+ bl __kernel_standard@plt
+ fmr fp12,fp1
+ b .L4
+ END (__sqrtf)
+
+weak_alias (__sqrtf, sqrtf)
+
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.c b/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.c
deleted file mode 100644
index 4784869f07..0000000000
--- a/sysdeps/powerpc/powerpc32/power4/fpu/w_sqrtf.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Single-precision floating point square root wrapper.
- Copyright (C) 2004, 2007 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, write to the Free
- Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
- 02111-1307 USA. */
-
-#include "math.h"
-#include "math_private.h"
-#include <fenv_libc.h>
-
-#include <sysdep.h>
-#include <ldsodefs.h>
-
-#ifdef __STDC__
-float
-__sqrtf (float x) /* wrapper sqrtf */
-#else
-float
-__sqrtf (x) /* wrapper sqrtf */
- float x;
-#endif
-{
-#ifdef _IEEE_LIBM
- return __ieee754_sqrtf (x);
-#else
- float z;
-/* Power4 (ISA V2.0) and above implement sqrtf in hardware. */
- __asm __volatile (
- " fsqrts %0,%1\n"
- : "=f" (z)
- : "f" (x));
-
- if (__builtin_expect (_LIB_VERSION == _IEEE_, 0))
- return z;
-
- if (__builtin_expect (x != x, 0))
- return z;
-
- if (__builtin_expect (x < 0.0, 0))
- /* sqrtf(negative) */
- return (float) __kernel_standard ((double) x, (double) x, 126);
- else
- return z;
-#endif
-}
-
-weak_alias (__sqrtf, sqrtf)
diff --git a/sysdeps/powerpc/powerpc32/power4/hp-timing.c b/sysdeps/powerpc/powerpc32/power4/hp-timing.c
new file mode 100644
index 0000000000..332fe8af99
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/hp-timing.c
@@ -0,0 +1,25 @@
+/* Support for high precision, low overhead timing functions.
+ powerpc64 version.
+ Copyright (C) 2005, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <hp-timing.h>
+
+/* We have to define the variable for the overhead. */
+hp_timing_t _dl_hp_timing_overhead;
diff --git a/sysdeps/powerpc/powerpc32/power4/hp-timing.h b/sysdeps/powerpc/powerpc32/power4/hp-timing.h
new file mode 100644
index 0000000000..5f719dd5a1
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power4/hp-timing.h
@@ -0,0 +1,152 @@
+/* High precision, low overhead timing functions. powerpc64 version.
+ Copyright (C) 2005, 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H 1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+#include <atomic.h>
+
+/* The macros defined here use the powerpc 64-bit time base register.
+ The time base is nominally clocked at 1/8th the CPU clock, but this
+ can vary.
+
+ The list of macros we need includes the following:
+
+ - HP_TIMING_AVAIL: test for availability.
+
+ - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+ implemented using function calls but instead uses some inlined code
+ which might simply consist of a few assembler instructions. We have to
+ know this since we might want to use the macros here in places where we
+ cannot make function calls.
+
+ - hp_timing_t: This is the type for variables used to store the time
+ values.
+
+ - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+ - HP_TIMING_NOW: place timestamp for current time in variable given as
+ parameter.
+
+ - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+ HP_TIMING_DIFF macro.
+
+ - HP_TIMING_DIFF: compute difference between two times and store it
+ in a third. Source and destination might overlap.
+
+ - HP_TIMING_ACCUM: add time difference to another variable. This might
+ be a bit more complicated to implement for some platforms as the
+ operation should be thread-safe and 64bit arithmetic on 32bit platforms
+ is not.
+
+ - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+ there are no threads involved.
+
+ - HP_TIMING_PRINT: write decimal representation of the timing value into
+ the given string. This operation need not be inline even though
+ HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register. */
+#define HP_TIMING_AVAIL (1)
+
+/* We indeed have inlined functions. */
+#define HP_TIMING_INLINE (1)
+
+/* We use 64bit values for the times. */
+typedef unsigned long long int hp_timing_t;
+
+/* Set timestamp value to zero. */
+#define HP_TIMING_ZERO(Var) (Var) = (0)
+
+/* That's quite simple. Use the `mftb' instruction. Note that the value
+ might not be 100% accurate since there might be some more instructions
+ running in this moment. This could be changed by using a barrier like
+ 'lwsync' right before the `mftb' instruciton. But we are not interested
+ in accurate clock cycles here so we don't do this. */
+
+#define HP_TIMING_NOW(Var) \
+ do { \
+ union { long long ll; long ii[2]; } _var; \
+ long tmp; \
+ __asm__ __volatile__ ( \
+ "1: mfspr %0,269;" \
+ " mfspr %1,268;" \
+ " mfspr %2,269;" \
+ " cmpw %0,%2;" \
+ " bne 1b;" \
+ : "=r" (_var.ii[0]), "=r" (_var.ii[1]) , "=r" (tmp) \
+ : : "cr0" \
+ ); \
+ Var = _var.ll; \
+ } while (0)
+
+
+/* Use two 'mftb' instructions in a row to find out how long it takes.
+ On current POWER4, POWER5, and 970 processors mftb take ~10 cycles. */
+#define HP_TIMING_DIFF_INIT() \
+ do { \
+ if (GLRO(dl_hp_timing_overhead) == 0) \
+ { \
+ int __cnt = 5; \
+ GLRO(dl_hp_timing_overhead) = ~0ull; \
+ do \
+ { \
+ hp_timing_t __t1, __t2; \
+ HP_TIMING_NOW (__t1); \
+ HP_TIMING_NOW (__t2); \
+ if (__t2 - __t1 < GLRO(dl_hp_timing_overhead)) \
+ GLRO(dl_hp_timing_overhead) = __t2 - __t1; \
+ } \
+ while (--__cnt > 0); \
+ } \
+ } while (0)
+
+/* It's simple arithmetic in 64-bit. */
+#define HP_TIMING_DIFF(Diff, Start, End) (Diff) = ((End) - (Start))
+
+/* We need to insure that this add is atomic in threaded environments. We use
+ __arch_atomic_exchange_and_add_64 from atomic.h to get thread safety. */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+ do { \
+ hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead); \
+ __arch_atomic_exchange_and_add_64 (&(Sum), __diff); \
+ } while (0)
+
+/* No threads, no extra work. */
+#define HP_TIMING_ACCUM_NT(Sum, Diff) (Sum) += (Diff)
+
+/* Print the time value. */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+ do { \
+ char __buf[20]; \
+ char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0); \
+ size_t __len = (Len); \
+ char *__dest = (Buf); \
+ while (__len-- > 0 && __cp < __buf + sizeof (__buf)) \
+ *__dest++ = *__cp++; \
+ memcpy (__dest, " ticks", MIN (__len, sizeof (" ticks"))); \
+ } while (0)
+
+#endif /* hp-timing.h */
diff --git a/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S
new file mode 100644
index 0000000000..91337483d7
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power5/fpu/s_isnan.S
@@ -0,0 +1,62 @@
+/* isnan(). PowerPC32 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power5
+EALIGN (__isnan, 4, 0)
+ stwu r1,-32(r1)
+ cfi_adjust_cfa_offset (32)
+ ori r1,r1,0
+ stfd fp1,24(r1) /* copy FPR to GPR */
+ ori r1,r1,0
+ lwz r4,24(r1)
+ lwz r5,28(r1)
+ lis r0,0x7ff0 /* const long r0 0x7ff00000 00000000 */
+ clrlwi r4,r4,1 /* x = fabs(x) */
+ cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */
+ cmpwi cr6,r5,0
+ li r3,0 /* then return 0 */
+ addi r1,r1,32
+ cfi_adjust_cfa_offset (-32)
+ bltlr+ cr7
+ bgt- cr7,L(NaN)
+ beqlr+ cr6
+L(NaN):
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/powerpc/powerpc32/power5/fpu/s_isnanf.S b/sysdeps/powerpc/powerpc32/power5/fpu/s_isnanf.S
new file mode 100644
index 0000000000..9b1e95f35f
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power5/fpu/s_isnanf.S
@@ -0,0 +1,46 @@
+/* isnan(). PowerPC32 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnanf(x) */
+ .machine power5
+EALIGN (__isnanf, 4, 0)
+ stwu r1,-32(r1)
+ cfi_adjust_cfa_offset (32)
+ stfs fp1,28(r1) /* copy FPR to GPR */
+ nop
+ nop
+ lwz r4,28(r1)
+ lis r0,0x7f80 /* const long r0 0x7f800000 */
+ clrlwi r4,r4,1 /* x = fabs(x) */
+ cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */
+ li r3,0 /* then return 0 */
+ addi r1,r1,32
+ cfi_adjust_cfa_offset (-32)
+ blelr+ cr7
+L(NaN):
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnanf)
+
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
diff --git a/sysdeps/powerpc/powerpc32/power5/fpu/w_sqrt.S b/sysdeps/powerpc/powerpc32/power5/fpu/w_sqrt.S
new file mode 100644
index 0000000000..925930bf77
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power5/fpu/w_sqrt.S
@@ -0,0 +1,117 @@
+/* sqrt function. PowerPC32 version.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* double [fp1] sqrt (double x [fp1])
+ Power4 (ISA V2.0) and above implement sqrt in hardware (not optional).
+ The fsqrt instruction generates the correct value for all inputs and
+ sets the appropriate floating point exceptions. Extented checking is
+ only needed to set errno (via __kernel_standard) if the input value
+ is negative.
+
+ So compare the input value against the absolute value of itself.
+ This will compare equal unless the value is negative (EDOM) or a NAN,
+ in which case we branch to the extend wrapper. If equal we can return
+ the result directly.
+
+ This part of the function looks like a leaf routine, so no need to
+ stack a frame or execute prologue/epilogue code. It is safe to
+ branch directly to w_sqrt as long as the input value (f1) is
+ preserved. Putting the the sqrt result into f2 (float parameter 2)
+ allows passing both the input value and sqrt result into the extended
+ wrapper so there is no need to recompute.
+
+ This tactic avoids the overhead of stacking a frame for the normal
+ (non-error) case. Until gcc supports prologue shrink-wrapping
+ this is the best we can do. */
+
+ .section ".text"
+ .machine power4
+EALIGN (__sqrt, 5, 0)
+ fabs fp0,fp1
+ fsqrt fp2,fp1
+ fcmpu cr1,fp0,fp1
+ bne- cr1,.Lw_sqrt
+ fmr fp1,fp2
+ blr
+ .align 4
+.Lw_sqrt:
+ mflr r0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset(16)
+ fmr fp12,fp2
+ stw r0,20(r1)
+ stw r30,8(r1)
+ cfi_offset(lr,20)
+ cfi_offset(r30,8)
+#ifdef SHARED
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,.LCF1
+.LCF1:
+ mflr r30
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@ha
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@l
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r30
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# endif
+#else
+ lis r9,_LIB_VERSION@ha
+ lwz r0,_LIB_VERSION@l(r9)
+#endif
+/* if (_LIB_VERSION == _IEEE_) return z; */
+ cmpwi cr7,r0,-1
+ beq- cr7,.L4
+/* if (x != x) return z; !isnan*/
+ fcmpu cr7,fp1,fp1
+ bne- cr7,.L4
+/* if (x < 0.0)
+ return __kernel_standard (x, x, 26) */
+ fmr fp2,fp1
+ li r3,26
+ bne- cr1,.L11
+.L4:
+ lwz r0,20(r1)
+ fmr fp1,fp12
+ lwz r30,8(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+.L11:
+ bl __kernel_standard@plt
+ fmr fp12,fp1
+ b .L4
+ END (__sqrt)
+
+weak_alias (__sqrt, sqrt)
+
+#ifdef NO_LONG_DOUBLE
+weak_alias (__sqrt, sqrtl)
+strong_alias (__sqrt, __sqrtl)
+#endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __sqrt, sqrtl, GLIBC_2_0)
+#endif
+
diff --git a/sysdeps/powerpc/powerpc32/power5/fpu/w_sqrtf.S b/sysdeps/powerpc/powerpc32/power5/fpu/w_sqrtf.S
new file mode 100644
index 0000000000..891e69c9c0
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power5/fpu/w_sqrtf.S
@@ -0,0 +1,109 @@
+/* sqrtf function. PowerPC32 version.
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+ 02110-1301 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* float [fp1] sqrts (float x [fp1])
+ Power4 (ISA V2.0) and above implement sqrt in hardware (not optional).
+ The fsqrts instruction generates the correct value for all inputs and
+ sets the appropriate floating point exceptions. Extented checking is
+ only needed to set errno (via __kernel_standard) if the input value
+ is negative.
+
+ So compare the input value against the absolute value of itself.
+ This will compare equal unless the value is negative (EDOM) or a NAN,
+ in which case we branch to the extend wrapper. If equal we can return
+ the result directly.
+
+ This part of the function looks like a leaf routine, so no need to
+ stack a frame or execute prologue/epilogue code. It is safe to
+ branch directly to w_sqrt as long as the input value (f1) is
+ preserved. Putting the the sqrt result into f2 (float parameter 2)
+ allows passing both the input value and sqrt result into the extended
+ wrapper so there is no need to recompute.
+
+ This tactic avoids the overhead of stacking a frame for the normal
+ (non-error) case. Until gcc supports prologue shrink-wrapping
+ this is the best we can do. */
+
+ .section ".text"
+ .machine power4
+EALIGN (__sqrtf, 5, 0)
+ fabs fp0,fp1
+ fsqrts fp2,fp1
+ fcmpu cr1,fp0,fp1
+ bne- cr1,.Lw_sqrtf
+ fmr fp1,fp2
+ blr
+ .align 4
+.Lw_sqrtf:
+ mflr r0
+ stwu r1,-16(r1)
+ cfi_adjust_cfa_offset(16)
+ fmr fp12,fp2
+ stw r0,20(r1)
+ stw r30,8(r1)
+ cfi_offset(lr,20)
+ cfi_offset(r30,8)
+#ifdef SHARED
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,.LCF1
+.LCF1:
+ mflr r30
+ addis r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@ha
+ addi r30,r30,_GLOBAL_OFFSET_TABLE_-.LCF1@l
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# else
+ bl _GLOBAL_OFFSET_TABLE_@local-4
+ mflr r30
+ lwz r9,_LIB_VERSION@got(30)
+ lwz r0,0(r9)
+# endif
+#else
+ lis r9,_LIB_VERSION@ha
+ lwz r0,_LIB_VERSION@l(r9)
+#endif
+/* if (_LIB_VERSION == _IEEE_) return z; */
+ cmpwi cr7,r0,-1
+ beq- cr7,.L4
+/* if (x != x, 0) return z; !isnan */
+ fcmpu cr7,fp1,fp1
+ bne- cr7,.L4
+/* if (x < 0.0)
+ return __kernel_standard (x, x, 126) */
+ fmr fp2,fp1
+ li r3,126
+ bne- cr1,.L11
+.L4:
+ lwz r0,20(r1)
+ fmr fp1,fp12
+ lwz r30,8(r1)
+ addi r1,r1,16
+ mtlr r0
+ blr
+.L11:
+ bl __kernel_standard@plt
+ fmr fp12,fp1
+ b .L4
+ END (__sqrtf)
+
+weak_alias (__sqrtf, sqrtf)
+
diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S
new file mode 100644
index 0000000000..dbaaf1c1a8
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power6/fpu/s_isnan.S
@@ -0,0 +1,62 @@
+/* isnan(). PowerPC32 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power6
+EALIGN (__isnan, 4, 0)
+ stwu r1,-32(r1)
+ cfi_adjust_cfa_offset (32)
+ ori r1,r1,0
+ stfd fp1,24(r1) /* copy FPR to GPR */
+ ori r1,r1,0
+ lwz r4,24(r1)
+ lwz r5,28(r1)
+ lis r0,0x7ff0 /* const long r0 0x7ff00000 00000000 */
+ clrlwi r4,r4,1 /* x = fabs(x) */
+ cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */
+ cmpwi cr6,r5,0
+ li r3,0 /* then return 0 */
+ addi r1,r1,32
+ cfi_adjust_cfa_offset (-32)
+ bltlr+ cr7
+ bgt- cr7,L(NaN)
+ beqlr+ cr6
+L(NaN):
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/powerpc/powerpc32/power6/fpu/s_isnanf.S b/sysdeps/powerpc/powerpc32/power6/fpu/s_isnanf.S
new file mode 100644
index 0000000000..12bf473a8d
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/power6/fpu/s_isnanf.S
@@ -0,0 +1,46 @@
+/* isnanf(). PowerPC32 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnanf(x) */
+ .machine power6
+EALIGN (__isnanf, 4, 0)
+ stwu r1,-32(r1)
+ cfi_adjust_cfa_offset (32)
+ ori r1,r1,0
+ stfs fp1,24(r1) /* copy FPR to GPR */
+ ori r1,r1,0
+ lwz r4,24(r1)
+ lis r0,0x7f80 /* const long r0 0x7f800000 */
+ clrlwi r4,r4,1 /* x = fabs(x) */
+ cmpw cr7,r4,r0 /* if (fabs(x) =< inf) */
+ li r3,0 /* then return 0 */
+ addi r1,r1,32
+ cfi_adjust_cfa_offset (-32)
+ blelr+ cr7
+L(NaN):
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnan)
+
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
diff --git a/sysdeps/powerpc/powerpc64/dl-machine.h b/sysdeps/powerpc/powerpc64/dl-machine.h
index 89a69e1a23..c837393d79 100644
--- a/sysdeps/powerpc/powerpc64/dl-machine.h
+++ b/sysdeps/powerpc/powerpc64/dl-machine.h
@@ -246,30 +246,35 @@ BODY_PREFIX "_dl_start_user:\n" \
" " END_2(_dl_start_user) "\n" \
" .popsection");
-/* Nonzero iff TYPE should not be allowed to resolve to one of
- the main executable's symbols, as for a COPY reloc. */
-#define elf_machine_lookup_noexec_p(type) ((type) == R_PPC64_COPY)
+/* ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to
+ one of the main executable's symbols, as for a COPY reloc.
+
+ To make function pointer comparisons work on most targets, the
+ relevant ABI states that the address of a non-local function in a
+ dynamically linked executable is the address of the PLT entry for
+ that function. This is quite reasonable since using the real
+ function address in a non-PIC executable would typically require
+ dynamic relocations in .text, something to be avoided. For such
+ functions, the linker emits a SHN_UNDEF symbol in the executable
+ with value equal to the PLT entry address. Normally, SHN_UNDEF
+ symbols have a value of zero, so this is a clue to ld.so that it
+ should treat these symbols specially. For relocations not in
+ ELF_RTYPE_CLASS_PLT (eg. those on function pointers), ld.so should
+ use the value of the executable SHN_UNDEF symbol, ie. the PLT entry
+ address. For relocations in ELF_RTYPE_CLASS_PLT (eg. the relocs in
+ the PLT itself), ld.so should use the value of the corresponding
+ defined symbol in the object that defines the function, ie. the
+ real function address. This complicates ld.so in that there are
+ now two possible values for a given symbol, and it gets even worse
+ because protected symbols need yet another set of rules.
+
+ On PowerPC64 we don't need any of this. The linker won't emit
+ SHN_UNDEF symbols with non-zero values. ld.so can make all
+ relocations behave "normally", ie. always use the real address
+ like PLT relocations. So always set ELF_RTYPE_CLASS_PLT. */
-/* Nonzero iff TYPE describes relocation of a PLT entry, so
- PLT entries should not be allowed to define the value. */
-#define elf_machine_lookup_noplt_p(type) ((type) == R_PPC64_JMP_SLOT)
-
-/* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
- PLT entries should not be allowed to define the value.
- ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one
- of the main executable's symbols, as for a COPY reloc. */
-
-#if !defined RTLD_BOOTSTRAP || USE___THREAD
-#define elf_machine_type_class(type) \
- /* This covers all the TLS relocs, though most won't appear. */ \
- (((((type) >= R_PPC64_DTPMOD64 && (type) <= R_PPC64_TPREL16_HIGHESTA) \
- || (type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \
- | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
-#else
#define elf_machine_type_class(type) \
- ((((type) == R_PPC64_ADDR24) * ELF_RTYPE_CLASS_PLT) \
- | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
-#endif
+ (ELF_RTYPE_CLASS_PLT | (((type) == R_PPC64_COPY) * ELF_RTYPE_CLASS_COPY))
/* A reloc type used for ld.so cmdline arg lookups to reject PLT entries. */
#define ELF_MACHINE_JMP_SLOT R_PPC64_JMP_SLOT
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/fpu/s_isnan.S
new file mode 100644
index 0000000000..9963896f2d
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/fpu/s_isnan.S
@@ -0,0 +1,57 @@
+/* isnan(). PowerPC64 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power4
+EALIGN (__isnan, 4, 0)
+ CALL_MCOUNT 0
+ mffs fp0
+ mtfsb0 4*cr6+lt /* reset_fpscr_bit (FPSCR_VE) */
+ fcmpu cr7,fp1,fp1
+ mtfsf 255,fp0
+ li r3,0
+ beqlr+ cr7 /* (x == x) then not a NAN */
+ li r3,1 /* else must be a NAN */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+/* It turns out that the 'double' version will also always work for
+ single-precision. */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/powerpc/powerpc64/fpu/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/s_isnan.c
deleted file mode 100644
index 397717ba9c..0000000000
--- a/sysdeps/powerpc/powerpc64/fpu/s_isnan.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#include <sysdeps/powerpc/fpu/s_isnan.c>
-#ifndef IS_IN_libm
-# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
-compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
-compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
-# endif
-#endif
diff --git a/sysdeps/powerpc/powerpc64/hp-timing.h b/sysdeps/powerpc/powerpc64/hp-timing.h
index b58cca9003..e107a2dd49 100644
--- a/sysdeps/powerpc/powerpc64/hp-timing.h
+++ b/sysdeps/powerpc/powerpc64/hp-timing.h
@@ -1,5 +1,5 @@
/* High precision, low overhead timing functions. powerpc64 version.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
@@ -85,7 +85,11 @@ typedef unsigned long long int hp_timing_t;
running in this moment. This could be changed by using a barrier like
'lwsync' right before the `mftb' instruciton. But we are not interested
in accurate clock cycles here so we don't do this. */
+#ifdef _ARCH_PWR4
+#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mfspr %0,268" : "=r" (Var))
+#else
#define HP_TIMING_NOW(Var) __asm__ __volatile__ ("mftb %0" : "=r" (Var))
+#endif
/* Use two 'mftb' instructions in a row to find out how long it takes.
On current POWER4, POWER5, and 970 processors mftb take ~10 cycles. */
diff --git a/sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S
new file mode 100644
index 0000000000..d46d049d45
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S
@@ -0,0 +1,61 @@
+/* isnan(). PowerPC64 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power5
+EALIGN (__isnan, 4, 0)
+ CALL_MCOUNT 0
+ stfd fp1,-8(r1) /* copy FPR to GPR */
+ lis r0,0x7ff0
+ nop /* insure the following is in a different */
+ nop /* dispatch group */
+ ld r4,-8(r1)
+ sldi r0,r0,32 /* const long r0 0x7ff00000 00000000 */
+ clrldi r4,r4,1 /* x = fabs(x) */
+ cmpd cr7,r4,r0 /* if (fabs(x) <= inf) */
+ li r3,0 /* then return 0 */
+ blelr+ cr7
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+/* It turns out that the 'double' version will also always work for
+ single-precision. */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S
new file mode 100644
index 0000000000..fe0c56ca8e
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S
@@ -0,0 +1,60 @@
+/* isnan(). PowerPC64 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power6
+EALIGN (__isnan, 4, 0)
+ CALL_MCOUNT 0
+ stfd fp1,-8(r1) /* copy FPR to GPR */
+ ori r1,r1,0
+ ld r4,-8(r1)
+ lis r0,0x7ff0
+ sldi r0,r0,32 /* const long r0 0x7ff00000 00000000 */
+ clrldi r4,r4,1 /* x = fabs(x) */
+ cmpd cr7,r4,r0 /* if (fabs(x) <= inf) */
+ li r3,0 /* then return 0 */
+ blelr+ cr7
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+/* It turns out that the 'double' version will also always work for
+ single-precision. */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S b/sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S
new file mode 100644
index 0000000000..47dd49a751
--- /dev/null
+++ b/sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S
@@ -0,0 +1,59 @@
+/* isnan(). PowerPC64 version.
+ Copyright (C) 2008 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <sysdep.h>
+#include <math_ldbl_opt.h>
+
+/* int __isnan(x) */
+ .machine power6
+EALIGN (__isnan, 4, 0)
+ CALL_MCOUNT 0
+ mftgpr r4,fp1 /* copy FPR to GPR */
+ lis r0,0x7ff0
+ ori r1,r1,0
+ clrldi r4,r4,1 /* x = fabs(x) */
+ sldi r0,r0,32 /* const long r0 0x7ff00000 00000000 */
+ cmpd cr7,r4,r0 /* if (fabs(x) <= inf) */
+ li r3,0 /* then return 0 */
+ blelr+ cr7
+ li r3,1 /* else return 1 */
+ blr
+ END (__isnan)
+
+hidden_def (__isnan)
+weak_alias (__isnan, isnan)
+
+/* It turns out that the 'double' version will also always work for
+ single-precision. */
+strong_alias (__isnan, __isnanf)
+hidden_def (__isnanf)
+weak_alias (__isnanf, isnanf)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__isnan, __isnanl)
+weak_alias (__isnan, isnanl)
+#endif
+
+#ifndef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __isnan, __isnanl, GLIBC_2_0);
+compat_symbol (libc, isnan, isnanl, GLIBC_2_0);
+# endif
+#endif
+
diff --git a/sysdeps/unix/sysv/linux/i386/vfork.S b/sysdeps/unix/sysv/linux/i386/vfork.S
index eefd4b49cb..2494d9bef0 100644
--- a/sysdeps/unix/sysv/linux/i386/vfork.S
+++ b/sysdeps/unix/sysv/linux/i386/vfork.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2002, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2002, 2004, 2005, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Schwab <schwab@gnu.org>.
@@ -34,6 +34,7 @@ ENTRY (__vfork)
/* Pop the return PC value into ECX. */
popl %ecx
cfi_adjust_cfa_offset (-4)
+ cfi_register (%eip, %ecx)
#ifdef SAVE_PID
SAVE_PID
diff --git a/sysdeps/unix/sysv/linux/x86_64/makecontext.c b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
index 5deea7d1b2..615dede522 100644
--- a/sysdeps/unix/sysv/linux/x86_64/makecontext.c
+++ b/sysdeps/unix/sysv/linux/x86_64/makecontext.c
@@ -1,5 +1,5 @@
/* Create new context.
- Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2002.
@@ -78,31 +78,39 @@ __makecontext (ucontext_t *ucp, void (*func) (void), int argc, ...)
sp[idx_uc_link] = (unsigned long int) ucp->uc_link;
va_start (ap, argc);
- /* Handle arguments. */
+ /* Handle arguments.
+
+ The standard says the parameters must all be int values. This is
+ an historic accident and would be done differently today. For
+ x86-64 all integer values are passed as 64-bit values and
+ therefore extending the API to copy 64-bit values instead of
+ 32-bit ints makes sense. It does not break existing
+ functionality and it does not violate the standard which says
+ that passing non-int values means undefined behavior. */
for (i = 0; i < argc; ++i)
switch (i)
{
case 0:
- ucp->uc_mcontext.gregs [REG_RDI] = va_arg (ap, int);
+ ucp->uc_mcontext.gregs[REG_RDI] = va_arg (ap, long int);
break;
case 1:
- ucp->uc_mcontext.gregs [REG_RSI] = va_arg (ap, int);
+ ucp->uc_mcontext.gregs[REG_RSI] = va_arg (ap, long int);
break;
case 2:
- ucp->uc_mcontext.gregs [REG_RDX] = va_arg (ap, int);
+ ucp->uc_mcontext.gregs[REG_RDX] = va_arg (ap, long int);
break;
case 3:
- ucp->uc_mcontext.gregs [REG_RCX] = va_arg (ap, int);
+ ucp->uc_mcontext.gregs[REG_RCX] = va_arg (ap, long int);
break;
case 4:
- ucp->uc_mcontext.gregs [REG_R8] = va_arg (ap, int);
+ ucp->uc_mcontext.gregs[REG_R8] = va_arg (ap, long int);
break;
case 5:
- ucp->uc_mcontext.gregs [REG_R9] = va_arg (ap, int);
+ ucp->uc_mcontext.gregs[REG_R9] = va_arg (ap, long int);
break;
default:
/* Put value on stack. */
- sp[(i - 5)] = va_arg (ap, int);
+ sp[i - 5] = va_arg (ap, unsigned long int);
break;
}
va_end (ap);
diff --git a/sysdeps/unix/sysv/linux/x86_64/vfork.S b/sysdeps/unix/sysv/linux/x86_64/vfork.S
index 4bad38892b..e289656ad2 100644
--- a/sysdeps/unix/sysv/linux/x86_64/vfork.S
+++ b/sysdeps/unix/sysv/linux/x86_64/vfork.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2001, 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2001, 2002, 2004, 2008 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,6 +31,7 @@ ENTRY (__vfork)
is preserved by the syscall and that we're allowed to destroy. */
popq %rdi
cfi_adjust_cfa_offset(-8)
+ cfi_register(%rip, %rdi)
#ifdef SAVE_PID
SAVE_PID
diff --git a/sysdeps/unix/sysv/syscalls.list b/sysdeps/unix/sysv/syscalls.list
index 436d05eb9a..f65ed79f70 100644
--- a/sysdeps/unix/sysv/syscalls.list
+++ b/sysdeps/unix/sysv/syscalls.list
@@ -11,6 +11,6 @@ settimeofday - settimeofday i:PP __settimeofday settimeofday
signal - signal i:ii signal
stime - stime i:p stime
time - time Ei:P time
-times - times i:p __times times
+times - times Ei:p __times times
ulimit - ulimit i:ii ulimit
utime - utime i:sP utime