about summary refs log tree commit diff
path: root/sysdeps/powerpc/powerpc32
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
committerJakub Jelinek <jakub@redhat.com>2007-07-12 18:26:36 +0000
commit0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch)
tree2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /sysdeps/powerpc/powerpc32
parent7d58530341304d403a6626d7f7a1913165fe2f32 (diff)
downloadglibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz
glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip
2.5-18.1
Diffstat (limited to 'sysdeps/powerpc/powerpc32')
-rw-r--r--sysdeps/powerpc/powerpc32/Dist9
-rw-r--r--sysdeps/powerpc/powerpc32/Implies1
-rw-r--r--sysdeps/powerpc/powerpc32/Makefile2
-rw-r--r--sysdeps/powerpc/powerpc32/__longjmp-common.S14
-rw-r--r--sysdeps/powerpc/powerpc32/backtrace.c3
-rw-r--r--sysdeps/powerpc/powerpc32/bits/atomic.h15
-rw-r--r--sysdeps/powerpc/powerpc32/bsd-_setjmp.S8
-rw-r--r--sysdeps/powerpc/powerpc32/bsd-setjmp.S4
-rw-r--r--sysdeps/powerpc/powerpc32/configure62
-rw-r--r--sysdeps/powerpc/powerpc32/configure.in32
-rw-r--r--sysdeps/powerpc/powerpc32/dl-dtprocnum.h3
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.c5
-rw-r--r--sysdeps/powerpc/powerpc32/dl-machine.h305
-rw-r--r--sysdeps/powerpc/powerpc32/dl-start.S16
-rw-r--r--sysdeps/powerpc/powerpc32/dl-trampoline.S186
-rw-r--r--sysdeps/powerpc/powerpc32/elf/start.S12
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/Dist2
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S29
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fprrest.S7
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/fprsave.S25
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_ceil.S65
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_ceilf.S61
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_copysign.S22
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_copysignl.S50
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_fabs.S5
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_fabsl.S36
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_fdim.c5
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_floor.S45
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_floorf.S41
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_fmax.S5
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_fmin.S5
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_isnan.c7
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_llrint.c8
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lrint.S14
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_lround.S59
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_rint.S49
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_rintf.S46
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_round.S73
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_roundf.S69
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_trunc.S64
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/s_truncf.S60
-rw-r--r--sysdeps/powerpc/powerpc32/fpu/setjmp-common.S50
-rw-r--r--sysdeps/powerpc/powerpc32/gprrest0.S7
-rw-r--r--sysdeps/powerpc/powerpc32/gprrest1.S7
-rw-r--r--sysdeps/powerpc/powerpc32/gprsave0.S26
-rw-r--r--sysdeps/powerpc/powerpc32/gprsave1.S7
-rw-r--r--sysdeps/powerpc/powerpc32/hp-timing.h82
-rw-r--r--sysdeps/powerpc/powerpc32/lshift.S10
-rw-r--r--sysdeps/powerpc/powerpc32/memset.S97
-rw-r--r--sysdeps/powerpc/powerpc32/ppc-mcount.S28
-rw-r--r--sysdeps/powerpc/powerpc32/register-dump.h4
-rw-r--r--sysdeps/powerpc/powerpc32/setjmp-common.S23
-rw-r--r--sysdeps/powerpc/powerpc32/strncmp.S17
-rw-r--r--sysdeps/powerpc/powerpc32/sysdep.h40
54 files changed, 1195 insertions, 732 deletions
diff --git a/sysdeps/powerpc/powerpc32/Dist b/sysdeps/powerpc/powerpc32/Dist
deleted file mode 100644
index ada834f7c3..0000000000
--- a/sysdeps/powerpc/powerpc32/Dist
+++ /dev/null
@@ -1,9 +0,0 @@
-dl-machine.c
-dl-start.S
-libgcc-compat.S
-ppc-mcount.S
-gprsave1.S
-gprsave0.S
-gprrest1.S
-gprrest0.S
-bp-asm.h
diff --git a/sysdeps/powerpc/powerpc32/Implies b/sysdeps/powerpc/powerpc32/Implies
index 9ef3ac175b..39a34c5f57 100644
--- a/sysdeps/powerpc/powerpc32/Implies
+++ b/sysdeps/powerpc/powerpc32/Implies
@@ -1,2 +1 @@
 wordsize-32
-powerpc/soft-fp
diff --git a/sysdeps/powerpc/powerpc32/Makefile b/sysdeps/powerpc/powerpc32/Makefile
index 82b4fc95f9..1d58a063d6 100644
--- a/sysdeps/powerpc/powerpc32/Makefile
+++ b/sysdeps/powerpc/powerpc32/Makefile
@@ -21,7 +21,7 @@ ifeq ($(subdir),csu)
 ifneq ($(elf),no)
 # The initfini generation code doesn't work in the presence of -fPIC, so
 # we use -fpic instead which is much better.
-CFLAGS-initfini.s = -g0 -fpic -O1
+CFLAGS-initfini.s += -fpic -O1
 
 # There is no benefit to using sdata for these objects, and the user
 # of the library should be able to control what goes into sdata.
diff --git a/sysdeps/powerpc/powerpc32/__longjmp-common.S b/sysdeps/powerpc/powerpc32/__longjmp-common.S
index 82531ad6b3..2093b7e337 100644
--- a/sysdeps/powerpc/powerpc32/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/__longjmp-common.S
@@ -1,5 +1,6 @@
 /* longjmp for PowerPC.
-   Copyright (C) 1995-1997,1999-2001,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997, 1999-2001, 2003, 2004, 2005, 2006
+	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
@@ -19,11 +20,10 @@
 
 #include <sysdep.h>
 #define _ASM
-#define _SETJMP_H
 #ifdef __NO_VMX__
 # include <novmxsetjmp.h>
 #else
-# include <bits/setjmp.h>
+# include <jmpbuf-offsets.h>
 #endif
 #include <bp-sym.h>
 #include <bp-asm.h>
@@ -31,7 +31,11 @@
 ENTRY (BP_SYM (__longjmp))
 	CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
 
+#ifdef PTR_DEMANGLE
+	lwz r24,(JB_GPR1*4)(r3)
+#else
 	lwz r1,(JB_GPR1*4)(r3)
+#endif
 	lwz r0,(JB_LR*4)(r3)
 	lwz r14,((JB_GPRS+0)*4)(r3)
 	lwz r15,((JB_GPRS+1)*4)(r3)
@@ -40,6 +44,10 @@ ENTRY (BP_SYM (__longjmp))
 	lwz r18,((JB_GPRS+4)*4)(r3)
 	lwz r19,((JB_GPRS+5)*4)(r3)
 	lwz r20,((JB_GPRS+6)*4)(r3)
+#ifdef PTR_DEMANGLE
+	PTR_DEMANGLE3 (r1, r24, r25)
+	PTR_DEMANGLE2 (r0, r25)
+#endif
 	mtlr r0
 	lwz r21,((JB_GPRS+7)*4)(r3)
 	lwz r22,((JB_GPRS+8)*4)(r3)
diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c
index 118f0d6175..e7e12544c5 100644
--- a/sysdeps/powerpc/powerpc32/backtrace.c
+++ b/sysdeps/powerpc/powerpc32/backtrace.c
@@ -1,5 +1,5 @@
 /* Return backtrace of current program state.
-   Copyright (C) 1998, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2000, 2005 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
@@ -64,3 +64,4 @@ __backtrace (void **array, int size)
   return count;
 }
 weak_alias (__backtrace, backtrace)
+libc_hidden_def (__backtrace)
diff --git a/sysdeps/powerpc/powerpc32/bits/atomic.h b/sysdeps/powerpc/powerpc32/bits/atomic.h
index 0f1a72335f..6fcc669fb1 100644
--- a/sysdeps/powerpc/powerpc32/bits/atomic.h
+++ b/sysdeps/powerpc/powerpc32/bits/atomic.h
@@ -89,12 +89,27 @@
 # define __arch_atomic_decrement_if_positive_64(mem) \
     ({ abort (); (*mem)--; })
 
+#ifdef _ARCH_PWR4
+/*
+ * Newer powerpc64 processors support the new "light weight" sync (lwsync)
+ * So if the build is using -mcpu=[power4,power5,power5+,970] we can
+ * safely use lwsync.
+ */
+# define atomic_read_barrier()	__asm ("lwsync" ::: "memory")
+/*
+ * "light weight" sync can also be used for the release barrier.
+ */
+# ifndef UP
+#  define __ARCH_REL_INSTR	"lwsync"
+# endif
+#else
 /*
  * Older powerpc32 processors don't support the new "light weight"
  * sync (lwsync).  So the only safe option is to use normal sync
  * for all powerpc32 applications.
  */
 # define atomic_read_barrier()	__asm ("sync" ::: "memory")
+#endif
 
 /*
  * Include the rest of the atomic ops macros which are common to both
diff --git a/sysdeps/powerpc/powerpc32/bsd-_setjmp.S b/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
index 50deda8c90..4c28c2e547 100644
--- a/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
+++ b/sysdeps/powerpc/powerpc32/bsd-_setjmp.S
@@ -26,7 +26,7 @@
 /* Build a non-versioned object for rtld-*.  */
 ENTRY (BP_SYM (_setjmp))
 	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET(BP_SYM (__sigsetjmp))
+	b BP_SYM (__sigsetjmp@local)
 END (BP_SYM (_setjmp))
 libc_hidden_def (_setjmp)
 #else
@@ -37,7 +37,7 @@ symbol_version (__novmx_setjmp,_setjmp,GLIBC_2.0);
 
 ENTRY (BP_SYM (__novmx_setjmp))
 	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET(BP_SYM (__novmx__sigsetjmp))
+	b BP_SYM (__novmx__sigsetjmp@local)
 END (BP_SYM (__novmx_setjmp))
 libc_hidden_def (__novmx_setjmp)
 # endif /* defined SHARED  && SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) */
@@ -48,12 +48,12 @@ default_symbol_version (__vmx_setjmp,_setjmp,GLIBC_2.3.4)
    if HAVE_CLEANUP_JMP_BUF is defined */
 ENTRY (BP_SYM (__GI__setjmp))
 	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET(BP_SYM (__vmx__sigsetjmp))
+	b BP_SYM (__vmx__sigsetjmp@local)
 END (BP_SYM (__GI__setjmp))
 
 ENTRY (BP_SYM (__vmx_setjmp))
 	li r4,0			/* Set second argument to 0.  */
-	b JUMPTARGET(BP_SYM (__vmx__sigsetjmp))
+	b BP_SYM (__vmx__sigsetjmp@local)
 END (BP_SYM (__vmx_setjmp))
 libc_hidden_def (__vmx_setjmp)
 #endif /* !NOT_IN_libc */
diff --git a/sysdeps/powerpc/powerpc32/bsd-setjmp.S b/sysdeps/powerpc/powerpc32/bsd-setjmp.S
index 159b122ca5..01b195d832 100644
--- a/sysdeps/powerpc/powerpc32/bsd-setjmp.S
+++ b/sysdeps/powerpc/powerpc32/bsd-setjmp.S
@@ -25,7 +25,7 @@
 
 ENTRY (__novmxsetjmp)
 	li r4,1			/* Set second argument to 1.  */
-	b JUMPTARGET (__novmx__sigsetjmp)
+	b __novmx__sigsetjmp@local
 END (__novmxsetjmp)
 strong_alias (__novmxsetjmp, __novmx__setjmp)
 symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0)
@@ -34,7 +34,7 @@ symbol_version (__novmxsetjmp, setjmp, GLIBC_2.0)
 
 ENTRY (__vmxsetjmp)
 	li r4,1			/* Set second argument to 1.  */
-	b JUMPTARGET (__vmx__sigsetjmp)
+	b __vmx__sigsetjmp@local
 END (__vmxsetjmp)
 strong_alias (__vmxsetjmp, __vmx__setjmp)
 strong_alias (__vmx__setjmp, __setjmp)
diff --git a/sysdeps/powerpc/powerpc32/configure b/sysdeps/powerpc/powerpc32/configure
new file mode 100644
index 0000000000..0ff56c936a
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/configure
@@ -0,0 +1,62 @@
+# This file is generated from configure.in by Autoconf.  DO NOT EDIT!
+ # Local configure fragment for sysdeps/powerpc/powerpc32.
+
+# See whether gas has R_PPC_REL16 relocs.
+echo "$as_me:$LINENO: checking for R_PPC_REL16 gas support" >&5
+echo $ECHO_N "checking for R_PPC_REL16 gas support... $ECHO_C" >&6
+if test "${libc_cv_ppc_rel16+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat > conftest.s <<\EOF
+	.text
+	addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha
+EOF
+if { ac_try='${CC-cc} -c $CFLAGS conftest.s 1>&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  libc_cv_ppc_rel16=yes
+else
+  libc_cv_ppc_rel16=no
+fi
+rm -f conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ppc_rel16" >&5
+echo "${ECHO_T}$libc_cv_ppc_rel16" >&6
+if test $libc_cv_ppc_rel16 = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_ASM_PPC_REL16 1
+_ACEOF
+
+fi
+
+# See whether GCC uses -msecure-plt.
+echo "$as_me:$LINENO: checking for -msecure-plt by default" >&5
+echo $ECHO_N "checking for -msecure-plt by default... $ECHO_C" >&6
+if test "${libc_cv_ppc_secure_plt+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  echo 'int foo (void) { extern int bar; return bar; }' > conftest.c
+libc_cv_ppc_secure_plt=no
+if { ac_try='${CC-cc} -S $CFLAGS conftest.c -fpic -o conftest.s 1>&5'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  if grep '_GLOBAL_OFFSET_TABLE_-.*@ha' conftest.s > /dev/null 2>&1; then
+    libc_cv_ppc_secure_plt=yes
+  fi
+fi
+rm -rf conftest*
+fi
+echo "$as_me:$LINENO: result: $libc_cv_ppc_secure_plt" >&5
+echo "${ECHO_T}$libc_cv_ppc_secure_plt" >&6
+if test $libc_cv_ppc_secure_plt = yes; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_PPC_SECURE_PLT 1
+_ACEOF
+
+fi
diff --git a/sysdeps/powerpc/powerpc32/configure.in b/sysdeps/powerpc/powerpc32/configure.in
new file mode 100644
index 0000000000..7219ad993e
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/configure.in
@@ -0,0 +1,32 @@
+GLIBC_PROVIDES dnl See aclocal.m4 in the top level source directory.
+# Local configure fragment for sysdeps/powerpc/powerpc32.
+
+# See whether gas has R_PPC_REL16 relocs.
+AC_CACHE_CHECK(for R_PPC_REL16 gas support, libc_cv_ppc_rel16, [dnl
+cat > conftest.s <<\EOF
+	.text
+	addis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha
+EOF
+if AC_TRY_COMMAND(${CC-cc} -c $CFLAGS conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  libc_cv_ppc_rel16=yes
+else
+  libc_cv_ppc_rel16=no
+fi
+rm -f conftest*])
+if test $libc_cv_ppc_rel16 = yes; then
+  AC_DEFINE(HAVE_ASM_PPC_REL16)
+fi
+
+# See whether GCC uses -msecure-plt.
+AC_CACHE_CHECK(for -msecure-plt by default, libc_cv_ppc_secure_plt, [dnl
+echo 'int foo (void) { extern int bar; return bar; }' > conftest.c
+libc_cv_ppc_secure_plt=no
+if AC_TRY_COMMAND(${CC-cc} -S $CFLAGS conftest.c -fpic -o conftest.s 1>&AS_MESSAGE_LOG_FD); then
+  if grep '_GLOBAL_OFFSET_TABLE_-.*@ha' conftest.s > /dev/null 2>&1; then
+    libc_cv_ppc_secure_plt=yes
+  fi
+fi
+rm -rf conftest*])
+if test $libc_cv_ppc_secure_plt = yes; then
+  AC_DEFINE(HAVE_PPC_SECURE_PLT)
+fi
diff --git a/sysdeps/powerpc/powerpc32/dl-dtprocnum.h b/sysdeps/powerpc/powerpc32/dl-dtprocnum.h
new file mode 100644
index 0000000000..7fe2be7939
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/dl-dtprocnum.h
@@ -0,0 +1,3 @@
+/* Number of extra dynamic section entries for this architecture.  By
+   default there are none.  */
+#define DT_THISPROCNUM	DT_PPC_NUM
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.c b/sysdeps/powerpc/powerpc32/dl-machine.c
index 06960716b9..4120a02382 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.c
+++ b/sysdeps/powerpc/powerpc32/dl-machine.c
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation functions.  PowerPC version.
-   Copyright (C) 1995-2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2003, 2004, 2005 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
@@ -242,7 +242,8 @@ __elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 					 : _dl_runtime_resolve);
 	  Elf32_Word offset;
 
-	  if (profile && _dl_name_match_p (GLRO(dl_profile), map))
+	  if (profile && GLRO(dl_profile) != NULL
+	      && _dl_name_match_p (GLRO(dl_profile), map))
 	    /* This is the object we are looking for.  Say that we really
 	       want profiling and the timers are started.  */
 	    GL(dl_profile_map) = map;
diff --git a/sysdeps/powerpc/powerpc32/dl-machine.h b/sysdeps/powerpc/powerpc32/dl-machine.h
index a8c1e3e490..496fa71ecc 100644
--- a/sysdeps/powerpc/powerpc32/dl-machine.h
+++ b/sysdeps/powerpc/powerpc32/dl-machine.h
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF dynamic relocation inline functions.  PowerPC version.
-   Copyright (C) 1995-2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1995-2002, 2003, 2005 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
@@ -25,6 +25,10 @@
 #include <assert.h>
 #include <dl-tls.h>
 
+/* Translate a processor specific dynamic tag to the index
+   in l_info array.  */
+#define DT_PPC(x) (DT_PPC_##x - DT_LOPROC + DT_NUM)
+
 /* Return nonzero iff ELF header is compatible with the running host.  */
 static inline int
 elf_machine_matches_host (const Elf32_Ehdr *ehdr)
@@ -32,24 +36,38 @@ elf_machine_matches_host (const Elf32_Ehdr *ehdr)
   return ehdr->e_machine == EM_PPC;
 }
 
+/* Return the value of the GOT pointer.  */
+static inline Elf32_Addr * __attribute__ ((const))
+ppc_got (void)
+{
+  Elf32_Addr *got;
+#ifdef HAVE_ASM_PPC_REL16
+  asm ("bcl 20,31,1f\n"
+       "1:	mflr %0\n"
+       "	addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+       "	addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+       : "=b" (got) : : "lr");
+#else
+  asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
+       : "=l" (got));
+#endif
+  return got;
+}
 
 /* Return the link-time address of _DYNAMIC, stored as
    the first value in the GOT. */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
 elf_machine_dynamic (void)
 {
-  Elf32_Addr *got;
-  asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
-       : "=l"(got));
-  return *got;
+  return *ppc_got ();
 }
 
 /* Return the run-time load address of the shared object.  */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
 elf_machine_load_address (void)
 {
-  unsigned int *got;
-  unsigned int *branchaddr;
+  Elf32_Addr *branchaddr;
+  Elf32_Addr runtime_dynamic;
 
   /* This is much harder than you'd expect.  Possibly I'm missing something.
      The 'obvious' way:
@@ -80,19 +98,17 @@ elf_machine_load_address (void)
      the address ourselves. That gives us the following code: */
 
   /* Get address of the 'b _DYNAMIC@local'...  */
-  asm ("bl 0f ;"
+  asm ("bcl 20,31,0f;"
        "b _DYNAMIC@local;"
        "0:"
-       : "=l"(branchaddr));
-
-  /* ... and the address of the GOT.  */
-  asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
-       : "=l"(got));
+       : "=l" (branchaddr));
 
   /* So now work out the difference between where the branch actually points,
      and the offset of that location in memory from the start of the file.  */
-  return ((Elf32_Addr)branchaddr - *got
-	  + ((int)(*branchaddr << 6 & 0xffffff00) >> 6));
+  runtime_dynamic = ((Elf32_Addr) branchaddr
+		     + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6));
+
+  return runtime_dynamic - elf_machine_dynamic ();
 }
 
 #define ELF_MACHINE_BEFORE_RTLD_RELOC(dynamic_info) /* nothing */
@@ -100,160 +116,6 @@ elf_machine_load_address (void)
 /* The PLT uses Elf32_Rela relocs.  */
 #define elf_machine_relplt elf_machine_rela
 
-/* This code is used in dl-runtime.c to call the `fixup' function
-   and then redirect to the address it returns.  It is called
-   from code built in the PLT by elf_machine_runtime_setup.  */
-#if !defined PROF
-#define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\
-	.section \".text\"	\n\
-	.align 2	\n\
-	.globl _dl_runtime_resolve	\n\
-	.type _dl_runtime_resolve,@function	\n\
-_dl_runtime_resolve:	\n\
- # We need to save the registers used to pass parameters, and register 0,\n\
- # which is used by _mcount; the registers are saved in a stack frame.\n\
-	stwu 1,-64(1)	\n\
-	stw 0,12(1)	\n\
-	stw 3,16(1)	\n\
-	stw 4,20(1)	\n\
- # The code that calls this has put parameters for `fixup' in r12 and r11.\n\
-	mr 3,12	\n\
-	stw 5,24(1)	\n\
-	mr 4,11	\n\
-	stw 6,28(1)	\n\
-	mflr 0	\n\
- # We also need to save some of the condition register fields.\n\
-	stw 7,32(1)	\n\
-	stw 0,48(1)	\n\
-	stw 8,36(1)	\n\
-	mfcr 0	\n\
-	stw 9,40(1)	\n\
-	stw 10,44(1)	\n\
-	stw 0,8(1)	\n\
-	bl fixup@local	\n\
- # 'fixup' returns the address we want to branch to.\n\
-	mtctr 3	\n\
- # Put the registers back...\n\
-	lwz 0,48(1)	\n\
-	lwz 10,44(1)	\n\
-	lwz 9,40(1)	\n\
-	mtlr 0	\n\
-	lwz 8,36(1)	\n\
-	lwz 0,8(1)	\n\
-	lwz 7,32(1)	\n\
-	lwz 6,28(1)	\n\
-	mtcrf 0xFF,0	\n\
-	lwz 5,24(1)	\n\
-	lwz 4,20(1)	\n\
-	lwz 3,16(1)	\n\
-	lwz 0,12(1)	\n\
- # ...unwind the stack frame, and jump to the PLT entry we updated.\n\
-	addi 1,1,64	\n\
-	bctr	\n\
-	.size	 _dl_runtime_resolve,.-_dl_runtime_resolve	\n\
-	\n\
-	.align 2	\n\
-	.globl _dl_prof_resolve	\n\
-	.type _dl_prof_resolve,@function	\n\
-_dl_prof_resolve:	\n\
- # We need to save the registers used to pass parameters, and register 0,\n\
- # which is used by _mcount; the registers are saved in a stack frame.\n\
-	stwu 1,-64(1)	\n\
-        stw 0,12(1)	\n\
-	stw 3,16(1)	\n\
-	stw 4,20(1)	\n\
- # The code that calls this has put parameters for `fixup' in r12 and r11.\n\
-	mr 3,12	\n\
-	stw 5,24(1)	\n\
-	mr 4,11	\n\
-	stw 6,28(1)	\n\
-	mflr 5	\n\
- # We also need to save some of the condition register fields.\n\
-	stw 7,32(1)	\n\
-	stw 5,48(1)	\n\
-	stw 8,36(1)	\n\
-	mfcr 0	\n\
-	stw 9,40(1)	\n\
-	stw 10,44(1)	\n\
-	stw 0,8(1)	\n\
-	bl profile_fixup@local	\n\
- # 'fixup' returns the address we want to branch to.\n\
-	mtctr 3	\n\
- # Put the registers back...\n\
-	lwz 0,48(1)	\n\
-	lwz 10,44(1)	\n\
-	lwz 9,40(1)	\n\
-	mtlr 0	\n\
-	lwz 8,36(1)	\n\
-	lwz 0,8(1)	\n\
-	lwz 7,32(1)	\n\
-	lwz 6,28(1)	\n\
-	mtcrf 0xFF,0	\n\
-	lwz 5,24(1)	\n\
-	lwz 4,20(1)	\n\
-	lwz 3,16(1)	\n\
-        lwz 0,12(1)	\n\
- # ...unwind the stack frame, and jump to the PLT entry we updated.\n\
-	addi 1,1,64	\n\
-	bctr	\n\
-	.size	 _dl_prof_resolve,.-_dl_prof_resolve	\n\
- # Undo '.section text'.\n\
-	.previous	\n\
-");
-#else
-# define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\n\
-	.section \".text\"	\n\
-	.align 2	\n\
-	.globl _dl_runtime_resolve	\n\
-	.globl _dl_prof_resolve	\n\
-	.type _dl_runtime_resolve,@function	\n\
-	.type _dl_prof_resolve,@function	\n\
-_dl_runtime_resolve:	\n\
-_dl_prof_resolve:	\n\
- # We need to save the registers used to pass parameters, and register 0,\n\
- # which is used by _mcount; the registers are saved in a stack frame.\n\
-	stwu 1,-64(1)	\n\
-	stw 0,12(1)	\n\
-	stw 3,16(1)	\n\
-	stw 4,20(1)	\n\
- # The code that calls this has put parameters for `fixup' in r12 and r11.\n\
-	mr 3,12	\n\
-	stw 5,24(1)	\n\
-	mr 4,11	\n\
-	stw 6,28(1)	\n\
-	mflr 0	\n\
- # We also need to save some of the condition register fields.\n\
-	stw 7,32(1)	\n\
-	stw 0,48(1)	\n\
-	stw 8,36(1)	\n\
-	mfcr 0	\n\
-	stw 9,40(1)	\n\
-	stw 10,44(1)	\n\
-	stw 0,8(1)	\n\
-	bl fixup@local	\n\
- # 'fixup' returns the address we want to branch to.\n\
-	mtctr 3	\n\
- # Put the registers back...\n\
-	lwz 0,48(1)	\n\
-	lwz 10,44(1)	\n\
-	lwz 9,40(1)	\n\
-	mtlr 0	\n\
-	lwz 8,36(1)	\n\
-	lwz 0,8(1)	\n\
-	lwz 7,32(1)	\n\
-	lwz 6,28(1)	\n\
-	mtcrf 0xFF,0	\n\
-	lwz 5,24(1)	\n\
-	lwz 4,20(1)	\n\
-	lwz 3,16(1)	\n\
-	lwz 0,12(1)	\n\
- # ...unwind the stack frame, and jump to the PLT entry we updated.\n\
-	addi 1,1,64	\n\
-	bctr	\n\
-	.size	 _dl_runtime_resolve,.-_dl_runtime_resolve	\n\
-");
-#endif
-
 /* Mask identifying addresses reserved for the user program,
    where the dynamic linker should not map anything.  */
 #define ELF_MACHINE_USER_ADDRESS_MASK	0xf0000000UL
@@ -298,13 +160,69 @@ __elf_preferred_address(struct link_map *loader, size_t maplength,
 /* The PowerPC never uses REL relocations.  */
 #define ELF_MACHINE_NO_REL 1
 
-/* Set up the loaded object described by L so its unrelocated PLT
+/* Set up the loaded object described by MAP so its unrelocated PLT
    entries will jump to the on-demand fixup code in dl-runtime.c.
    Also install a small trampoline to be used by entries that have
    been relocated to an address too far away for a single branch.  */
 extern int __elf_machine_runtime_setup (struct link_map *map,
 					int lazy, int profile);
-#define elf_machine_runtime_setup __elf_machine_runtime_setup
+
+static inline int
+elf_machine_runtime_setup (struct link_map *map,
+			   int lazy, int profile)
+{
+  if (map->l_info[DT_JMPREL] == 0)
+    return lazy;
+
+  if (map->l_info[DT_PPC(GOT)] == 0)
+    /* Handle old style PLT.  */
+    return __elf_machine_runtime_setup (map, lazy, profile);
+
+  /* New style non-exec PLT consisting of an array of addresses.  */
+  map->l_info[DT_PPC(GOT)]->d_un.d_ptr += map->l_addr;
+  if (lazy)
+    {
+      Elf32_Addr *plt, *got, glink;
+      Elf32_Word num_plt_entries;
+      void (*dlrr) (void);
+      extern void _dl_runtime_resolve (void);
+      extern void _dl_prof_resolve (void);
+
+      if (__builtin_expect (!profile, 1))
+	dlrr = _dl_runtime_resolve;
+      else
+	{
+	  if (GLRO(dl_profile) != NULL
+	      &&_dl_name_match_p (GLRO(dl_profile), map))
+	    GL(dl_profile_map) = map;
+	  dlrr = _dl_prof_resolve;
+	}
+      got = (Elf32_Addr *) map->l_info[DT_PPC(GOT)]->d_un.d_ptr;
+      glink = got[1];
+      got[1] = (Elf32_Addr) dlrr;
+      got[2] = (Elf32_Addr) map;
+
+      /* Relocate everything in .plt by the load address offset.  */
+      plt = (Elf32_Addr *) D_PTR (map, l_info[DT_PLTGOT]);
+      num_plt_entries = (map->l_info[DT_PLTRELSZ]->d_un.d_val
+			 / sizeof (Elf32_Rela));
+
+      /* If a library is prelinked but we have to relocate anyway,
+	 we have to be able to undo the prelinking of .plt section.
+	 The prelinker saved us at got[1] address of .glink
+	 section's start.  */
+      if (glink)
+	{
+	  glink += map->l_addr;
+	  while (num_plt_entries-- != 0)
+	    *plt++ = glink, glink += 4;
+	}
+      else
+	while (num_plt_entries-- != 0)
+	  *plt++ += map->l_addr;
+    }
+  return lazy;
+}
 
 /* Change the PLT entry whose reloc is 'reloc' to call the actual routine.  */
 extern Elf32_Addr __elf_machine_fixup_plt (struct link_map *map,
@@ -317,7 +235,12 @@ elf_machine_fixup_plt (struct link_map *map, lookup_t t,
 		       const Elf32_Rela *reloc,
 		       Elf32_Addr *reloc_addr, Elf64_Addr finaladdr)
 {
-  return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr);
+  if (map->l_info[DT_PPC(GOT)] == 0)
+    /* Handle old style PLT.  */
+    return __elf_machine_fixup_plt (map, reloc, reloc_addr, finaladdr);
+
+  *reloc_addr = finaladdr;
+  return finaladdr;
 }
 
 /* Return the final value of a plt relocation.  */
@@ -328,9 +251,14 @@ elf_machine_plt_value (struct link_map *map, const Elf32_Rela *reloc,
   return value + reloc->r_addend;
 }
 
+
+/* Names of the architecture-specific auditing callback functions.  */
+#define ARCH_LA_PLTENTER ppc32_gnu_pltenter
+#define ARCH_LA_PLTEXIT ppc32_gnu_pltexit
+
 #endif /* dl_machine_h */
 
-#ifdef RESOLVE
+#ifdef RESOLVE_MAP
 
 /* Do the actual processing of a reloc, once its target address
    has been determined.  */
@@ -353,7 +281,7 @@ extern void _dl_reloc_overflow (struct link_map *map,
    LOADADDR is the load address of the object; INFO is an array indexed
    by DT_* of the .dynamic section info.  */
 
-inline void
+auto inline void __attribute__ ((always_inline))
 elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		  const Elf32_Sym *sym, const struct r_found_version *version,
 		  void *const reloc_addr_arg)
@@ -381,16 +309,8 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     value = map->l_addr;
   else
     {
-# if defined USE_TLS && !defined RTLD_BOOTSTRAP
       sym_map = RESOLVE_MAP (&sym, version, r_type);
-      value = sym == NULL ? 0 : sym_map->l_addr + sym->st_value;
-# else
-      value = RESOLVE (&sym, version, r_type);
-#  ifndef RTLD_BOOTSTRAP
-      if (sym != NULL)
-#  endif
-	value += sym->st_value;
-# endif
+      value = sym_map == NULL ? 0 : sym_map->l_addr + sym->st_value;
     }
   value += reloc->r_addend;
 #else
@@ -443,11 +363,16 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
       break;
 #endif /* USE_TLS etc. */
 
-#ifdef RESOLVE_CONFLICT_FIND_MAP
     case R_PPC_JMP_SLOT:
+#ifdef RESOLVE_CONFLICT_FIND_MAP
       RESOLVE_CONFLICT_FIND_MAP (map, reloc_addr);
-      /* FALLTHROUGH */
 #endif
+      if (map->l_info[DT_PPC(GOT)] != 0)
+	{
+	  *reloc_addr = value;
+	  break;
+	}
+      /* FALLTHROUGH */
 
     default:
       __process_machine_rela (map, reloc, sym_map, sym, refsym,
@@ -455,7 +380,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     }
 }
 
-static inline void
+auto inline void __attribute__ ((always_inline))
 elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
 			   void *const reloc_addr_arg)
 {
@@ -463,7 +388,7 @@ elf_machine_rela_relative (Elf32_Addr l_addr, const Elf32_Rela *reloc,
   *reloc_addr = l_addr + reloc->r_addend;
 }
 
-static inline void
+auto inline void __attribute__ ((always_inline))
 elf_machine_lazy_rel (struct link_map *map,
 		      Elf32_Addr l_addr, const Elf32_Rela *reloc)
 {
@@ -474,4 +399,4 @@ elf_machine_lazy_rel (struct link_map *map,
    DT_RELA table.  */
 #define ELF_MACHINE_PLTREL_OVERLAP 1
 
-#endif /* RESOLVE */
+#endif /* RESOLVE_MAP */
diff --git a/sysdeps/powerpc/powerpc32/dl-start.S b/sysdeps/powerpc/powerpc32/dl-start.S
index d72202d4a4..c77c4de198 100644
--- a/sysdeps/powerpc/powerpc32/dl-start.S
+++ b/sysdeps/powerpc/powerpc32/dl-start.S
@@ -1,5 +1,5 @@
 /* Machine-dependent ELF startup code.  PowerPC version.
-   Copyright (C) 1995-2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000, 2002, 2004, 2005, 2006 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
@@ -14,8 +14,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 
@@ -39,7 +39,7 @@ ENTRY(_start)
 	bl	_dl_start@local
 
 	/* FALLTHRU */
-ENTRY(_dl_start_user)
+_dl_start_user:
 /* Now, we do our main work of calling initialisation procedures.
    The ELF ABI doesn't say anything about parameters for these,
    so we just pass argc, argv, and the environment.
@@ -47,8 +47,15 @@ ENTRY(_dl_start_user)
    passed by value!).  */
 
 /*  Put our GOT pointer in r31, */
+#ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r31
+	addis	r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l
+#else
 	bl	_GLOBAL_OFFSET_TABLE_-4@local
 	mflr	r31
+#endif
 /*  the address of _start in r30, */
 	mr	r30,r3
 /*  &_dl_argc in 29, &_dl_argv in 27, and _dl_loaded in 28.  */
@@ -91,6 +98,7 @@ ENTRY(_dl_start_user)
    Take the opportunity to clear LR, so anyone who accidentally returns
    from _start gets SEGV.  Also clear the next few words of the stack.  */
 
+_dl_main_dispatch:
 	li	r31,0
 	stw	r31,0(r1)
 	mtlr	r31
diff --git a/sysdeps/powerpc/powerpc32/dl-trampoline.S b/sysdeps/powerpc/powerpc32/dl-trampoline.S
new file mode 100644
index 0000000000..6a158c3fff
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/dl-trampoline.S
@@ -0,0 +1,186 @@
+/* PLT trampolines.  PPC32 version.
+   Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+
+	.section ".text"
+	.align 2
+	.globl _dl_runtime_resolve
+	.type _dl_runtime_resolve,@function
+_dl_runtime_resolve:
+	cfi_startproc
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+	stwu r1,-64(r1)
+	cfi_adjust_cfa_offset (64)
+	stw r0,12(r1)
+	stw r3,16(r1)
+	stw r4,20(r1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+	mr r3,r12
+	stw r5,24(r1)
+	mr r4,r11
+	stw r6,28(r1)
+	mflr r0
+ # We also need to save some of the condition register fields
+	stw r7,32(r1)
+ # Don't clobber the caller's LRSAVE, it is needed by _mcount.
+	stw r0,48(r1)
+ 	cfi_offset (lr, -16)
+	stw r8,36(r1)
+	mfcr r0
+	stw r9,40(r1)
+	stw r10,44(r1)
+	stw r0,8(r1)
+	bl _dl_fixup@local
+ # 'fixup' returns the address we want to branch to.
+	mtctr r3
+ # Put the registers back...
+	lwz r0,48(r1)
+	lwz r10,44(r1)
+	lwz r9,40(r1)
+	mtlr r0
+	lwz r8,36(r1)
+	lwz r0,8(r1)
+	lwz r7,32(r1)
+	lwz r6,28(r1)
+	mtcrf 0xFF,r0
+	lwz r5,24(r1)
+	lwz r4,20(r1)
+	lwz r3,16(r1)
+	lwz r0,12(r1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+	addi r1,r1,64
+	bctr
+	cfi_endproc
+	.size	 _dl_runtime_resolve,.-_dl_runtime_resolve
+
+#ifndef PROF
+	.align 2
+	.globl _dl_prof_resolve
+	.type _dl_prof_resolve,@function
+_dl_prof_resolve:
+	cfi_startproc
+ # We need to save the registers used to pass parameters, and register 0,
+ # which is used by _mcount; the registers are saved in a stack frame.
+	stwu r1,-320(r1)
+	cfi_adjust_cfa_offset (320)
+	/* Stack layout:
+
+	  +312   stackframe
+	  +308   lr
+	  +304   r1
+	  +288   v12
+	  +272   v11
+	  +256   v10
+	  +240   v9
+	  +224   v8
+	  +208   v7
+	  +192   v6
+	  +176   v5
+	  +160   v4
+	  +144   v3
+	  +128   v2
+	  +112   v1
+	  +104   fp8
+	  +96    fp7
+	  +88    fp6
+	  +80    fp5
+	  +72    fp4
+	  +64    fp3
+	  +56    fp2
+	  +48    fp1
+	  +44    r10
+	  +40    r9
+	  +36    r8
+	  +32    r7
+	  +28    r6
+	  +24    r5
+	  +20    r4
+	  +16    r3
+	  +12    r0
+	  +8     cr
+	   r1    link
+	*/
+        stw r0,12(r1)
+	stw r3,16(r1)
+	stw r4,20(r1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+	mr r3,r12
+	stw r5,24(r1)
+	mr r4,r11
+	stw r6,28(r1)
+	mflr r5
+ # We also need to save some of the condition register fields.
+	stw r7,32(r1)
+ # Don't clobber the caller's LRSAVE, it is needed by _mcount.
+	stw r5,308(r1)
+	cfi_offset (lr, -12)
+	stw r8,36(r1)
+	mfcr r0
+	stw r9,40(r1)
+	stw r10,44(r1)
+	stw r0,8(r1)
+ # Save the floating point registers
+	stfd fp1,48(r1)
+	stfd fp2,56(r1)
+	stfd fp3,64(r1)
+	stfd fp4,72(r1)
+	stfd fp5,80(r1)
+	stfd fp6,88(r1)
+	stfd fp7,96(r1)
+	stfd fp8,104(r1)
+ # XXX TODO: store vmx registers
+ # Load the extra parameters.
+	addi r6,r1,16
+	addi r7,r1,312
+	li r0,-1
+	stw r0,0(r7)
+	bl _dl_profile_fixup@local
+ # 'fixup' returns the address we want to branch to.
+	mtctr r3
+ # Put the registers back...
+	lwz r0,308(r1)
+	lwz r10,44(r1)
+	lwz r9,40(r1)
+	mtlr r0
+	lwz r8,36(r1)
+	lwz r0,8(r1)
+	lwz r7,32(r1)
+	lwz r6,28(r1)
+	mtcrf 0xFF,r0
+	lwz r5,24(r1)
+	lwz r4,20(r1)
+	lwz r3,16(r1)
+        lwz r0,12(r1)
+ # Load the floating point registers.
+	lfd fp1,48(r1)
+	lfd fp2,56(r1)
+	lfd fp3,64(r1)
+	lfd fp4,72(r1)
+	lfd fp5,80(r1)
+	lfd fp6,88(r1)
+	lfd fp7,96(r1)
+	lfd fp8,104(r1)
+ # ...unwind the stack frame, and jump to the PLT entry we updated.
+	addi r1,r1,320
+	bctr
+	cfi_endproc
+	.size	 _dl_prof_resolve,.-_dl_prof_resolve
+#endif
diff --git a/sysdeps/powerpc/powerpc32/elf/start.S b/sysdeps/powerpc/powerpc32/elf/start.S
index 7827357a6c..bafd2ae001 100644
--- a/sysdeps/powerpc/powerpc32/elf/start.S
+++ b/sysdeps/powerpc/powerpc32/elf/start.S
@@ -52,7 +52,7 @@ L(start_addresses):
 	ASM_SIZE_DIRECTIVE(L(start_addresses))
 
 	.section ".text"
-#ifdef PIC
+#if defined PIC && !defined HAVE_ASM_PPC_REL16
 L(start_addressesp):
 	.long	L(start_addresses)-L(branch)
 #endif
@@ -73,11 +73,19 @@ L(branch):
 	mtlr	r0
 	stw	r0,0(r1)
  /* Set r13 to point at the 'small data area', and put the address of
-    start_addresses in r8...  */
+    start_addresses in r8.  Also load the GOT pointer so that new PLT
+    calls work, like the one to __libc_start_main.  */
 #ifdef PIC
+# ifdef HAVE_ASM_PPC_REL16
+	addis	r30,r13,_GLOBAL_OFFSET_TABLE_-L(branch)@ha
+	addis	r8,r13,L(start_addresses)-L(branch)@ha
+	addi	r30,r30,_GLOBAL_OFFSET_TABLE_-L(branch)@l
+	lwzu	r13,L(start_addresses)-L(branch)@l(r8)
+# else
 	lwz	r8,L(start_addressesp)-L(branch)(r13)
 	add	r8,r13,r8
 	lwz	r13,0(r8)
+# endif
 #else
 	lis	r8,L(start_addresses)@ha
 	lwzu	r13,L(start_addresses)@l(r8)
diff --git a/sysdeps/powerpc/powerpc32/fpu/Dist b/sysdeps/powerpc/powerpc32/fpu/Dist
deleted file mode 100644
index 375e57172e..0000000000
--- a/sysdeps/powerpc/powerpc32/fpu/Dist
+++ /dev/null
@@ -1,2 +0,0 @@
-fprrest.S
-fprsave.S
diff --git a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
index a2415b9542..404f403855 100644
--- a/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/fpu/__longjmp-common.S
@@ -1,5 +1,5 @@
 /* longjmp for PowerPC.
-   Copyright (C) 1995-99, 2000, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-99, 2000, 2003-2005, 2006 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
@@ -14,16 +14,15 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 #define _ASM
-#define _SETJMP_H
 #ifdef __NO_VMX__
 # include <novmxsetjmp.h>
 #else
-# include <bits/setjmp.h>
+# include <jmpbuf-offsets.h>
 #endif
 #include <bp-sym.h>
 #include <bp-asm.h>
@@ -34,15 +33,25 @@ ENTRY (BP_SYM (__longjmp))
 #ifndef __NO_VMX__
 # ifdef PIC
 	mflr    r6
+	cfi_register (lr,r6)
+#  ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r5
+	addis	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+#  else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r5
+#  endif
 #  ifdef SHARED
 	lwz     r5,_rtld_global_ro@got(r5)
 	mtlr    r6
+	cfi_same_value (lr)
 	lwz     r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
 #  else
-	lwz     r5,_rtld_global_ro@got(r5)
+	lwz     r5,_dl_hwcap@got(r5)
 	mtlr    r6
+	cfi_same_value (lr)
 	lwz     r5,0(r5)
 #  endif
 # else
@@ -105,7 +114,11 @@ aligned_restore_vmx:
 	lvx	v31,0,r6
 L(no_vmx):
 #endif
+#ifdef PTR_DEMANGLE
+	lwz r24,(JB_GPR1*4)(r3)
+#else
 	lwz r1,(JB_GPR1*4)(r3)
+#endif
 	lwz r0,(JB_LR*4)(r3)
 	lwz r14,((JB_GPRS+0)*4)(r3)
 	lfd fp14,((JB_FPRS+0*2)*4)(r3)
@@ -121,6 +134,10 @@ L(no_vmx):
 	lfd fp19,((JB_FPRS+5*2)*4)(r3)
 	lwz r20,((JB_GPRS+6)*4)(r3)
 	lfd fp20,((JB_FPRS+6*2)*4)(r3)
+#ifdef PTR_DEMANGLE
+	PTR_DEMANGLE3 (r1, r24, r25)
+	PTR_DEMANGLE2 (r0, r25)
+#endif
 	mtlr r0
 	lwz r21,((JB_GPRS+7)*4)(r3)
 	lfd fp21,((JB_FPRS+7*2)*4)(r3)
diff --git a/sysdeps/powerpc/powerpc32/fpu/fprrest.S b/sysdeps/powerpc/powerpc32/fpu/fprrest.S
index 42317809eb..2f6c6deb2e 100644
--- a/sysdeps/powerpc/powerpc32/fpu/fprrest.S
+++ b/sysdeps/powerpc/powerpc32/fpu/fprrest.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2006 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
@@ -13,8 +13,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /*
     Floating Point Registers (FPRs) restore routine
@@ -92,3 +92,4 @@ C_TEXT(_restfpr_29):	lwz	r0,8(r1)	#get return address from frame
 			lfd	fp30,-16(r1)	#restore f30
 			lfd	fp31,-8(r1)	#restore f31
 			blr			#return
+END (_restfpr_all)
diff --git a/sysdeps/powerpc/powerpc32/fpu/fprsave.S b/sysdeps/powerpc/powerpc32/fpu/fprsave.S
index d7bc1ab7dc..c05178775d 100644
--- a/sysdeps/powerpc/powerpc32/fpu/fprsave.S
+++ b/sysdeps/powerpc/powerpc32/fpu/fprsave.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2006 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
@@ -13,8 +13,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /*
     Floating Point Registers (FPRs) save routine
@@ -27,67 +27,86 @@ ENTRY(_savefpr_all)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_14)
 C_TEXT(_savef14):
 C_TEXT(_savefpr_14):	stfd	fp14,-144(r1)
+			cfi_offset(fp14,-144)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef15)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_15)
 C_TEXT(_savef15):
 C_TEXT(_savefpr_15):	stfd	fp15,-136(r1)
+			cfi_offset(fp15,-136)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef16)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_16)
 C_TEXT(_savef16):
 C_TEXT(_savefpr_16):	stfd	fp16,-128(r1)
+			cfi_offset(fp16,-128)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef17)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_17)
 C_TEXT(_savef17):
 C_TEXT(_savefpr_17):	stfd	fp17,-120(r1)
+			cfi_offset(fp17,-120)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef18)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_18)
 C_TEXT(_savef18):
 C_TEXT(_savefpr_18):	stfd	fp18,-112(r1)
+			cfi_offset(fp18,-112)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef19)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_19)
 C_TEXT(_savef19):
 C_TEXT(_savefpr_19):	stfd	fp19,-104(r1)
+			cfi_offset(fp19,-104)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef20)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_20)
 C_TEXT(_savef20):
 C_TEXT(_savefpr_20):	stfd	fp20,-96(r1)
+			cfi_offset(fp20,-96)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef21)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_21)
 C_TEXT(_savef21):
 C_TEXT(_savefpr_21):	stfd	fp21,-88(r1)
+			cfi_offset(fp21,-88)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef22)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_22)
 C_TEXT(_savef22):
 C_TEXT(_savefpr_22):	stfd	fp22,-80(r1)
+			cfi_offset(fp22,-80)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef23)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_23)
 C_TEXT(_savef23):
 C_TEXT(_savefpr_23):	stfd	fp23,-72(r1)
+			cfi_offset(fp23,-72)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef24)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_24)
 C_TEXT(_savef24):
 C_TEXT(_savefpr_24):	stfd	fp24,-64(r1)
+			cfi_offset(fp24,-64)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef25)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_25)
 C_TEXT(_savef25):
 C_TEXT(_savefpr_25):	stfd	fp25,-56(r1)
+			cfi_offset(fp25,-56)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef26)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_26)
 C_TEXT(_savef26):
 C_TEXT(_savefpr_26):	stfd	fp26,-48(r1)
+			cfi_offset(fp26,-48)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef27)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_27)
 C_TEXT(_savef27):
 C_TEXT(_savefpr_27):	stfd	fp27,-40(r1)
+			cfi_offset(fp27,-40)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef28)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_28)
 C_TEXT(_savef28):
 C_TEXT(_savefpr_28):	stfd	fp28,-32(r1)
+			cfi_offset(fp28,-32)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savef29)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savefpr_29)
 C_TEXT(_savef29):
 C_TEXT(_savefpr_29):	stfd	fp29,-24(r1)	#save f29
 			stfd	fp30,-16(r1)	#save f30
 			stfd	fp31,-8(r1)	#save f31
+			cfi_offset(fp29,-24)
+			cfi_offset(fp30,-16)
+			cfi_offset(fp31,-8)
 			stw	r0,8(r1)	#save LR in callers frame
 			blr			#return
+END (_savefpr_all)
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
index d211314bbf..bc74d302fb 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_ceil.S
@@ -1,5 +1,5 @@
 /* ceil function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,46 +14,39 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
+#include <math_ldbl_opt.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO52.0,@object
-	.size	TWO52.0,8
-TWO52.0:
-	.long 0x43300000
-	.long 0
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x80000000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**52 */
-	.long 0x43300000
-	.long 0
-.LC1:	/* -0.0 */
-	.long 0x80000000
-	.long 0
+	.long 0x59800000
 
 	.section	".text"
 ENTRY (__ceil)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsub	fp12,fp13,fp13	/* generate 0.0  */
@@ -64,27 +57,18 @@ ENTRY (__ceil)
 	ble-	cr6,.L4
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-.L9:	
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
 	blr
 .L4:
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
+.L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-#ifdef SHARED
-	mflr	r11
-	bl	_GLOBAL_OFFSET_TABLE_@local-4
-	mflr	r10
-	lwz	r9,.LC1@got(10)
-	mtlr	r11
-	lfd	fp1,0(r9)
-#else
-	lis	r9,.LC1@ha
-	lfd	fp1,.LC1@l(r9)
-#endif
 	blr
 	END (__ceil)
 
@@ -94,3 +78,6 @@ weak_alias (__ceil, ceil)
 weak_alias (__ceil, ceill)
 strong_alias (__ceil, __ceill)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __ceil, ceill, GLIBC_2_0)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
index 4439dc2338..47a75ec0c3 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_ceilf.S
@@ -1,5 +1,5 @@
 /* float ceil function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,46 +14,38 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO52.0,@object
-	.size	TWO52.0,8
-TWO52.0:
-	.long 0x43300000
-	.long 0
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x80000000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**23 */
-	.long 0x41600000
-	.long 0
-.LC1:	/* -0.0 */
-	.long 0x80000000
-	.long 0
+	.long 0x4b000000
 
 	.section	".text"
 ENTRY (__ceilf)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsubs	fp12,fp13,fp13	/* generate 0.0  */
@@ -64,27 +56,18 @@ ENTRY (__ceilf)
 	ble-	cr6,.L4
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
-.L9:	
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
 	blr
 .L4:
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
+.L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-#ifdef SHARED
-	mflr	r11
-	bl	_GLOBAL_OFFSET_TABLE_@local-4
-	mflr	r10
-	lwz	r9,.LC1@got(10)
-	mtlr	r11
-	lfd	fp1,0(r9)
-#else
-	lis	r9,.LC1@ha
-	lfd	fp1,.LC1@l(r9)
-#endif
 	blr
 	END (__ceilf)
 
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
index 933435da3d..dd68b0869c 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_copysign.S
@@ -1,5 +1,5 @@
 /* Copy a sign bit between floating-point values.
-   Copyright (C) 1997, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2000, 2006 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
@@ -14,23 +14,26 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /* This has been coded in assembler because GCC makes such a mess of it
    when it's coded in C.  */
 
 #include <sysdep.h>
+#include <math_ldbl_opt.h>
 
 ENTRY(__copysign)
 /* double [f1] copysign (double [f1] x, double [f2] y);
    copysign(x,y) returns a value with the magnitude of x and
    with the sign bit of y.  */
 	stwu	r1,-16(r1)
+	cfi_adjust_cfa_offset (16)
 	stfd	fp2,8(r1)
 	lwz	r3,8(r1)
 	cmpwi   r3,0
 	addi    r1,r1,16
+	cfi_adjust_cfa_offset (-16)
 	blt     L(0)
 	fabs    fp1,fp1
 	blr
@@ -38,13 +41,20 @@ L(0):	fnabs   fp1,fp1
 	blr
 	END (__copysign)
 
-weak_alias(__copysign,copysign)
+weak_alias (__copysign,copysign)
 
 /* It turns out that it's safe to use this code even for single-precision.  */
-weak_alias(__copysign,copysignf)
+weak_alias (__copysign,copysignf)
 strong_alias(__copysign,__copysignf)
 
 #ifdef NO_LONG_DOUBLE
-weak_alias(__copysign,copysignl)
+weak_alias (__copysign,copysignl)
 strong_alias(__copysign,__copysignl)
 #endif
+#ifdef IS_IN_libm
+# if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __copysign, copysignl, GLIBC_2_0)
+# endif
+#elif LONG_DOUBLE_COMPAT(libc, GLIBC_2_0)
+compat_symbol (libc, __copysign, copysignl, GLIBC_2_0)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S
new file mode 100644
index 0000000000..64b6a45437
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_copysignl.S
@@ -0,0 +1,50 @@
+/* Copy a sign bit between floating-point values.
+   IBM extended format long double version.
+   Copyright (C) 2006 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>
+
+ENTRY(__copysignl)
+/* long double [f1,f2] copysign (long double [f1,f2] x, long double [f3,f4] y);
+   copysign(x,y) returns a value with the magnitude of x and
+   with the sign bit of y.  */
+	stwu	r1,-16(r1)
+	cfi_adjust_cfa_offset (16)
+	stfd	fp3,8(r1)
+	fmr	fp0,fp1
+	fabs	fp1,fp1
+	fcmpu	cr7,fp0,fp1
+	lwz	r3,8(r1)
+	cmpwi	cr6,r3,0
+	addi	r1,r1,16
+	cfi_adjust_cfa_offset (-16)
+	beq	cr7,L(0)
+	fneg	fp2,fp2
+L(0):	bgelr	cr6
+	fneg	fp1,fp1
+	fneg	fp2,fp2
+	blr
+END (__copysignl)
+
+#ifdef IS_IN_libm
+long_double_symbol (libm, __copysignl, copysignl)
+#else
+long_double_symbol (libc, __copysignl, copysignl)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fabs.S b/sysdeps/powerpc/powerpc32/fpu/s_fabs.S
new file mode 100644
index 0000000000..53d21301ee
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_fabs.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fabs.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __fabs, fabsl, GLIBC_2_0)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S
new file mode 100644
index 0000000000..3655e5b2f3
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_fabsl.S
@@ -0,0 +1,36 @@
+/* Copy a sign bit between floating-point values.
+   IBM extended format long double version.
+   Copyright (C) 2004, 2006 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>
+
+ENTRY(__fabsl)
+/* long double [f1,f2] fabs (long double [f1,f2] x);
+   fabs(x,y) returns a value with the magnitude of x and
+   with the sign bit of y.  */
+	fmr	fp0,fp1
+	fabs	fp1,fp1
+	fcmpu	cr1,fp0,fp1
+	beqlr	cr1
+	fneg	fp2,fp2
+	blr
+END (__fabsl)
+
+long_double_symbol (libm, __fabsl, fabsl)
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fdim.c b/sysdeps/powerpc/powerpc32/fpu/s_fdim.c
new file mode 100644
index 0000000000..e34b51ee54
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_fdim.c
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fdim.c>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fdim, fdiml, GLIBC_2_1);
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floor.S b/sysdeps/powerpc/powerpc32/fpu/s_floor.S
index 143f907b18..a29e4791ea 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_floor.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_floor.S
@@ -1,5 +1,5 @@
 /* Floor function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,38 +14,39 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
+#include <math_ldbl_opt.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO52.0,@object
-	.size	TWO52.0,8
-TWO52.0:
-	.long 0x43300000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**52 */
-	.long 0x43300000
-	.long 0
+	.long 0x59800000
 
 	.section	".text"
 ENTRY (__floor)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsub	fp12,fp13,fp13	/* generate 0.0  */
@@ -56,15 +57,16 @@ ENTRY (__floor)
 	ble-	cr6,.L4
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-	fmr	fp1,fp12	/* x must be +0.0 for the 0.0 case.  */
 	blr
 .L4:
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
 .L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */	
 	blr
@@ -76,3 +78,6 @@ weak_alias (__floor, floor)
 weak_alias (__floor, floorl)
 strong_alias (__floor, __floorl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __floor, floorl, GLIBC_2_0)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
index 154bc30ff7..99fbdc5f86 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_floorf.S
@@ -1,5 +1,5 @@
 /* float Floor function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,38 +14,38 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO23.0,@object
-	.size	TWO23.0,8
-TWO23.0:
-	.long 0x41600000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**23 */
-	.long 0x41600000
-	.long 0
+	.long 0x4b000000
 
 	.section	".text"
 ENTRY (__floorf)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsubs	fp12,fp13,fp13	/* generate 0.0  */
@@ -56,15 +56,16 @@ ENTRY (__floorf)
 	ble-	cr6,.L4
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-	fmr	fp1,fp12	/* x must be +0.0 for the 0.0 case.  */
 	blr
 .L4:
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
 .L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */	
 	blr
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fmax.S b/sysdeps/powerpc/powerpc32/fpu/s_fmax.S
new file mode 100644
index 0000000000..69735761ab
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_fmax.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fmax.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmax, fmaxl, GLIBC_2_1)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_fmin.S b/sysdeps/powerpc/powerpc32/fpu/s_fmin.S
new file mode 100644
index 0000000000..6d4a0a946c
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_fmin.S
@@ -0,0 +1,5 @@
+#include <math_ldbl_opt.h>
+#include <sysdeps/powerpc/fpu/s_fmin.S>
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __fmin, fminl, GLIBC_2_1)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_isnan.c b/sysdeps/powerpc/powerpc32/fpu/s_isnan.c
new file mode 100644
index 0000000000..397717ba9c
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/fpu/s_isnan.c
@@ -0,0 +1,7 @@
+#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/fpu/s_llrint.c b/sysdeps/powerpc/powerpc32/fpu/s_llrint.c
index 7fdc296b0b..cb96be7c9b 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_llrint.c
+++ b/sysdeps/powerpc/powerpc32/fpu/s_llrint.c
@@ -1,5 +1,5 @@
 /* Round a double value to a long long in the current rounding mode.
-   Copyright (C) 1997 Free Software Foundation, Inc.
+   Copyright (C) 1997, 2006 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
@@ -17,7 +17,8 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include "math.h"
+#include <math.h>
+#include <math_ldbl_opt.h>
 
 long long int
 __llrint (double x)
@@ -29,3 +30,6 @@ weak_alias (__llrint, llrint)
 strong_alias (__llrint, __llrintl)
 weak_alias (__llrint, llrintl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __llrint, llrintl, GLIBC_2_1);
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
index 57d56c48cd..da0a1e505a 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_lrint.S
@@ -1,5 +1,5 @@
 /* Round double to long int.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -18,15 +18,18 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <math_ldbl_opt.h>
 
 /* long int[r3] __lrint (double x[fp1])  */
-ENTRY (__lrint)	
+ENTRY (__lrint)
+	stwu	r1,-16(r1)
 	fctiw	fp13,fp1
-	stfd	fp13,-8(r1)
+	stfd	fp13,8(r1)
 	nop	/* Insure the following load is in a different dispatch group */
 	nop	/* to avoid pipe stall on POWER4&5.  */
 	nop
-	lwz	r3,-4(r1)	
+	lwz	r3,12(r1)
+	addi	r1,r1,16
 	blr
 	END (__lrint)
 
@@ -39,3 +42,6 @@ weak_alias (__lrint, lrintf)
 strong_alias (__lrint, __lrintl)
 weak_alias (__lrint, lrintl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lrint, lrintl, GLIBC_2_1)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_lround.S b/sysdeps/powerpc/powerpc32/fpu/s_lround.S
index dcb97e373b..9c534ec2be 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_lround.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_lround.S
@@ -1,5 +1,5 @@
 /* lround function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,32 +14,18 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
-
-	.section	.rodata
-	.align 3
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x00000000
-	.long 0
-	.type	POINTFIVE.0,@object
-	.size	POINTFIVE.0,8
-POINTFIVE.0:
-	.long 0x3fe00000
-	.long 0
+#include <math_ldbl_opt.h>
 
 	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.align	2
 .LC0:	/* 0.0 */
 	.long 0x00000000
-	.long 0
 .LC1:	/* 0.5 */
-	.long 0x3fe00000
-	.long 0
+	.long 0x3f000000
 
 	.section	".text"
 	
@@ -54,41 +40,51 @@ POINTFIVE.0:
    to the integer value.  */
 
 ENTRY (__lround)
+	stwu    r1,-16(r1)
+	cfi_adjust_cfa_offset (16)
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	addi	r9,r9,.LC0-1b@l
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+# endif
 	mtlr	r11
-	lfd	fp12,0(r9)
+	cfi_same_value (lr)
+	lfs	fp12,0(r9)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp12,.LC0@l(r9)
+	lfs	fp12,.LC0@l(r9)
 #endif
 #ifdef SHARED
-	lwz	r9,.LC1@got(10)
-	lfd	fp10,0(r9)
+	lfs	fp10,.LC1-.LC0(r9)
 #else
 	lis	r9,.LC1@ha
-	lfd	fp10,.LC1@l(r9)
+	lfs	fp10,.LC1@l(r9)
 #endif
 	fcmpu	cr6,fp1,fp12	/* if (x > 0.0)  */
 	ble-	cr6,.L4
 	fadd	fp1,fp1,fp10	/* x+= 0.5;  */
 .L9:
 	fctiwz	fp2,fp1		/* Convert To Integer DW lround toward 0.  */
-	stfd	fp2,-8(r1)
-	nop	/* Insure the following load is in a different dispatch group */
-	nop	/* to avoid pipe stall on POWER4&5.  */
+	stfd	fp2,8(r1)
+	nop	/* Ensure the following load is in a different dispatch  */
+	nop	/* group to avoid pipe stall on POWER4&5.  */
 	nop
-	lwz	r3,-4(r1)
+	lwz	r3,12(r1)
+	addi	r1,r1,16
 	blr
 .L4:
 	fsub	fp1,fp1,fp10	/* x-= 0.5;  */
 	b	.L9
 	END (__lround)
 
-strong_alias (__lround, __lround)
 weak_alias (__lround, lround)
 
 strong_alias (__lround, __lroundf)
@@ -98,3 +94,6 @@ weak_alias (__lround, lroundf)
 weak_alias (__lround, lroundl)
 strong_alias (__lround, __lroundl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __lround, lroundl, GLIBC_2_1)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rint.S b/sysdeps/powerpc/powerpc32/fpu/s_rint.S
index dee25f204f..c8dca313ae 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_rint.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_rint.S
@@ -1,5 +1,5 @@
 /* Round to int floating-point values.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,40 +14,41 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /* This has been coded in assembler because GCC makes such a mess of it
    when it's coded in C.  */
 
 #include <sysdep.h>
+#include <math_ldbl_opt.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO52.0,@object
-	.size	TWO52.0,8
-TWO52.0:
-	.long 0x43300000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**52 */
-	.long 0x43300000
-	.long 0
+	.long 0x59800000
 
 	.section	".text"
 ENTRY (__rint)
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsub	fp12,fp13,fp13	/* generate 0.0  */
@@ -57,13 +58,14 @@ ENTRY (__rint)
 	bng-	cr6,.L4
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-	blr
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+	blr			/* x = 0.0; */
 .L4:
 	bnllr-	cr6		/* if (x < 0.0)  */
-	fsub	fp1,fp13,fp1	/* x = TWO52 - x;  */
-	fsub	fp0,fp1,fp13	/* x = - (x - TWO52);  */
-	fneg	fp1,fp0
-	blr
+	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
+	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+	blr			/* x = -0.0; */
 	END (__rint)
 
 weak_alias (__rint, rint)
@@ -72,3 +74,6 @@ weak_alias (__rint, rint)
 weak_alias (__rint, rintl)
 strong_alias (__rint, __rintl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_0)
+compat_symbol (libm, __rint, rintl, GLIBC_2_0)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
index cebf6423af..7771cb2bc8 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_rintf.S
@@ -1,5 +1,5 @@
 /* Round float to int floating-point values.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,38 +14,37 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 
-
-	.section	.rodata
-	.align 3
-	.type	TWO23.0,@object
-	.size	TWO23.0,8
-TWO23.0:
-	.long 0x41600000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**23 */
-	.long 0x41600000
-	.long 0
+	.long 0x4b000000
 
 	.section	".text"
 ENTRY (__rintf)
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsubs	fp12,fp13,fp13	/* generate 0.0  */
@@ -55,13 +54,14 @@ ENTRY (__rintf)
 	bng-	cr6,.L4
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
-	blr
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+	blr			/* x = 0.0; */
 .L4:
 	bnllr-	cr6		/* if (x < 0.0)  */
-	fsubs	fp1,fp13,fp1	/* x = TWO23 - x;  */
-	fsubs	fp0,fp1,fp13	/* x = - (x - TWO23);  */
-	fneg	fp1,fp0
-	blr
+	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
+	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+	blr			/* x = -0.0; */
 	END (__rintf)
 
 weak_alias (__rintf, rintf)
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_round.S b/sysdeps/powerpc/powerpc32/fpu/s_round.S
index 13fc74f001..590c87ad8c 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_round.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_round.S
@@ -1,5 +1,5 @@
 /* round function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,40 +14,18 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
-
-	.section	.rodata
-	.align 3
-	.type	TWO52.0,@object
-	.size	TWO52.0,8
-TWO52.0:
-	.long 0x43300000
-	.long 0
-	.type	POINTFIVE.0,@object
-	.size	POINTFIVE.0,8
-POINTFIVE.0:
-	.long 0x3fe00000
-	.long 0
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x80000000
-	.long 0
+#include <math_ldbl_opt.h>
 
 	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.align	2
 .LC0:	/* 2**52 */
-	.long 0x43300000
-	.long 0
+	.long 0x59800000
 .LC1:	/* 0.5 */
-	.long 0x3fe00000
-	.long 0
-.LC2:	/* -0.0 */
-	.long 0x80000000
-	.long 0
+	.long 0x3f000000
 
 /* double [fp1] round (double x [fp1])
    IEEE 1003.1 round function.  IEEE specifies "round to the nearest 
@@ -59,18 +37,28 @@ NEGZERO.0:
    "Round toward Zero" mode and round by adding +-0.5 before rounding
    to the integer value.  */
 
+	.section	".text"
 ENTRY (__round)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	addi	r9,r9,.LC0-1b@l
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
+	lfs	fp13,0(r9)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsub	fp12,fp13,fp13	/* generate 0.0  */
@@ -79,17 +67,17 @@ ENTRY (__round)
 	bnllr-	cr7
 	mtfsfi	7,1		/* Set rounding mode toward 0.  */
 #ifdef SHARED
-	lwz	r9,.LC1@got(10)
-	lfd	fp10,0(r9)
+	lfs	fp10,.LC1-.LC0(r9)
 #else
 	lis	r9,.LC1@ha
-	lfd	fp10,.LC1@l(r9)
+	lfs	fp10,.LC1@l(r9)
 #endif
 	ble-	cr6,.L4
 	fadd	fp1,fp1,fp10	/* x+= 0.5;  */
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-.L9:	
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
 	blr
 .L4:
@@ -97,16 +85,10 @@ ENTRY (__round)
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsub	fp1,fp9,fp13	/* x-= TWO52;  */
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
+.L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-#ifdef SHARED
-	lwz	r9,.LC2@got(10)
-	lfd	fp1,0(r9)
-#else
-	lis	r9,.LC2@ha
-	lfd	fp1,.LC2@l(r9)
-#endif
 	blr
 	END (__round)
 
@@ -116,3 +98,6 @@ weak_alias (__round, round)
 weak_alias (__round, roundl)
 strong_alias (__round, __roundl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __round, roundl, GLIBC_2_1)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
index ea8aaf3add..7e99bca315 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_roundf.S
@@ -1,5 +1,5 @@
 /* roundf  function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,40 +14,17 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO23.0,@object
-	.size	TWO23.0,8
-TWO23.0:
-	.long 0x43300000
-	.long 0
-	.type	POINTFIVE.0,@object
-	.size	POINTFIVE.0,8
-POINTFIVE.0:
-	.long 0x3fe00000
-	.long 0
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x80000000
-	.long 0
-
 	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.align	2
 .LC0:	/* 2**23 */
-	.long 0x41600000
-	.long 0
+	.long 0x4b000000
 .LC1:	/* 0.5 */
-	.long 0x3fe00000
-	.long 0
-.LC2:	/* -0.0 */
-	.long 0x80000000
-	.long 0
+	.long 0x3f000000
 
 /* float [fp1] roundf  (float x [fp1])
    IEEE 1003.1 round function.  IEEE specifies "round to the nearest 
@@ -59,18 +36,28 @@ NEGZERO.0:
    "Round toward Zero" mode and round by adding +-0.5 before rounding
    to the integer value.  */
 
+	.section	".text"
 ENTRY (__roundf )
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	addi	r9,r9,.LC0-1b@l
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
+	lfs	fp13,0(r9)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsubs	fp12,fp13,fp13	/* generate 0.0  */
@@ -79,17 +66,17 @@ ENTRY (__roundf )
 	bnllr-	cr7
 	mtfsfi	7,1		/* Set rounding mode toward 0.  */
 #ifdef SHARED
-	lwz	r9,.LC1@got(10)
-	lfd	fp10,0(r9)
+	lfs	fp10,.LC1-.LC0(r9)
 #else
 	lis	r9,.LC1@ha
-	lfd	fp10,.LC1@l(r9)
+	lfs	fp10,.LC1@l(r9)
 #endif
 	ble-	cr6,.L4
 	fadds	fp1,fp1,fp10	/* x+= 0.5;  */
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
-.L9:	
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
 	blr
 .L4:
@@ -97,16 +84,10 @@ ENTRY (__roundf )
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsubs	fp1,fp9,fp13	/* x-= TWO23;  */
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
+.L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-#ifdef SHARED
-	lwz	r9,.LC2@got(10)
-	lfd	fp1,0(r9)
-#else
-	lis	r9,.LC2@ha
-	lfd	fp1,.LC2@l(r9)
-#endif
 	blr
 	END (__roundf)
 
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
index a4be651f8c..5bc0856b9f 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_trunc.S
@@ -1,5 +1,5 @@
 /* trunc function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,32 +14,16 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
+#include <math_ldbl_opt.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO52.0,@object
-	.size	TWO52.0,8
-TWO52.0:
-	.long 0x43300000
-	.long 0
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x80000000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**52 */
-	.long 0x43300000
-	.long 0
-.LC1:	/* -0.0 */
-	.long 0x80000000
-	.long 0
+	.long 0x59800000
 
 /* double [fp1] trunc (double x [fp1])
    IEEE 1003.1 trunc function.  IEEE specifies "trunc to the integer
@@ -48,18 +32,28 @@ NEGZERO.0:
    We set "round toward Zero" mode and trunc by adding +-2**52 then
    subtracting +-2**52.  */
 
+	.section	".text"
 ENTRY (__trunc)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsub	fp12,fp13,fp13	/* generate 0.0  */
@@ -70,23 +64,18 @@ ENTRY (__trunc)
 	ble-	cr6,.L4
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
-.L9:	
-	mtfsf	0x01,fp11	/* restore previous truncing mode.  */
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
+	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
 	blr
 .L4:
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsub	fp1,fp1,fp13	/* x-= TWO52;  */
 	fadd	fp1,fp1,fp13	/* x+= TWO52;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
+.L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-#ifdef SHARED
-	lwz	r9,.LC1@got(10)
-	lfd	fp1,0(r9)
-#else
-	lis	r9,.LC1@ha
-	lfd	fp1,.LC1@l(r9)
-#endif
 	blr
 	END (__trunc)
 
@@ -96,3 +85,6 @@ weak_alias (__trunc, trunc)
 weak_alias (__trunc, truncl)
 strong_alias (__trunc, __truncl)
 #endif
+#if LONG_DOUBLE_COMPAT(libm, GLIBC_2_1)
+compat_symbol (libm, __trunc, truncl, GLIBC_2_1)
+#endif
diff --git a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
index 9a8dae931b..e2e3bd6740 100644
--- a/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
+++ b/sysdeps/powerpc/powerpc32/fpu/s_truncf.S
@@ -1,5 +1,5 @@
 /* truncf function.  PowerPC32 version.
-   Copyright (C) 2004 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2006 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
@@ -14,32 +14,15 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 
-	.section	.rodata
-	.align 3
-	.type	TWO23.0,@object
-	.size	TWO23.0,8
-TWO23.0:
-	.long 0x41600000
-	.long 0
-	.type	NEGZERO.0,@object
-	.size	NEGZERO.0,8
-NEGZERO.0:
-	.long 0x80000000
-	.long 0
-
-	.section	.rodata.cst8,"aM",@progbits,8
-	.align 3
+	.section	.rodata.cst4,"aM",@progbits,4
+	.align	2
 .LC0:	/* 2**23 */
-	.long 0x41600000
-	.long 0
-.LC1:	/* -0.0 */
-	.long 0x80000000
-	.long 0
+	.long 0x4b000000
 
 /* float [fp1] truncf (float x [fp1])
    IEEE 1003.1 trunc function.  IEEE specifies "trunc to the integer
@@ -48,18 +31,28 @@ NEGZERO.0:
    We set "round toward Zero" mode and trunc by adding +-2**23 then
    subtracting +-2**23.  */
 
+	.section	".text"
 ENTRY (__truncf)
 	mffs	fp11		/* Save current FPU rounding mode.  */
 #ifdef SHARED
 	mflr	r11
+	cfi_register(lr,r11)
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r9
+	addis	r9,r9,.LC0-1b@ha
+	lfs	fp13,.LC0-1b@l(r9)
+# else
 	bl	_GLOBAL_OFFSET_TABLE_@local-4
 	mflr	r10
 	lwz	r9,.LC0@got(10)
+	lfs	fp13,0(r9)
+# endif
 	mtlr	r11
-	lfd	fp13,0(r9)
+	cfi_same_value (lr)
 #else
 	lis	r9,.LC0@ha
-	lfd	fp13,.LC0@l(r9)
+	lfs	fp13,.LC0@l(r9)
 #endif
 	fabs	fp0,fp1
 	fsubs	fp12,fp13,fp13	/* generate 0.0  */
@@ -70,23 +63,18 @@ ENTRY (__truncf)
 	ble-	cr6,.L4
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
-.L9:	
-	mtfsf	0x01,fp11	/* restore previous truncing mode.  */
+	fabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = 0.0; */
+	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
 	blr
 .L4:
 	bge-	cr6,.L9		/* if (x < 0.0)  */
 	fsubs	fp1,fp1,fp13	/* x-= TWO23;  */
 	fadds	fp1,fp1,fp13	/* x+= TWO23;  */
-	fcmpu	cr5,fp1,fp12	/* if (x > 0.0)  */
+	fnabs	fp1,fp1		/* if (x == 0.0)  */
+				/* x = -0.0; */
+.L9:
 	mtfsf	0x01,fp11	/* restore previous rounding mode.  */
-	bnelr+	cr5
-#ifdef SHARED
-	lwz	r9,.LC1@got(10)
-	lfd	fp1,0(r9)
-#else
-	lis	r9,.LC1@ha
-	lfd	fp1,.LC1@l(r9)
-#endif
 	blr
 	END (__truncf)
 
diff --git a/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S b/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
index 77ee05f487..851480d2ef 100644
--- a/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/fpu/setjmp-common.S
@@ -1,5 +1,5 @@
 /* setjmp for PowerPC.
-   Copyright (C) 1995-99, 2000, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000, 2003-2005, 2006 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
@@ -14,16 +14,15 @@
 
    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.  */
+   Software Foundation, Inc., 1 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 #define _ASM
-#define _SETJMP_H
 #ifdef __NO_VMX__
 # include <novmxsetjmp.h>
 #else
-# include <bits/setjmp.h>
+# include <jmpbuf-offsets.h>
 #endif
 #include <bp-sym.h>
 #include <bp-asm.h>
@@ -32,10 +31,19 @@
 ENTRY (BP_SYM (__sigsetjmp))
 	CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
 
+#ifdef PTR_MANGLE
+	mr   r5,r1
+	PTR_MANGLE(r5, r6)
+	stw  r5,(JB_GPR1*4)(3)
+#else
 	stw  r1,(JB_GPR1*4)(3)
+#endif
 	mflr r0
 	stw  r14,((JB_GPRS+0)*4)(3)
 	stfd fp14,((JB_FPRS+0*2)*4)(3)
+#ifdef PTR_MANGLE
+	PTR_MANGLE2 (r0, r6)
+#endif
 	stw  r0,(JB_LR*4)(3)
 	stw  r15,((JB_GPRS+1)*4)(3)
 	stfd fp15,((JB_FPRS+1*2)*4)(3)
@@ -74,23 +82,31 @@ ENTRY (BP_SYM (__sigsetjmp))
 	stw  r31,((JB_GPRS+17)*4)(3)
 	stfd fp31,((JB_FPRS+17*2)*4)(3)
 #ifndef __NO_VMX__
-#ifdef PIC
+# ifdef PIC
 	mflr    r6
+	cfi_register(lr,r6)
+#  ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	r5
+	addis	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+	addi	r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+#  else
 	bl      _GLOBAL_OFFSET_TABLE_@local-4
 	mflr    r5
-#ifdef SHARED
+#  endif
+	mtlr	r6
+	cfi_same_value (lr)
+#  ifdef SHARED
 	lwz     r5,_rtld_global_ro@got(r5)
-	mtlr    r6
 	lwz     r5,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET(r5)
-#else
-	lwz     r5,_rtld_global_ro@got(r5)
-	mtlr    r6
+#  else
+	lwz     r5,_dl_hwcap@got(r5)
 	lwz     r5,0(r5)
-#endif
-#else
-	lis	r5,_dl_hwcap@ha
-	lwz     r5,_dl_hwcap@l(r5)
-#endif
+#  endif
+# else
+	lis	r6,_dl_hwcap@ha
+	lwz     r5,_dl_hwcap@l(r6)
+# endif
 	andis.	r5,r5,(PPC_FEATURE_HAS_ALTIVEC >> 16)
 	beq	L(no_vmx)
 	la	r5,((JB_VRS)*4)(3)
@@ -164,5 +180,5 @@ L(aligned_save_vmx):
 	stvx	31,0,r6
 L(no_vmx):
 #endif
-	b JUMPTARGET (BP_SYM (__sigjmp_save))
+	b BP_SYM (__sigjmp_save@local)
 END (BP_SYM (__sigsetjmp))
diff --git a/sysdeps/powerpc/powerpc32/gprrest0.S b/sysdeps/powerpc/powerpc32/gprrest0.S
index cf493f0c47..90eb4a0c4c 100644
--- a/sysdeps/powerpc/powerpc32/gprrest0.S
+++ b/sysdeps/powerpc/powerpc32/gprrest0.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2006 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
@@ -13,8 +13,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /*
     General Purpose Register (GPR) restore routine
@@ -67,3 +67,4 @@ C_TEXT(_restgpr0_29):	lwz	r0,8(r1)	#get return address from frame
 			lwz	r30,-8(r1)	#restore r30
 			lwz	r31,-4(r1)	#restore r31
 			blr			#return
+END (_restgpr0_all)
diff --git a/sysdeps/powerpc/powerpc32/gprrest1.S b/sysdeps/powerpc/powerpc32/gprrest1.S
index 5ac18606f8..ca00b8f133 100644
--- a/sysdeps/powerpc/powerpc32/gprrest1.S
+++ b/sysdeps/powerpc/powerpc32/gprrest1.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2006 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
@@ -13,8 +13,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /*
     General Purpose Register (GPR) restore routine
@@ -61,3 +61,4 @@ C_TEXT(_restgpr1_29):	lwz	r29,-12(r12)	#restore r29
 			lwz	r30,-8(r12)	#restore r30
 			lwz	r31,-4(r12)	#restore r31
 			blr			#return
+END (_restgpr1_all)
diff --git a/sysdeps/powerpc/powerpc32/gprsave0.S b/sysdeps/powerpc/powerpc32/gprsave0.S
index a09f1e569a..c74272b56d 100644
--- a/sysdeps/powerpc/powerpc32/gprsave0.S
+++ b/sysdeps/powerpc/powerpc32/gprsave0.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2006 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
@@ -13,8 +13,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /*
     General Purpose Register (GPR) save routine
@@ -30,39 +30,59 @@
 ENTRY(_savegpr0_all)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_13)
 C_TEXT(_savegpr0_13):	stw	r13,-76(r1)
+			cfi_offset(r13,-76)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_14)
 C_TEXT(_savegpr0_14):	stw	r14,-72(r1)
+			cfi_offset(r14,-72)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_15)
 C_TEXT(_savegpr0_15):	stw	r15,-68(r1)
+			cfi_offset(r15,-68)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_16)
 C_TEXT(_savegpr0_16):	stw	r16,-64(r1)
+			cfi_offset(r16,-64)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_17)
 C_TEXT(_savegpr0_17):	stw	r17,-60(r1)
+			cfi_offset(r17,-60)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_18)
 C_TEXT(_savegpr0_18):	stw	r18,-56(r1)
+			cfi_offset(r18,-56)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_19)
 C_TEXT(_savegpr0_19):	stw	r19,-52(r1)
+			cfi_offset(r19,-52)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_20)
 C_TEXT(_savegpr0_20):	stw	r20,-48(r1)
+			cfi_offset(r20,-48)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_21)
 C_TEXT(_savegpr0_21):	stw	r21,-44(r1)
+			cfi_offset(r21,-44)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_22)
 C_TEXT(_savegpr0_22):	stw	r22,-40(r1)
+			cfi_offset(r22,-40)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_23)
 C_TEXT(_savegpr0_23):	stw	r23,-36(r1)
+			cfi_offset(r23,-36)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_24)
 C_TEXT(_savegpr0_24):	stw	r24,-32(r1)
+			cfi_offset(r24,-32)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_25)
 C_TEXT(_savegpr0_25):	stw	r25,-28(r1)
+			cfi_offset(r25,-28)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_26)
 C_TEXT(_savegpr0_26):	stw	r26,-24(r1)
+			cfi_offset(r26,-24)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_27)
 C_TEXT(_savegpr0_27):	stw	r27,-20(r1)
+			cfi_offset(r27,-20)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_28)
 C_TEXT(_savegpr0_28):	stw	r28,-16(r1)
+			cfi_offset(r28,-16)
 		ASM_GLOBAL_DIRECTIVE C_TEXT(_savegpr0_29)
 C_TEXT(_savegpr0_29):	stw	r29,-12(r1) #save r29
 			stw	r30,-8(r1)  #save r30
 			stw	r31,-4(r1)  #save r31
+			cfi_offset(r29,-12)
+			cfi_offset(r30,-8)
+			cfi_offset(r31,-4)
 			stw	r0,8(r1)    #save LR in callers frame
 			blr		    #return
+END (_savegpr0_all)
diff --git a/sysdeps/powerpc/powerpc32/gprsave1.S b/sysdeps/powerpc/powerpc32/gprsave1.S
index 06ee4a69d3..6c1790129e 100644
--- a/sysdeps/powerpc/powerpc32/gprsave1.S
+++ b/sysdeps/powerpc/powerpc32/gprsave1.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2006 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
@@ -13,8 +13,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /*
     General Purpose Register (GPR) save routine
@@ -61,3 +61,4 @@ C_TEXT(_savegpr1_29):	stw	r29,-12(r12)	#save r29
 			stw	r30,-8(r12)	#save r30
 			stw	r31,-4(r12)	#save r31
 			blr			#return
+END (_savegpr1_all)
diff --git a/sysdeps/powerpc/powerpc32/hp-timing.h b/sysdeps/powerpc/powerpc32/hp-timing.h
new file mode 100644
index 0000000000..b62b0f2138
--- /dev/null
+++ b/sysdeps/powerpc/powerpc32/hp-timing.h
@@ -0,0 +1,82 @@
+/* High precision, low overhead timing functions.  Linux/PPC32 version.
+   Copyright (C) 2005 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.  */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H	1
+
+
+/* There are no generic definitions for the times.  We could write something
+   using the `gettimeofday' system call where available but the overhead of
+   the system call might be too high.
+
+   In case a platform supports timers in the hardware the following macros
+   and types must be defined:
+
+   - 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.
+
+*/
+
+/* Provide dummy definitions.  */
+#define HP_TIMING_AVAIL		(0)
+#define HP_TIMING_INLINE	(0)
+typedef unsigned long long int hp_timing_t;
+#define HP_TIMING_ZERO(Var)
+#define HP_TIMING_NOW(var)
+#define HP_TIMING_DIFF_INIT()
+#define HP_TIMING_DIFF(Diff, Start, End)
+#define HP_TIMING_ACCUM(Sum, Diff)
+#define HP_TIMING_ACCUM_NT(Sum, Diff)
+#define HP_TIMING_PRINT(Buf, Len, Val)
+
+/* Since this implementation is not available we tell the user about it.  */
+#define HP_TIMING_NONAVAIL	1
+
+#endif /* hp-timing.h */
diff --git a/sysdeps/powerpc/powerpc32/lshift.S b/sysdeps/powerpc/powerpc32/lshift.S
index 9f5870d828..65054f229d 100644
--- a/sysdeps/powerpc/powerpc32/lshift.S
+++ b/sysdeps/powerpc/powerpc32/lshift.S
@@ -1,5 +1,5 @@
 /* Shift a limb left, low level routine.
-   Copyright (C) 1996, 1997, 1999, 2000 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1997, 1999, 2000, 2006 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
@@ -14,8 +14,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdep.h>
 #include <bp-sym.h>
@@ -67,6 +67,7 @@ L(boom): tweq    r0,r0
 /* We imitate a case statement, by using (yuk!) fixed-length code chunks,
    of size 4*12 bytes.  We have to do this (or something) to make this PIC.  */
 L(big):	mflr    r9
+	cfi_register(lr,r9)
 	bltl-   cr0,L(boom)	# Never taken, only used to set LR.
 	slwi    r10,r6,4
 	mflr    r12
@@ -75,7 +76,8 @@ L(big):	mflr    r9
 	add     r10,r8,r10
 	mtctr   r10
 	addi	r5,r5,-1
-	mtlr    r9
+	mtlr	r9
+	cfi_same_value (lr)
 	bctr
 
 L(end2):slw	r0,r10,r6
diff --git a/sysdeps/powerpc/powerpc32/memset.S b/sysdeps/powerpc/powerpc32/memset.S
index 53f1143320..f09c294674 100644
--- a/sysdeps/powerpc/powerpc32/memset.S
+++ b/sysdeps/powerpc/powerpc32/memset.S
@@ -140,7 +140,7 @@ L(nondcbz):
 
 /* We can't use dcbz here as we don't know the cache line size.  We can
    use "data cache block touch for store", which is safe.  */
-L(c3):	dcbtst rNEG64, rMEMP
+L(c3):	dcbtst	rNEG64, rMEMP
 	stw	rCHR, -4(rMEMP)
 	stw	rCHR, -8(rMEMP)
 	stw	rCHR, -12(rMEMP)
@@ -166,7 +166,7 @@ L(cloopdone):
 	add	rMEMP, rMEMP, rALIGN
 	b	L(medium_tail2)	/* 72nd instruction from .align */
 
-	.align 5
+	.align	5
 	nop
 /* Clear cache lines of memory in 128-byte chunks.
    This code is optimized for processors with 32-byte cache lines.
@@ -200,7 +200,7 @@ L(zloop):
 	beqlr	cr5
 	b	L(medium_tail2)
 
-	.align 5
+	.align	5
 L(small):
 /* Memset of 4 bytes or less.  */
 	cmplwi	cr5, rLEN, 1
@@ -218,7 +218,7 @@ L(small):
 	blr
 
 /* Memset of 0-31 bytes.  */
-	.align 5
+	.align	5
 L(medium):
 	cmplwi	cr1, rLEN, 16
 L(medium_tail2):
@@ -258,70 +258,77 @@ L(medium_28t):
 
 L(checklinesize):
 #ifdef SHARED
-	mflr rTMP
+	mflr	rTMP
 /* If the remaining length is less the 32 bytes then don't bother getting
-	 the cache line size.  */
+   the cache line size.  */
 	beq	L(medium)
 /* Establishes GOT addressability so we can load __cache_line_size
    from static. This value was set from the aux vector during startup.  */
-	bl   _GLOBAL_OFFSET_TABLE_@local-4
-	mflr rGOT
-	lwz	 rGOT,__cache_line_size@got(rGOT)
-	lwz	 rCLS,0(rGOT)
-	mtlr rTMP
+# ifdef HAVE_ASM_PPC_REL16
+	bcl	20,31,1f
+1:	mflr	rGOT
+	addis	rGOT,rGOT,__cache_line_size-1b@ha
+	lwz	rCLS,__cache_line_size-1b@l(rGOT)
+# else
+	bl	_GLOBAL_OFFSET_TABLE_@local-4
+	mflr	rGOT
+	lwz	rGOT,__cache_line_size@got(rGOT)
+	lwz	rCLS,0(rGOT)
+# endif
+	mtlr	rTMP
 #else
 /* Load __cache_line_size from static. This value was set from the
    aux vector during startup.  */
-	lis	 rCLS,__cache_line_size@ha
+	lis	rCLS,__cache_line_size@ha
 /* If the remaining length is less the 32 bytes then don't bother getting
-	 the cache line size.  */
+   the cache line size.  */
 	beq	L(medium)
-	lwz  rCLS,__cache_line_size@l(rCLS)
+	lwz	rCLS,__cache_line_size@l(rCLS)
 #endif
 
-/*If the cache line size was not set then goto to L(nondcbz), which is
-	safe for any cache line size.  */
-	cmplwi cr1,rCLS,0
+/* If the cache line size was not set then goto to L(nondcbz), which is
+   safe for any cache line size.  */
+	cmplwi	cr1,rCLS,0
 	beq	cr1,L(nondcbz)
 
 /* If the cache line size is 32 bytes then goto to L(zloopstart),
-	 which is coded specificly for 32-byte lines (and 601).  */
-	cmplwi cr1,rCLS,32
+   which is coded specificly for 32-byte lines (and 601).  */
+	cmplwi	cr1,rCLS,32
 	beq	cr1,L(zloopstart)
 
 /* Now we know the cache line size and it is not 32-bytes.  However
-	 we may not yet be aligned to the cache line and may have a partial
-	 line to fill.  Touch it 1st to fetch the cache line.  */
-	dcbtst 0,rMEMP
+   we may not yet be aligned to the cache line and may have a partial
+   line to fill.  Touch it 1st to fetch the cache line.  */
+	dcbtst	0,rMEMP
 
-	addi rCLM,rCLS,-1
+	addi	rCLM,rCLS,-1
 L(getCacheAligned):
-	cmplwi cr1,rLEN,32
-	and. rTMP,rCLM,rMEMP
-	blt	 cr1,L(handletail32)
-	beq	 L(cacheAligned)
+	cmplwi	cr1,rLEN,32
+	and.	rTMP,rCLM,rMEMP
+	blt	cr1,L(handletail32)
+	beq	L(cacheAligned)
 /* We are not aligned to start of a cache line yet.  Store 32-byte
    of data and test again.  */
-	addi rMEMP,rMEMP,32
-	addi rLEN,rLEN,-32
-	stw	 rCHR,-32(rMEMP)
-	stw	 rCHR,-28(rMEMP)
-	stw	 rCHR,-24(rMEMP)
-	stw	 rCHR,-20(rMEMP)
-	stw	 rCHR,-16(rMEMP)
-	stw	 rCHR,-12(rMEMP)
-	stw	 rCHR,-8(rMEMP)
-	stw	 rCHR,-4(rMEMP)
-	b	 L(getCacheAligned)
+	addi	rMEMP,rMEMP,32
+	addi	rLEN,rLEN,-32
+	stw	rCHR,-32(rMEMP)
+	stw	rCHR,-28(rMEMP)
+	stw	rCHR,-24(rMEMP)
+	stw	rCHR,-20(rMEMP)
+	stw	rCHR,-16(rMEMP)
+	stw	rCHR,-12(rMEMP)
+	stw	rCHR,-8(rMEMP)
+	stw	rCHR,-4(rMEMP)
+	b	L(getCacheAligned)
 
 /* Now we are aligned to the cache line and can use dcbz.  */
 L(cacheAligned):
-	cmplw cr1,rLEN,rCLS
-	blt	 cr1,L(handletail32)
-	dcbz 0,rMEMP
-	subf rLEN,rCLS,rLEN
-	add	 rMEMP,rMEMP,rCLS
-	b	 L(cacheAligned)
+	cmplw	cr1,rLEN,rCLS
+	blt	cr1,L(handletail32)
+	dcbz	0,rMEMP
+	subf	rLEN,rCLS,rLEN
+	add	rMEMP,rMEMP,rCLS
+	b	L(cacheAligned)
 
 /* We are here because; the cache line size was set, it was not
    32-bytes, and the remainder (rLEN) is now less than the actual cache
@@ -329,7 +336,7 @@ L(cacheAligned):
    store the remaining bytes.  */
 L(handletail32):
 	clrrwi.	rALIGN, rLEN, 5
-	b		L(nondcbz)
+	b	L(nondcbz)
 
 END (BP_SYM (memset))
 libc_hidden_builtin_def (memset)
diff --git a/sysdeps/powerpc/powerpc32/ppc-mcount.S b/sysdeps/powerpc/powerpc32/ppc-mcount.S
index a72d676bbe..7e39acb55b 100644
--- a/sysdeps/powerpc/powerpc32/ppc-mcount.S
+++ b/sysdeps/powerpc/powerpc32/ppc-mcount.S
@@ -1,5 +1,5 @@
 /* PowerPC-specific implementation of profiling support.
-   Copyright (C) 1997, 1999 Free Software Foundation, Inc.
+   Copyright (C) 1997, 1999, 2005, 2006 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
@@ -14,8 +14,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 /* This would be bad.  */
 #ifdef PROF
@@ -24,30 +24,25 @@
 
 #include <sysdep.h>
 
-/* We do profiling as described in the SYSV ELF ABI, _mcount is called
-   with the address of a data word in r0 (that is different for every
-   routine, initialised to 0, and otherwise unused).  The caller has put
-   the address the caller will return to in the usual place on the stack,
-   4(r1).  _mcount is responsible for ensuring that when it returns no
-   argument-passing registers are disturbed, and that the LR is set back
-   to (what the caller sees as) 4(r1).
+/* We do profiling as described in the SYSV ELF ABI, except that glibc
+   _mcount manages its own counters.  The caller has put the address the
+   caller will return to in the usual place on the stack, 4(r1).  _mcount
+   is responsible for ensuring that when it returns no argument-passing
+   registers are disturbed, and that the LR is set back to (what the
+   caller sees as) 4(r1).
 
    This is intended so that the following code can be inserted at the
    front of any routine without changing the routine:
 
 	.data
-	.align	2
-   0:	.long	0
-	.previous
 	mflr	r0
-	lis	r11,0b@ha
 	stw	r0,4(r1)
-	addi	r0,r11,0b@l
 	bl	_mcount
 */
 
 ENTRY(_mcount)
 	stwu	r1,-48(r1)
+	cfi_adjust_cfa_offset (48)
 /* We need to save the parameter-passing registers.  */
 	stw	r3, 12(r1)
 	stw	r4, 16(r1)
@@ -61,8 +56,9 @@ ENTRY(_mcount)
 	stw	r9, 36(r1)
 	stw	r10,40(r1)
 	stw	r4, 44(r1)
+	cfi_offset (lr, -4)
 	stw	r5,  8(r1)
-	bl	JUMPTARGET(__mcount_internal)
+	bl	__mcount_internal@local
 	nop
  /* Restore the registers...  */
 	lwz     r6,  8(r1)
diff --git a/sysdeps/powerpc/powerpc32/register-dump.h b/sysdeps/powerpc/powerpc32/register-dump.h
index d341eea8ff..7071632083 100644
--- a/sysdeps/powerpc/powerpc32/register-dump.h
+++ b/sysdeps/powerpc/powerpc32/register-dump.h
@@ -1,5 +1,5 @@
 /* Dump registers.
-   Copyright (C) 1998 Free Software Foundation, Inc.
+   Copyright (C) 1998, 2006 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
@@ -113,7 +113,7 @@ register_dump (int fd, struct sigcontext *ctx)
     }
 
   /* Write the output.  */
-  write (fd, buffer, sizeof(buffer));
+  write (fd, buffer, sizeof(buffer) - 1);
 }
 
 
diff --git a/sysdeps/powerpc/powerpc32/setjmp-common.S b/sysdeps/powerpc/powerpc32/setjmp-common.S
index 40f626498c..12ee14d788 100644
--- a/sysdeps/powerpc/powerpc32/setjmp-common.S
+++ b/sysdeps/powerpc/powerpc32/setjmp-common.S
@@ -1,5 +1,6 @@
 /* setjmp for PowerPC.
-   Copyright (C) 1995-1997,1999-2001,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-1997,1999-2001,2003,2004,2005, 2006
+   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
@@ -19,11 +20,10 @@
 
 #include <sysdep.h>
 #define _ASM
-#define _SETJMP_H
 #ifdef __NO_VMX__
 # include <novmxsetjmp.h>
 #else
-# include <bits/setjmp.h>
+# include <jmpbuf-offsets.h>
 #endif
 #include <bp-sym.h>
 #include <bp-asm.h>
@@ -32,9 +32,19 @@
 ENTRY (BP_SYM (__sigsetjmp))
 	CHECK_BOUNDS_BOTH_WIDE_LIT (r3, r8, r9, JB_SIZE)
 
+#ifdef PTR_MANGLE
+	mr   r5,r1
+	PTR_MANGLE(r5, r10)
+	stw  r5,(JB_GPR1*4)(3)
+#else
 	stw  r1,(JB_GPR1*4)(3)
+#endif
 	mflr r0
 	stw  r14,((JB_GPRS+0)*4)(3)
+#ifdef PTR_MANGLE
+	PTR_MANGLE2 (r0, r10)
+	li   r10,0
+#endif
 	stw  r0,(JB_LR*4)(3)
 	stw  r15,((JB_GPRS+1)*4)(3)
 	mfcr r0
@@ -55,5 +65,10 @@ ENTRY (BP_SYM (__sigsetjmp))
 	stw  r29,((JB_GPRS+15)*4)(3)
 	stw  r30,((JB_GPRS+16)*4)(3)
 	stw  r31,((JB_GPRS+17)*4)(3)
-	b JUMPTARGET (BP_SYM (__sigjmp_save))
+#if defined NOT_IN_libc && defined IS_IN_rtld
+	li   r3,0
+	blr
+#else
+	b BP_SYM (__sigjmp_save@local)
+#endif
 END (BP_SYM (__sigsetjmp))
diff --git a/sysdeps/powerpc/powerpc32/strncmp.S b/sysdeps/powerpc/powerpc32/strncmp.S
index 3b33bb921f..3e0fff5ac2 100644
--- a/sysdeps/powerpc/powerpc32/strncmp.S
+++ b/sysdeps/powerpc/powerpc32/strncmp.S
@@ -47,6 +47,7 @@ EALIGN (BP_SYM(strncmp), 4, 0)
 	lis	r7F7F, 0x7f7f
 	dcbt	0,rSTR2
 	clrlwi.	rTMP, rTMP, 30
+	cmplwi	cr1, rN, 0
 	lis	rFEFE, -0x101
 	bne	L(unaligned)
 /* We are word alligned so set up for two loops.  first a word
@@ -54,7 +55,8 @@ EALIGN (BP_SYM(strncmp), 4, 0)
 	srwi.	rTMP, rN, 2
 	clrlwi	rN, rN, 30
 	addi	rFEFE, rFEFE, -0x101
-	addi	r7F7F, r7F7F, 0x7f7f	
+	addi	r7F7F, r7F7F, 0x7f7f
+	cmplwi	cr1, rN, 0	
 	beq	L(unaligned)
 
 	mtctr	rTMP	/* Power4 wants mtctr 1st in dispatch group.  */
@@ -122,16 +124,19 @@ L(tail):
 	addi	rSTR1, rSTR1, 4
 	bne-	cr1, L(different)
 	addi	rSTR2, rSTR2, 4
+	cmplwi	cr1, rN, 0
 L(unaligned):
 	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
-	cmpwi	rN,0
-	lbz	rWORD1, 0(rSTR1)
-	lbz	rWORD2, 0(rSTR2)
-	bgt	L(u1)
+	bgt	cr1, L(uz)
 L(ux):
 	li	rRTN, 0
 	blr
-
+	.align 4
+L(uz):
+	lbz	rWORD1, 0(rSTR1)
+	lbz	rWORD2, 0(rSTR2)
+	nop
+	b	L(u1)
 L(u0):
 	lbzu	rWORD2, 1(rSTR2)
 L(u1):
diff --git a/sysdeps/powerpc/powerpc32/sysdep.h b/sysdeps/powerpc/powerpc32/sysdep.h
index 59761f75b9..8fc624ebd9 100644
--- a/sysdeps/powerpc/powerpc32/sysdep.h
+++ b/sysdeps/powerpc/powerpc32/sysdep.h
@@ -1,5 +1,5 @@
 /* Assembly macros for 32-bit PowerPC.
-   Copyright (C) 1999, 2001, 2002, 2003 Free Software Foundation, Inc.
+   Copyright (C) 1999, 2001, 2002, 2003, 2006 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
@@ -14,8 +14,8 @@
 
    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.  */
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
 
 #include <sysdeps/powerpc/sysdep.h>
 
@@ -29,31 +29,11 @@
 /* The mcount code relies on a the return address being on the stack
    to locate our caller and so it can restore it; so store one just
    for its benefit.  */
-# ifdef PIC
-#  define CALL_MCOUNT							      \
-  .pushsection;								      \
-  .section ".data";    							      \
-  .align ALIGNARG(2);							      \
-0:.long 0;								      \
-  .previous;								      \
+# define CALL_MCOUNT							      \
   mflr  r0;								      \
-  stw   r0,4(r1);	       						      \
-  bl    _GLOBAL_OFFSET_TABLE_@local-4;					      \
-  mflr  r11;								      \
-  lwz   r0,0b@got(r11);							      \
+  stw   r0,4(r1);							      \
+  cfi_offset (lr, 4);	       						      \
   bl    JUMPTARGET(_mcount);
-# else  /* PIC */
-#  define CALL_MCOUNT							      \
-  .section ".data";							      \
-  .align ALIGNARG(2);							      \
-0:.long 0;								      \
-  .previous;								      \
-  mflr  r0;								      \
-  lis   r11,0b@ha;		       					      \
-  stw   r0,4(r1);	       						      \
-  addi  r0,r11,0b@l;							      \
-  bl    JUMPTARGET(_mcount);
-# endif /* PIC */
 #else  /* PROF */
 # define CALL_MCOUNT		/* Do nothing.  */
 #endif /* PROF */
@@ -63,6 +43,7 @@
   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
   .align ALIGNARG(2);							      \
   C_LABEL(name)								      \
+  cfi_startproc;							      \
   CALL_MCOUNT
 
 #define EALIGN_W_0  /* No words to insert.  */
@@ -82,6 +63,7 @@
   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
   .align ALIGNARG(2);							      \
   C_LABEL(name)								      \
+  cfi_startproc;							      \
   CALL_MCOUNT								      \
   b 0f;									      \
   .align ALIGNARG(alignt);						      \
@@ -93,11 +75,13 @@
   ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
   .align ALIGNARG(alignt);						      \
   EALIGN_W_##words;							      \
-  C_LABEL(name)
+  C_LABEL(name)								      \
+  cfi_startproc;
 #endif
 
 #undef	END
 #define END(name)							      \
+  cfi_endproc;								      \
   ASM_SIZE_DIRECTIVE(name)
 
 #define DO_CALL(syscall)				      		      \
@@ -124,7 +108,7 @@
 
 #define PSEUDO_RET							      \
     bnslr+;								      \
-    b JUMPTARGET(__syscall_error)
+    b __syscall_error@local
 #define ret PSEUDO_RET
 
 #undef	PSEUDO_END