about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/alpha/Makefile6
-rw-r--r--sysdeps/alpha/__longjmp.S59
-rw-r--r--sysdeps/alpha/__longjmp.c92
-rw-r--r--sysdeps/alpha/bits/setjmp.h79
-rw-r--r--sysdeps/alpha/bsd-_setjmp.S40
-rw-r--r--sysdeps/alpha/bsd-setjmp.S38
-rw-r--r--sysdeps/alpha/setjmp.S68
-rw-r--r--sysdeps/alpha/setjmp_aux.c76
-rw-r--r--sysdeps/generic/crypt.h2
-rw-r--r--sysdeps/generic/memccpy.c11
-rw-r--r--sysdeps/generic/memchr.c5
-rw-r--r--sysdeps/generic/memcmp.c2
-rw-r--r--sysdeps/generic/memmem.c1
-rw-r--r--sysdeps/generic/memmove.c2
-rw-r--r--sysdeps/generic/mempcpy.c66
-rw-r--r--sysdeps/generic/strcat.c2
-rw-r--r--sysdeps/generic/strchr.c2
-rw-r--r--sysdeps/generic/strcmp.c4
-rw-r--r--sysdeps/generic/strcpy.c2
-rw-r--r--sysdeps/generic/strcspn.c2
-rw-r--r--sysdeps/generic/strlen.c2
-rw-r--r--sysdeps/generic/strncat.c2
-rw-r--r--sysdeps/generic/strncmp.c4
-rw-r--r--sysdeps/generic/strncpy.c1
-rw-r--r--sysdeps/generic/strpbrk.c2
-rw-r--r--sysdeps/generic/strrchr.c4
-rw-r--r--sysdeps/generic/strsep.c2
-rw-r--r--sysdeps/generic/strspn.c1
-rw-r--r--sysdeps/generic/strstr.c2
-rw-r--r--sysdeps/generic/strtok.c2
-rw-r--r--sysdeps/generic/strtok_r.c1
-rw-r--r--sysdeps/generic/sysd-stdio.c33
-rw-r--r--sysdeps/i386/bits/select.h15
-rw-r--r--sysdeps/i386/bits/string.h17
-rw-r--r--sysdeps/i386/fpu/bits/mathinline.h21
-rw-r--r--sysdeps/i386/i486/atomicity.h57
-rw-r--r--sysdeps/i386/i486/bits/string.h850
-rw-r--r--sysdeps/i386/machine-gmon.h4
-rw-r--r--sysdeps/i386/memset.c2
-rw-r--r--sysdeps/mach/hurd/profil.c3
-rw-r--r--sysdeps/posix/defs.c2
-rw-r--r--sysdeps/posix/getcwd.c2
-rw-r--r--sysdeps/posix/pipestream.c20
-rw-r--r--sysdeps/posix/profil.c3
-rw-r--r--sysdeps/posix/sleep.c3
-rw-r--r--sysdeps/posix/stdio_init.c3
-rw-r--r--sysdeps/powerpc/Makefile18
-rw-r--r--sysdeps/powerpc/add_n.S68
-rw-r--r--sysdeps/powerpc/add_n.s68
-rw-r--r--sysdeps/powerpc/addmul_1.S49
-rw-r--r--sysdeps/powerpc/addmul_1.s50
-rw-r--r--sysdeps/powerpc/bsd-_setjmp.S6
-rw-r--r--sysdeps/powerpc/bsd-setjmp.S6
-rw-r--r--sysdeps/powerpc/dl-machine.h152
-rw-r--r--sysdeps/powerpc/lshift.S123
-rw-r--r--sysdeps/powerpc/lshift.s479
-rw-r--r--sysdeps/powerpc/machine-gmon.h (renamed from sysdeps/unix/sysv/linux/powerpc/_exit.S)20
-rw-r--r--sysdeps/powerpc/memset.S199
-rw-r--r--sysdeps/powerpc/memset.s202
-rw-r--r--sysdeps/powerpc/mul_1.S46
-rw-r--r--sysdeps/powerpc/mul_1.s47
-rw-r--r--sysdeps/powerpc/ppc-mcount.S84
-rw-r--r--sysdeps/powerpc/rshift.S56
-rw-r--r--sysdeps/powerpc/rshift.s59
-rw-r--r--sysdeps/powerpc/s_copysign.S40
-rw-r--r--sysdeps/powerpc/s_fabs.S33
-rw-r--r--sysdeps/powerpc/setjmp.S6
-rw-r--r--sysdeps/powerpc/strchr.S111
-rw-r--r--sysdeps/powerpc/strchr.s118
-rw-r--r--sysdeps/powerpc/strcmp.S115
-rw-r--r--sysdeps/powerpc/strcmp.s273
-rw-r--r--sysdeps/powerpc/strlen.S144
-rw-r--r--sysdeps/powerpc/strlen.s144
-rw-r--r--sysdeps/powerpc/sub_n.S68
-rw-r--r--sysdeps/powerpc/sub_n.s69
-rw-r--r--sysdeps/powerpc/submul_1.S52
-rw-r--r--sysdeps/powerpc/submul_1.s52
-rw-r--r--sysdeps/powerpc/test-arith.c15
-rw-r--r--sysdeps/stub/atomicity.h53
-rw-r--r--sysdeps/stub/ftruncate.c1
-rw-r--r--sysdeps/stub/getdents.c1
-rw-r--r--sysdeps/stub/init-posix.c2
-rw-r--r--sysdeps/stub/profil.c3
-rw-r--r--sysdeps/stub/reboot.c1
-rw-r--r--sysdeps/stub/swapon.c1
-rw-r--r--sysdeps/stub/syscall.c1
-rw-r--r--sysdeps/stub/ualarm.c1
-rw-r--r--sysdeps/stub/usleep.c1
-rw-r--r--sysdeps/unix/sysv/linux/if_index.c2
-rw-r--r--sysdeps/unix/sysv/linux/net/if.h5
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/bits/mman.h26
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/brk.S (renamed from sysdeps/unix/sysv/linux/powerpc/brk.c)52
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/clone.S29
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/profil-counter.h14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sigreturn.S9
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/socket.S14
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/syscall.S8
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/sysdep.h111
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/ioctls.h8
-rw-r--r--sysdeps/unix/sysv/linux/sparc/bits/termios.h10
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S2
-rw-r--r--sysdeps/vax/strcmp.s85
102 files changed, 2715 insertions, 2314 deletions
diff --git a/sysdeps/alpha/Makefile b/sysdeps/alpha/Makefile
index 5fe8e4ee7f..6cf4a173a6 100644
--- a/sysdeps/alpha/Makefile
+++ b/sysdeps/alpha/Makefile
@@ -21,10 +21,6 @@ ifeq ($(subdir),gmon)
 sysdep_routines += _mcount
 endif
 
-ifeq ($(subdir),setjmp)
-sysdep_routines += setjmp_aux
-endif
-
 ifeq ($(subdir),gnulib)
 sysdep_routines += $(divrem)
 endif
@@ -45,6 +41,6 @@ endif
 
 divrem := divl divq reml remq
 
-# For now, build everything with full IEEE math support. 
+# For now, build everything with full IEEE math support.
 # TODO: build separate libm and libm-ieee.
 sysdep-CFLAGS += -mieee
diff --git a/sysdeps/alpha/__longjmp.S b/sysdeps/alpha/__longjmp.S
new file mode 100644
index 0000000000..34731172e1
--- /dev/null
+++ b/sysdeps/alpha/__longjmp.S
@@ -0,0 +1,59 @@
+/* Copyright (C) 1992, 1994, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#define __ASSEMBLY__
+
+#include <sysdep.h>
+#include <bits/setjmp.h>
+
+
+ENTRY(__longjmp)
+#ifdef PROF
+	ldgp    gp, 0(pv)
+	.set noat
+	lda     AT, _mcount
+	jsr     AT, (AT), _mcount
+	.set at
+	.prologue 1
+#else
+	.prologue 0
+#endif
+
+	mov     a1, v0
+	ldq     s0, JB_S0*8(a0)
+	ldq     s1, JB_S1*8(a0)
+	ldq     s2, JB_S2*8(a0)
+	ldq     s3, JB_S3*8(a0)
+	ldq     s4, JB_S4*8(a0)
+	ldq     s5, JB_S5*8(a0)
+	ldq     ra, JB_PC*8(a0)
+	ldq     fp, JB_FP*8(a0)
+	ldq     t0, JB_SP*8(a0)
+	ldt     $f2, JB_F2*8(a0)
+	ldt     $f3, JB_F3*8(a0)
+	ldt     $f4, JB_F4*8(a0)
+	ldt     $f5, JB_F5*8(a0)
+	ldt     $f6, JB_F6*8(a0)
+	ldt     $f7, JB_F7*8(a0)
+	ldt     $f8, JB_F8*8(a0)
+	ldt     $f9, JB_F9*8(a0)
+	cmoveq  v0, 1, v0
+	mov     t0, sp
+	ret
+
+END(__longjmp)
diff --git a/sysdeps/alpha/__longjmp.c b/sysdeps/alpha/__longjmp.c
deleted file mode 100644
index 98eba7c513..0000000000
--- a/sysdeps/alpha/__longjmp.c
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Copyright (C) 1992, 1994, 1997 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* Global register vars must come before any function defn.  */
-
-register long int
-  r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
-  r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1				/* XXX */
-register double
-  f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
-  f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-#include <setjmp.h>
-
-
-/* Jump to the position specified by ENV, causing the
-   setjmp call there to return VAL, or 1 if VAL is 0.  */
-void
-__longjmp (__jmp_buf env, int val)
-{
-  register long int retval asm ("$0");
-
-  /* Restore the integer registers.  */
-  r9 = env[0].__9;
-  r10 = env[0].__10;
-  r11 = env[0].__11;
-  r12 = env[0].__12;
-  r13 = env[0].__13;
-  r14 = env[0].__14;
-
-#if 1				/* XXX */
-  /* Restore the floating point registers.  */
-  f2 = env[0].__f2;
-  f3 = env[0].__f3;
-  f4 = env[0].__f4;
-  f5 = env[0].__f5;
-  f6 = env[0].__f6;
-  f7 = env[0].__f7;
-  f8 = env[0].__f8;
-  f9 = env[0].__f9;
-#endif
-
-  /* Set the return PC to that of setjmp's caller.  */
-  retpc = env[0].__pc;
-
-  /* Restore the FP and SP of setjmp's caller.  */
-  fp = env[0].__fp;
-  sp = env[0].__sp;
-
-  /* Return VAL (or 1 if VAL is zero) to setjmp's caller.
-
-     We use an asm here rather than a normal C return statement
-     just in case the compiler wanted to do some stack frobnication
-     in the function epilogue.  Since we have already restored
-     precisely the FP and SP the desired environment needs,
-     we must avoid the compiler doing anything with the stack.  */
-
-
-  asm volatile
-    ("cmoveq %1, 1, %0\n\t"	/* $0 = val ?: 1; */
-     "ret $31, (%2), 1"	/* return $0 */
-     : "=r" (retval)
-     /* The "0" constraint should force VAL into $0.  */
-     : "0" (val), "r" (retpc));
-
-  while (1)
-    {
-      /* The loop is just to avoid `volatile function does return' warnings.
-	 The instruction will only be executed once.  */
-      asm volatile ("");
-    }
-}
diff --git a/sysdeps/alpha/bits/setjmp.h b/sysdeps/alpha/bits/setjmp.h
index d461205c06..9aa30463d6 100644
--- a/sysdeps/alpha/bits/setjmp.h
+++ b/sysdeps/alpha/bits/setjmp.h
@@ -17,30 +17,57 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-typedef struct
-  {
-    /* Integer registers:
-	   $0 is the return value;
-	   $1-$8, $22-$25, $28 are call-used;
-	   $9-$14 we save here;
-	   $15 is the FP and we save it here;
-	   $16-$21 are input arguments (call-used);
-	   $26 is the return PC and we save it here;
-	   $27 is the procedure value (i.e., the address of __setjmp);
-	   $29 is the global pointer, which the caller will reconstruct
-	   from the return address restored in $26;
-	   $30 is the stack pointer and we save it here;
-	   $31 is always zero.  */
-    long int __9, __10, __11, __12, __13, __14;
-    long int *__pc, *__fp, *__sp;
+/* The previous bits/setjmp.h had __jmp_buf defined as a structure.
+   We use an array of 'long int' instead, to make writing the
+   assembler easier. Naturally, user code should not depend on
+   either representation. */
 
-#if 1				/* XXX need predefine for TARGET_FPREGS */
-    /* Floating-point registers:
-	   $f0 is the floating return value;
-	   $f1, $f10-$f15, $f22-$f30 are call-used;
-	   $f2-$f9 we save here;
-	   $f16-$21 are input args (call-used);
-	   $f31 is always zero.  */
-    double __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9;
-#endif	/* Have FP regs.  */
-  } __jmp_buf[1];
+/*
+ * Integer registers:
+ *    $0 is the return value (va);
+ *    $1-$8, $22-$25, $28 are call-used (t0-t7, t8-t11, at);
+ *    $9-$14 we save here (s0-s5);
+ *    $15 is the FP and we save it here (fp or s6);
+ *    $16-$21 are input arguments (call-used) (a0-a5);
+ *    $26 is the return PC and we save it here (ra);
+ *    $27 is the procedure value (i.e., the address of __setjmp) (pv or t12);
+ *    $29 is the global pointer, which the caller will reconstruct
+ *        from the return address restored in $26 (gp);
+ *    $30 is the stack pointer and we save it here (sp);
+ *    $31 is always zero (zero).
+ *
+ * Floating-point registers:
+ *    $f0 is the floating return value;
+ *    $f1, $f10-$f15, $f22-$f30 are call-used;
+ *    $f2-$f9 we save here;
+ *    $f16-$21 are input args (call-used);
+ *    $f31 is always zero.
+ *
+ * Note that even on Alpha hardware that does not have an FPU (there
+ * isn't such a thing currently) it is required to implement the FP
+ * registers.
+ */
+
+#if defined(__USE_MISC) || defined(__ASSEMBLY__)
+#define JB_S0  0
+#define JB_S1  1
+#define JB_S2  2
+#define JB_S3  3
+#define JB_S4  4
+#define JB_S5  5
+#define JB_PC  6
+#define JB_FP  7
+#define JB_SP  8
+#define JB_F2  9
+#define JB_F3  10
+#define JB_F4  11
+#define JB_F5  12
+#define JB_F6  13
+#define JB_F7  14
+#define JB_F8  15
+#define JB_F9  16
+#endif
+
+#ifndef __ASSEMBLY__
+typedef long int __jmp_buf[17];
+#endif
diff --git a/sysdeps/alpha/bsd-_setjmp.S b/sysdeps/alpha/bsd-_setjmp.S
index 07fb0c7637..4e6a2da560 100644
--- a/sysdeps/alpha/bsd-_setjmp.S
+++ b/sysdeps/alpha/bsd-_setjmp.S
@@ -1,39 +1 @@
-/* BSD `_setjmp' entry point to `sigsetjmp (..., 0)'.  Alpha version.
-   Copyright (C) 1994, 1996 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 0)'.
-   We cannot do it in C because it must be a tail-call, so frame-unwinding
-   in setjmp doesn't clobber the state restored by longjmp.  */
-
-#include <sysdep.h>
-
-ENTRY(_setjmp)
-	ldgp	$29,0($27)
-#ifdef PROF
-	.set noat
-	lda	AT, _mcount
-	jsr	AT, (AT), _mcount
-	.set at
-#endif
-	.prologue 1
-	bis	$31, $31, $17		/* Pass a second argument of zero.  */
-	jmp	$31, __sigsetjmp	/* Call __sigsetjmp.  */
-	END(_setjmp)
-
-strong_alias_asm(_setjmp, __setjmp)
+/* _setjmp is in setjmp.S  */
diff --git a/sysdeps/alpha/bsd-setjmp.S b/sysdeps/alpha/bsd-setjmp.S
index cf5bf189de..1da848d2f1 100644
--- a/sysdeps/alpha/bsd-setjmp.S
+++ b/sysdeps/alpha/bsd-setjmp.S
@@ -1,37 +1 @@
-/* BSD `setjmp' entry point to `sigsetjmp (..., 1)'.  Alpha version.
-   Copyright (C) 1994, 1996 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* This just does a tail-call to `__sigsetjmp (ARG, 1)'.
-   We cannot do it in C because it must be a tail-call, so frame-unwinding
-   in setjmp doesn't clobber the state restored by longjmp.  */
-
-#include <sysdep.h>
-
-ENTRY(setjmp)
-	ldgp	$29, 0($27)
-#ifdef PROF
-	.set noat
-	lda	AT, _mcount
-	jsr	AT, (AT), _mcount
-	.set at
-#endif
-	.prologue 1
-	bis	$31, 1, $17		/* Pass a second argument of one.  */
-	jmp	$31, __sigsetjmp	/* Call __sigsetjmp.  */
-	END(setjmp)
+/* setjmp is in setjmp.S  */
diff --git a/sysdeps/alpha/setjmp.S b/sysdeps/alpha/setjmp.S
index 4b2e147b15..48fe33b3ec 100644
--- a/sysdeps/alpha/setjmp.S
+++ b/sysdeps/alpha/setjmp.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992, 1994, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1994, 1996, 1997 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
@@ -16,13 +16,21 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#define __ASSEMBLY__
+
 #include <sysdep.h>
+#include <bits/setjmp.h>
+
+       .ent __sigsetjmp
+       .global __sigsetjmp
+__sigsetjmp:
+       ldgp    gp, 0(pv)
 
-/* The function __sigsetjmp_aux saves all the registers, but it can't
-   reliably access the stack or frame pointers, so we pass them in as
-   extra arguments.  */
-ENTRY (__sigsetjmp)
-	ldgp	$29, 0($27)
+$sigsetjmp_local:
+       subq    sp, 16, sp
+       .frame  sp, 16, ra, 0
+       stq     ra, 0(sp)
+       .mask   0x04000000, -16
 #ifdef PROF
 	.set noat
 	lda	AT, _mcount
@@ -31,8 +39,48 @@ ENTRY (__sigsetjmp)
 #endif
 	.prologue 1
 
-	bis	$30, $30, $18		/* Pass SP as 3rd arg.  */
-	bis	$15, $15, $19		/* Pass FP as 4th arg.  */
-	jmp	$31, __sigsetjmp_aux	/* Call __sigsetjmp_aux.  */
+	stq	s0, JB_S0*8(a0)
+	stq	s1, JB_S1*8(a0)
+	stq	s2, JB_S2*8(a0)
+	stq	s3, JB_S3*8(a0)
+	stq	s4, JB_S4*8(a0)
+	stq	s5, JB_S5*8(a0)
+	stq	ra, JB_PC*8(a0)
+	addq	sp, 16, t0
+	stq	fp, JB_FP*8(a0)
+	stq	t0, JB_SP*8(a0)
+	stt	$f2, JB_F2*8(a0)
+	stt	$f3, JB_F3*8(a0)
+	stt	$f4, JB_F4*8(a0)
+	stt	$f5, JB_F5*8(a0)
+	stt	$f6, JB_F6*8(a0)
+	stt	$f7, JB_F7*8(a0)
+	stt	$f8, JB_F8*8(a0)
+	stt	$f9, JB_F9*8(a0)
+
+	/* Call to C to (potentially) save our signal mask.  */
+	jsr	ra, __sigjmp_save
+
+	ldq	ra, 0(sp)
+	addq	sp, 16, sp
+	ret
+
+END(__sigsetjmp)
+
+/* Put these traditional entry points in the same file so that we can
+   elide much of the nonsense in trying to jmp to the real function.  */
+
+ENTRY(_setjmp)
+	ldgp	gp, 0(pv)
+	mov	0, a1
+	br	$sigsetjmp_local
+END(_setjmp)
+
+ENTRY(setjmp)
+	ldgp	gp, 0(pv)
+	mov	1, a1
+	br	$sigsetjmp_local
+END(setjmp)
 
-	END(__sigsetjmp)
+weak_extern(_setjmp)
+weak_extern(setjmp)
diff --git a/sysdeps/alpha/setjmp_aux.c b/sysdeps/alpha/setjmp_aux.c
deleted file mode 100644
index fa26975295..0000000000
--- a/sysdeps/alpha/setjmp_aux.c
+++ /dev/null
@@ -1,76 +0,0 @@
-/* Copyright (C) 1992, 1994, 1997 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 Library General Public License as
-   published by the Free Software Foundation; either version 2 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
-   Library General Public License for more details.
-
-   You should have received a copy of the GNU Library General Public
-   License along with the GNU C Library; see the file COPYING.LIB.  If not,
-   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
-
-/* Global register decls must come before any function defn.  */
-
-register long int
-  r9 asm ("$9"), r10 asm ("$10"), r11 asm ("$11"), r12 asm ("$12"),
-  r13 asm ("$13"), r14 asm ("$14");
-
-register long int *fp asm ("$15"), *sp asm ("$30"), *retpc asm ("$26");
-
-#if 1				/* XXX */
-register double
-  f2 asm ("$f2"), f3 asm ("$f3"), f4 asm ("$f4"), f5 asm ("$f5"),
-  f6 asm ("$f6"), f7 asm ("$f7"), f8 asm ("$f8"), f9 asm ("$f9");
-#endif
-
-
-#include <setjmp.h>
-
-
-/* Save the current program position in ENV and return 0.  */
-int
-__sigsetjmp_aux (sigjmp_buf env, int savemask, long int *sp, long int *fp)
-{
-  /* Save the integer registers.  */
-  env[0].__jmpbuf[0].__9 = r9;
-  env[0].__jmpbuf[0].__10 = r10;
-  env[0].__jmpbuf[0].__11 = r11;
-  env[0].__jmpbuf[0].__12 = r12;
-  env[0].__jmpbuf[0].__13 = r13;
-  env[0].__jmpbuf[0].__14 = r14;
-
-#if 1				/* XXX */
-  /* Save the floating point registers.  */
-  env[0].__jmpbuf[0].__f2 = f2;
-  env[0].__jmpbuf[0].__f3 = f3;
-  env[0].__jmpbuf[0].__f4 = f4;
-  env[0].__jmpbuf[0].__f5 = f5;
-  env[0].__jmpbuf[0].__f6 = f6;
-  env[0].__jmpbuf[0].__f7 = f7;
-  env[0].__jmpbuf[0].__f8 = f8;
-  env[0].__jmpbuf[0].__f9 = f9;
-#endif
-
-  /* Save the return address of our caller, where longjmp will jump to.  */
-  env[0].__jmpbuf[0].__pc = retpc;
-
-  /* Save the FP and SP of our caller.  The __sigsetjmp entry point
-     simply puts these in the argument registers for us to fetch.  */
-  env[0].__jmpbuf[0].__fp = fp;
-  env[0].__jmpbuf[0].__sp = sp;
-
-  /* Save the signal mask if requested.  */
-  __sigjmp_save (env, savemask);
-
-  retpc = env[0].__jmpbuf[0].__pc;	/* restore ra, ugly... */
-
-  /* Return to the original caller of __sigsetjmp.  */
-  return 0;
-}
diff --git a/sysdeps/generic/crypt.h b/sysdeps/generic/crypt.h
index 3f8f960140..c14554c829 100644
--- a/sysdeps/generic/crypt.h
+++ b/sysdeps/generic/crypt.h
@@ -50,6 +50,8 @@ struct crypt_data
     int direction, initialized;
   };
 
+extern char *__crypt_r __P ((__const char *__key, __const char *__salt,
+			     struct crypt_data *__data));
 extern char *crypt_r __P ((__const char *__key, __const char *__salt,
 			   struct crypt_data *__data));
 #endif
diff --git a/sysdeps/generic/memccpy.c b/sysdeps/generic/memccpy.c
index 6d85a791c6..44a874a954 100644
--- a/sysdeps/generic/memccpy.c
+++ b/sysdeps/generic/memccpy.c
@@ -18,11 +18,12 @@
 
 #include <string.h>
 
-/*
- * Copy no more than N bytes of SRC to DEST, stopping when C is found.
- * Return the position in DEST one byte past where C was copied,
- * or NULL if C was not found in the first N bytes of SRC.
- */
+#undef __memccpy
+#undef memccpy
+
+/* Copy no more than N bytes of SRC to DEST, stopping when C is found.
+   Return the position in DEST one byte past where C was copied, or
+   NULL if C was not found in the first N bytes of SRC.  */
 void *
 __memccpy (dest, src, c, n)
       void *dest; const void *src;
diff --git a/sysdeps/generic/memchr.c b/sysdeps/generic/memchr.c
index 60276e9942..c8926c7b38 100644
--- a/sysdeps/generic/memchr.c
+++ b/sysdeps/generic/memchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1993, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1993, 1996, 1997 Free Software Foundation, Inc.
    Based on strlen implementation by Torbjorn Granlund (tege@sics.se),
    with help from Dan Sahlin (dan@sics.se) and
    commentary by Jim Blandy (jimb@ai.mit.edu);
@@ -47,9 +47,10 @@
 
 #include <sys/types.h>
 
+#undef memchr
 
-/* Search no more than N bytes of S for C.  */
 
+/* Search no more than N bytes of S for C.  */
 __ptr_t
 memchr (s, c, n)
      const __ptr_t s;
diff --git a/sysdeps/generic/memcmp.c b/sysdeps/generic/memcmp.c
index 9dac13fc91..8fa371192c 100644
--- a/sysdeps/generic/memcmp.c
+++ b/sysdeps/generic/memcmp.c
@@ -34,6 +34,8 @@
 #include <string.h>
 #endif
 
+#undef memcmp
+
 #ifdef _LIBC
 
 #include <memcopy.h>
diff --git a/sysdeps/generic/memmem.c b/sysdeps/generic/memmem.c
index 8163709686..9e4e342237 100644
--- a/sysdeps/generic/memmem.c
+++ b/sysdeps/generic/memmem.c
@@ -19,6 +19,7 @@
 #include <stddef.h>
 #include <string.h>
 
+#undef memmem
 
 /* Return the first occurrence of NEEDLE in HAYSTACK.  */
 void *
diff --git a/sysdeps/generic/memmove.c b/sysdeps/generic/memmove.c
index f4a900973d..4115aa31c7 100644
--- a/sysdeps/generic/memmove.c
+++ b/sysdeps/generic/memmove.c
@@ -29,12 +29,14 @@
 #define	a1const
 #define	a2	src	/* Second arg is SRC.  */
 #define	a2const	const
+#undef memmove
 #endif
 #if	!defined(RETURN) || !defined(rettype)
 #define	RETURN(s)	return (s)	/* Return DEST.  */
 #define	rettype		void *
 #endif
 
+
 rettype
 memmove (a1, a2, len)
      a1const void *a1;
diff --git a/sysdeps/generic/mempcpy.c b/sysdeps/generic/mempcpy.c
new file mode 100644
index 0000000000..43873405c5
--- /dev/null
+++ b/sysdeps/generic/mempcpy.c
@@ -0,0 +1,66 @@
+/* Copy memory to memory until the specified number of bytes
+   has been copied, return pointer to following byte.
+   Overlap is NOT handled correctly.
+   Copyright (C) 1991, 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Torbjorn Granlund (tege@sics.se).
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <string.h>
+#include <memcopy.h>
+#include <pagecopy.h>
+
+#undef mempcpy
+
+void *
+__mempcpy (dstpp, srcpp, len)
+     void *dstpp;
+     const void *srcpp;
+     size_t len;
+{
+  unsigned long int dstp = (long int) dstpp;
+  unsigned long int srcp = (long int) srcpp;
+
+  /* Copy from the beginning to the end.  */
+
+  /* If there not too few bytes to copy, use word copy.  */
+  if (len >= OP_T_THRES)
+    {
+      /* Copy just a few bytes to make DSTP aligned.  */
+      len -= (-dstp) % OPSIZ;
+      BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
+
+      /* Copy whole pages from SRCP to DSTP by virtual address manipulation,
+	 as much as possible.  */
+
+      PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
+
+      /* Copy from SRCP to DSTP taking advantage of the known alignment of
+	 DSTP.  Number of bytes remaining is put in the third argument,
+	 i.e. in LEN.  This number may vary from machine to machine.  */
+
+      WORD_COPY_FWD (dstp, srcp, len, len);
+
+      /* Fall out and copy the tail.  */
+    }
+
+  /* There are just a few bytes to copy.  Use byte memory operations.  */
+  BYTE_COPY_FWD (dstp, srcp, len);
+
+  return (void *) dstp;
+}
+weak_alias (__mempcpy, mempcpy)
diff --git a/sysdeps/generic/strcat.c b/sysdeps/generic/strcat.c
index 05abd01eff..d8dbab2192 100644
--- a/sysdeps/generic/strcat.c
+++ b/sysdeps/generic/strcat.c
@@ -19,6 +19,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strcat
+
 /* Append SRC on the end of DEST.  */
 char *
 strcat (dest, src)
diff --git a/sysdeps/generic/strchr.c b/sysdeps/generic/strchr.c
index d9e58a85a7..3663382556 100644
--- a/sysdeps/generic/strchr.c
+++ b/sysdeps/generic/strchr.c
@@ -22,9 +22,9 @@
 
 #include <string.h>
 
+#undef strchr
 
 /* Find the first occurrence of C in S.  */
-
 char *
 strchr (s, c)
      const char *s;
diff --git a/sysdeps/generic/strcmp.c b/sysdeps/generic/strcmp.c
index a8d9db1bc9..62e55f56ab 100644
--- a/sysdeps/generic/strcmp.c
+++ b/sysdeps/generic/strcmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997 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,6 +19,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strcmp
+
 /* Compare S1 and S2, returning less than, equal to or
    greater than zero if S1 is lexicographically less than,
    equal to or greater than S2.  */
diff --git a/sysdeps/generic/strcpy.c b/sysdeps/generic/strcpy.c
index fc6beb27fd..cb260cf85a 100644
--- a/sysdeps/generic/strcpy.c
+++ b/sysdeps/generic/strcpy.c
@@ -20,6 +20,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strcpy
+
 /* Copy SRC to DEST.  */
 char *
 strcpy (dest, src)
diff --git a/sysdeps/generic/strcspn.c b/sysdeps/generic/strcspn.c
index d7d59b250b..3630a13332 100644
--- a/sysdeps/generic/strcspn.c
+++ b/sysdeps/generic/strcspn.c
@@ -29,6 +29,8 @@
 # endif
 #endif
 
+#undef strcspn
+
 /* Return the length of the maximum initial segment of S
    which contains no characters from REJECT.  */
 size_t
diff --git a/sysdeps/generic/strlen.c b/sysdeps/generic/strlen.c
index 37dc9ed20c..1fb8b1c97c 100644
--- a/sysdeps/generic/strlen.c
+++ b/sysdeps/generic/strlen.c
@@ -20,10 +20,10 @@
 
 #include <string.h>
 
+#undef strlen
 
 /* Return the length of the null-terminated string STR.  Scan for
    the null terminator quickly by testing four bytes at a time.  */
-
 size_t
 strlen (str)
      const char *str;
diff --git a/sysdeps/generic/strncat.c b/sysdeps/generic/strncat.c
index 1233f8b54b..ae9f5e1be3 100644
--- a/sysdeps/generic/strncat.c
+++ b/sysdeps/generic/strncat.c
@@ -24,6 +24,8 @@
 typedef char reg_char;
 #endif
 
+#undef strncat
+
 char *
 strncat (s1, s2, n)
      char *s1;
diff --git a/sysdeps/generic/strncmp.c b/sysdeps/generic/strncmp.c
index eea64389f8..6e5dabebcd 100644
--- a/sysdeps/generic/strncmp.c
+++ b/sysdeps/generic/strncmp.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1996, 1997 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,6 +19,8 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strncmp
+
 /* Compare no more than N characters of S1 and S2,
    returning less than, equal to or greater than zero
    if S1 is lexicographically less than, equal to or
diff --git a/sysdeps/generic/strncpy.c b/sysdeps/generic/strncpy.c
index 06f5cec2ed..24c7269b09 100644
--- a/sysdeps/generic/strncpy.c
+++ b/sysdeps/generic/strncpy.c
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <memcopy.h>
 
+#undef strncpy
 
 char *
 strncpy (s1, s2, n)
diff --git a/sysdeps/generic/strpbrk.c b/sysdeps/generic/strpbrk.c
index 3b533e1b87..a49d2b145b 100644
--- a/sysdeps/generic/strpbrk.c
+++ b/sysdeps/generic/strpbrk.c
@@ -24,6 +24,8 @@
 # include <string.h>
 #endif
 
+#undef strpbrk
+
 /* Find the first occurrence in S of any character in ACCEPT.  */
 char *
 strpbrk (s, accept)
diff --git a/sysdeps/generic/strrchr.c b/sysdeps/generic/strrchr.c
index db5549b922..98839ea4c4 100644
--- a/sysdeps/generic/strrchr.c
+++ b/sysdeps/generic/strrchr.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 1995, 1996, 1997 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,6 +18,8 @@
 
 #include <string.h>
 
+#undef strrchr
+
 /* Find the last occurrence of C in S.  */
 char *
 strrchr (const char *s, int c)
diff --git a/sysdeps/generic/strsep.c b/sysdeps/generic/strsep.c
index b2c7e90c39..b5ea6ead9d 100644
--- a/sysdeps/generic/strsep.c
+++ b/sysdeps/generic/strsep.c
@@ -18,6 +18,8 @@
 
 #include <string.h>
 
+#undef strsep
+
 char *
 __strsep (char **stringp, const char *delim)
 {
diff --git a/sysdeps/generic/strspn.c b/sysdeps/generic/strspn.c
index 9d2fe63848..5f64a6f756 100644
--- a/sysdeps/generic/strspn.c
+++ b/sysdeps/generic/strspn.c
@@ -18,6 +18,7 @@
 
 #include <string.h>
 
+#undef strspn
 
 /* Return the length of the maximum initial segment
    of S which contains only characters in ACCEPT.  */
diff --git a/sysdeps/generic/strstr.c b/sysdeps/generic/strstr.c
index 85774d3491..03d6c8e5fc 100644
--- a/sysdeps/generic/strstr.c
+++ b/sysdeps/generic/strstr.c
@@ -36,6 +36,8 @@
 
 typedef unsigned chartype;
 
+#undef strstr
+
 char *
 strstr (phaystack, pneedle)
      const char *phaystack;
diff --git a/sysdeps/generic/strtok.c b/sysdeps/generic/strtok.c
index 5eb0ee6f07..b366653cb3 100644
--- a/sysdeps/generic/strtok.c
+++ b/sysdeps/generic/strtok.c
@@ -21,6 +21,8 @@
 
 static char *olds = NULL;
 
+#undef strtok
+
 /* Parse S into tokens separated by characters in DELIM.
    If S is NULL, the last string strtok() was called with is
    used.  For example:
diff --git a/sysdeps/generic/strtok_r.c b/sysdeps/generic/strtok_r.c
index 3b7d202a6c..44430dae40 100644
--- a/sysdeps/generic/strtok_r.c
+++ b/sysdeps/generic/strtok_r.c
@@ -19,6 +19,7 @@
 
 #include <string.h>
 
+#undef strtok_r
 
 /* Parse S into tokens separated by characters in DELIM.
    If S is NULL, the saved pointer in SAVE_PTR is used as
diff --git a/sysdeps/generic/sysd-stdio.c b/sysdeps/generic/sysd-stdio.c
index f5147bb3aa..9818f84c5c 100644
--- a/sysdeps/generic/sysd-stdio.c
+++ b/sysdeps/generic/sysd-stdio.c
@@ -28,10 +28,7 @@
 
 /* Read N bytes into BUF from COOKIE.  */
 int
-__stdio_read (cookie, buf, n)
-     void *cookie;
-     register char *buf;
-     register size_t n;
+__stdio_read (void *cookie, char *buf, size_t n;)
 {
   const int fd = (int) cookie;
 #if	defined (EINTR) && defined (EINTR_REPEAT)
@@ -58,10 +55,7 @@ __stdio_read (cookie, buf, n)
 
 /* Write N bytes from BUF to COOKIE.  */
 int
-__stdio_write (cookie, buf, n)
-     void *cookie;
-     register const char *buf;
-     register size_t n;
+__stdio_write (void *cookie, const char *buf, size_t n)
 {
   const int fd = (int) cookie;
   register size_t written = 0;
@@ -92,10 +86,7 @@ __stdio_write (cookie, buf, n)
    The new file position is stored in *POS.
    Returns zero if successful, nonzero if not.  */
 int
-__stdio_seek (cookie, pos, whence)
-     void *cookie;
-     fpos_t *pos;
-     int whence;
+__stdio_seek (void *cookie, fpos_t *pos, int whence)
 {
   off_t new;
   new = __lseek ((int) cookie, (off_t) *pos, whence);
@@ -108,8 +99,7 @@ __stdio_seek (cookie, pos, whence)
 
 /* Close COOKIE.  */
 int
-__stdio_close (cookie)
-     void *cookie;
+__stdio_close (void *cookie)
 {
   return __close ((int) cookie);
 }
@@ -118,8 +108,7 @@ __stdio_close (cookie)
    or -1 for errors.  If COOKIE does not relate to any POSIX.1 file
    descriptor, this should return -1 with errno set to EOPNOTSUPP.  */
 int
-__stdio_fileno (cookie)
-     void *cookie;
+__stdio_fileno (void *cookie)
 {
   return (int) cookie;
 }
@@ -127,10 +116,7 @@ __stdio_fileno (cookie)
 
 /* Open the given file with the mode given in the __io_mode argument.  */
 int
-__stdio_open (filename, m, cookieptr)
-     const char *filename;
-     __io_mode m;
-     void **cookieptr;
+__stdio_open (const char *filename, __io_mode m, void **cookieptr)
 {
   int fd;
   int mode;
@@ -164,11 +150,8 @@ __stdio_open (filename, m, cookieptr)
 /* Open FILENAME with the mode in M.  Use the same magic cookie
    already in *COOKIEPTR if possible, closing the old cookie with CLOSEFN.  */
 int
-__stdio_reopen (filename, m, cookieptr, closefn)
-     const char *filename;
-     __io_mode m;
-     void **cookieptr;
-     __io_close_fn closefn;
+__stdio_reopen (const char *filename, __io_mode m, void **cookieptr,
+		__io_close_fn closefn)
 {
   void *newcookie;
 
diff --git a/sysdeps/i386/bits/select.h b/sysdeps/i386/bits/select.h
index 8c9a5434b9..edcb562945 100644
--- a/sysdeps/i386/bits/select.h
+++ b/sysdeps/i386/bits/select.h
@@ -24,29 +24,30 @@
 #if defined __GNUC__ && __GNUC__ >= 2
 
 # define __FD_ZERO(fdsetp) \
-  __asm__ __volatile__ ("cld ; rep ; stosl"				      \
-			: "=m" (*(__fd_set *) (fdsetp))			      \
+  __asm__ __volatile__ ("cld; rep; stosl"				      \
+			: "=m" (((__fd_mask *)				      \
+				 (fdsetp))[__FDELT (__FD_SETSIZE)])	      \
 			: "a" (0), "c" (sizeof (__fd_set)		      \
 					/ sizeof (__fd_mask)),		      \
 			  "D" ((__fd_set *) (fdsetp))			      \
 			:"cx","di")
 # define __FD_SET(fd, fdsetp) \
   __asm__ __volatile__ ("btsl %1,%0"					      \
-			: "=m" (((__fd_set *) (fdsetp))[__FDELT (fd)])	      \
+			: "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)])	      \
 			: "r" (((int) (fd)) % __NFDBITS)		      \
 			: "cc")
 # define __FD_CLR(fd, fdsetp) \
   __asm__ __volatile__ ("btrl %1,%0"					      \
-			: "=m" (((__fd_set *) (fdsetp))[__FDELT (fd)])	      \
+			: "=m" (((__fd_mask *) (fdsetp))[__FDELT (fd)])	      \
 			: "r" (((int) (fd)) % __NFDBITS)		      \
 			: "cc")
 # define __FD_ISSET(fd, fdsetp) \
   (__extension__							      \
-   ({unsigned int __result;						      \
-     __asm__ __volatile__ ("btl %1,%2 ; setcb %b0; andl $1,%0"		      \
+   ({register char __result;						      \
+     __asm__ __volatile__ ("btl %1,%2 ; setcb %b0"			      \
 			   : "=q" (__result)				      \
 			   : "r" (((int) (fd)) % __NFDBITS),		      \
-			     "m" (((__fd_set *) (fdsetp))[__FDELT (fd)])      \
+			     "m" (((__fd_mask *) (fdsetp))[__FDELT (fd)])     \
 			   : "cc");					      \
      __result; }))
 
diff --git a/sysdeps/i386/bits/string.h b/sysdeps/i386/bits/string.h
index 254db3e7f3..2931684781 100644
--- a/sysdeps/i386/bits/string.h
+++ b/sysdeps/i386/bits/string.h
@@ -41,7 +41,7 @@
 __STRING_INLINE void *
 __memcpy_c (void *__dest, __const void *__src, size_t __n)
 {
-  switch (n)
+  switch (__n)
     {
     case 0:
       return __dest;
@@ -102,10 +102,10 @@ __memcpy_c (void *__dest, __const void *__src, size_t __n)
      "rep; movsl"							      \
      x									      \
      : /* no outputs */							      \
-     : "c" (n / 4), "D" (__dest), "S" (__src)				      \
+     : "c" (__n / 4), "D" (__dest), "S" (__src)				      \
      : "cx", "di", "si", "memory");
 
-  switch (n % 4)
+  switch (__n % 4)
     {
     case 0:
       __COMMON_CODE ("");
@@ -232,8 +232,7 @@ __memset_gg (void *__s, char __c, size_t __n)
 {
   __asm__ __volatile__
     ("cld\n\t"
-     "rep\n\t"
-     "stosb"
+     "rep; stosb"
      : /* no output */
      : "a" (__c),"D" (__s), "c" (__n)
      : "cx", "di", "memory");
@@ -518,7 +517,7 @@ strcspn (__const char *__s, __const char *__reject)
      "2:\n\t"
      "popl	%%ebx"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -577,7 +576,7 @@ strspn (__const char *__s, __const char *__accept)
      "2:\n\t"
      "popl	%%ebx"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -639,7 +638,7 @@ strpbrk (__const char *__s, __const char *__accept)
      "3:\n\t"
      "popl	%%ebx"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
      : "ax", "cx", "di", "cc");
   return __res;
 }
@@ -704,7 +703,7 @@ strstr (__const char *__haystack, __const char *__needle)
      "2:\n\t"
      "popl	%%ebx"
      : "=a" (__res)
-     : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+     : "0" (0), "c" (0xffffffff), "S" (__haystack), "r" (__needle)
      : "cx", "di", "si", "cc");
   return __res;
 }
diff --git a/sysdeps/i386/fpu/bits/mathinline.h b/sysdeps/i386/fpu/bits/mathinline.h
index 17f62a080f..55e9171459 100644
--- a/sysdeps/i386/fpu/bits/mathinline.h
+++ b/sysdeps/i386/fpu/bits/mathinline.h
@@ -28,43 +28,40 @@
    These must not be inline functions since we have to be able to handle
    all floating-point types.  */
 # define isgreater(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; testb $0x45, %%ah; setz %%al;"	      \
-		 "andl $0x01, %0"					      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define isgreaterequal(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; testb $0x05, %%ah; setz %%al;"	      \
-		 "andl $0x01, %0"					      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define isless(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x45, %%ah;"      \
-		 "setz %%al; andl $0x01, %0"				      \
+		 "setz %%al"						      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define islessequal(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; xorb $0x01, %%ah; testb $0x05, %%ah;"      \
-		 "setz %%al; andl $0x01, %0"				      \
+		 "setz %%al"						      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define islessgreater(x, y) \
-     ({ int __result;							      \
+     ({ register char __result;						      \
 	__asm__ ("fucompp; fnstsw; testb $0x44, %%ah; setz %%al;"	      \
-		 "andl $0x01, %0"					      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 
 # define isunordered(x, y) \
-     ({ int __result;							      \
-	__asm__ ("fucompp; fnstsw; sahf; setp %%al; andl $0x01, %0"	      \
+     ({ register char __result;						      \
+	__asm__ ("fucompp; fnstsw; sahf; setp %%al"			      \
 		 : "=a" (__result) : "u" (y), "t" (x) : "cc", "st", "st(1)"); \
 	__result; })
 #endif
diff --git a/sysdeps/i386/i486/atomicity.h b/sysdeps/i386/i486/atomicity.h
new file mode 100644
index 0000000000..98a2531365
--- /dev/null
+++ b/sysdeps/i386/i486/atomicity.h
@@ -0,0 +1,57 @@
+/* Low-level functions for atomitc operations.  ix86 version, x >= 4.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _ATOMICITY_H
+#define _ATOMICITY_H	1
+
+#include <inttypes.h>
+
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (volatile uint32_t *mem, int val)
+{
+  register int result;
+  __asm__ __volatile__ ("lock; xaddl %0,%1"
+			: "=r" (result) : "0" (val), "m" (*mem) : "memory");
+  return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (volatile uint32_t *mem, int val)
+{
+  __asm__ __volatile__ ("lock; addl %0,%1"
+			: : "ir" (val), "m" (*mem) : "memory");
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (volatile long int *p, long int oldval, long int newval)
+{
+  char ret;
+  long int readval;
+
+  __asm__ __volatile__ ("lock; cmpxchgl %3, %1; sete %0"
+                        : "=q" (ret), "=m" (*p), "=a" (readval)
+                        : "r" (newval), "m" (*p), "a" (oldval));
+  return ret;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/i386/i486/bits/string.h b/sysdeps/i386/i486/bits/string.h
index f141bd50e1..770f5c1e15 100644
--- a/sysdeps/i386/i486/bits/string.h
+++ b/sysdeps/i386/i486/bits/string.h
@@ -32,16 +32,19 @@
 
 
 /* Copy N bytes of SRC to DEST.  */
+#define _HAVE_STRING_ARCH_memcpy 1
 #define memcpy(dest, src, n) \
   (__extension__ (__builtin_constant_p (n)				      \
 		  ? __memcpy_c (dest, src, n)				      \
 		  : __memcpy_g (dest, src, n)))
 #define __memcpy_c(dest, src, n) \
-  (((n) % 4 == 0)							      \
-   ? __memcpy_by4 (dest, src, n)					      \
-   : (((n) % 2 == 0)							      \
-      ? __memcpy_by2 (dest, src, n)					      \
-      : __memcpy_g (dest, src, n)))
+  ((n) == 0								      \
+   ? (dest)								      \
+   : (((n) % 4 == 0)							      \
+      ? __memcpy_by4 (dest, src, n)					      \
+      : (((n) % 2 == 0)							      \
+	 ? __memcpy_by2 (dest, src, n)					      \
+	 : __memcpy_g (dest, src, n))))
 
 __STRING_INLINE void *
 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
@@ -135,6 +138,7 @@ memmove (void *__dest, __const void *__src, size_t __n)
 
 
 /* Compare N bytes of S1 and S2.  */
+#define _HAVE_STRING_ARCH_memcmp 1
 #ifndef __PIC__
 /* gcc has problems to spill registers when using PIC.  */
 __STRING_INLINE int
@@ -157,6 +161,7 @@ memcmp (__const void *__s1, __const void *__s2, size_t __n)
 
 
 /* Set N bytes of S to C.  */
+#define _HAVE_STRING_ARCH_memset 1
 #define memset(s, c, n) \
   (__extension__ (__builtin_constant_p (c)				      \
 		  ? (__builtin_constant_p (n)				      \
@@ -166,17 +171,21 @@ memcmp (__const void *__s1, __const void *__s2, size_t __n)
 		     ? __memset_gc (s, c, n)				      \
 		     : __memset_gg (s, c, n))))
 #define __memset_cc(s, c, n) \
-  (((n) % 4 == 0)							      \
-   ? __memset_cc_by4 (s, c, n)						      \
-   : (((n) % 2== 0)							      \
-      ? __memset_cc_by2 (s, c, n)					      \
-      : __memset_cg (s, c, n)))
+  ((n) == 0								      \
+   ? (s)								      \
+   : (((n) % 4 == 0)							      \
+      ? __memset_cc_by4 (s, c, n)					      \
+      : (((n) % 2== 0)							      \
+	 ? __memset_cc_by2 (s, c, n)					      \
+	 : __memset_cg (s, c, n))))
 #define __memset_gc(s, c, n) \
-  (((n) % 4== 0)							      \
-   ? __memset_gc_by4 (s, c, n)						      \
-   : (((n) % 2 == 0)							      \
-      ? __memset_gc_by2 (s, c, n)					      \
-      : __memset_gg (s, c, n)))
+  ((n) == 0								      \
+   ? (s)								      \
+   : (((n) % 4== 0)							      \
+      ? __memset_gc_by4 (s, c, n)					      \
+      : (((n) % 2 == 0)							      \
+	 ? __memset_gc_by2 (s, c, n)					      \
+	 : __memset_gg (s, c, n))))
 
 __STRING_INLINE void *
 __memset_cc_by4 (void *__s, int __c, size_t __n)
@@ -196,7 +205,7 @@ __memset_cc_by4 (void *__s, int __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_cc_by2 (void *__s, char __c, size_t __n)
+__memset_cc_by2 (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   register int __dummy;
@@ -217,7 +226,7 @@ __memset_cc_by2 (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_gc_by4 (void *__s, char __c, size_t __n)
+__memset_gc_by4 (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   register int __dummy;
@@ -238,7 +247,7 @@ __memset_gc_by4 (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_gc_by2 (void *__s, char __c, size_t __n)
+__memset_gc_by2 (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   register int __dummy1, __dummy2;
@@ -263,7 +272,7 @@ __memset_gc_by2 (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_cg (void *__s, char __c, size_t __n)
+__memset_cg (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   __asm__ __volatile__
@@ -279,7 +288,7 @@ __memset_cg (void *__s, char __c, size_t __n)
 }
 
 __STRING_INLINE void *
-__memset_gg (void *__s, char __c, size_t __n)
+__memset_gg (void *__s, int __c, size_t __n)
 {
   register void *__tmp = __s;
   __asm__ __volatile__
@@ -297,6 +306,7 @@ __memset_gg (void *__s, char __c, size_t __n)
 
 
 /* Search N bytes of S for C.  */
+#define _HAVE_STRING_ARCH_memchr 1
 __STRING_INLINE void *
 memchr (__const void *__s, int __c, size_t __n)
 {
@@ -318,16 +328,21 @@ memchr (__const void *__s, int __c, size_t __n)
 
 
 /* Return the length of S.  */
+#define _HAVE_STRING_ARCH_strlen 1
+#define strlen(str) \
+  (__extension__ (__builtin_constant_p (str)				      \
+		  ? sizeof (str) - 1					      \
+		  : __strlen_g (str)))
 __STRING_INLINE size_t
-strlen (__const char *__str)
+__strlen_g (__const char *__str)
 {
   register char __dummy;
   register __const char *__tmp = __str;
   __asm__ __volatile__
     ("1:\n\t"
-     "movb	(%0),%1\n\t"
+     "movb	(%0),%b1\n\t"
      "leal	1(%0),%0\n\t"
-     "testb	%1,%1\n\t"
+     "testb	%b1,%b1\n\t"
      "jne	1b"
      : "=r" (__tmp), "=q" (__dummy)
      : "0" (__str)
@@ -337,19 +352,25 @@ strlen (__const char *__str)
 
 
 /* Copy SRC to DEST.  */
+#define _HAVE_STRING_ARCH_strcpy 1
+#define strcpy(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? (char *) memcpy (dest, src, strlen (src) + 1)	      \
+		  : __strcpy_g (dest, src)))
+
 __STRING_INLINE char *
-strcpy (char *__dest, __const char *__src)
+__strcpy_g (char *__dest, __const char *__src)
 {
   register char *__tmp = __dest;
   register char __dummy;
   __asm__ __volatile__
     (
      "1:\n\t"
-     "movb	(%0),%2\n\t"
-     "incl	%0\n\t"
-     "movb	%2,(%1)\n\t"
-     "incl	%1\n\t"
-     "testb	%2,%2\n\t"
+     "movb	(%0),%b2\n\t"
+     "leal	1(%0),%0\n\t"
+     "movb	%b2,(%1)\n\t"
+     "leal	1(%1),%1\n\t"
+     "testb	%b2,%b2\n\t"
      "jne	1b"
      : "=r" (__src), "=r" (__tmp), "=q" (__dummy)
      : "0" (__src), "1" (__tmp)
@@ -358,9 +379,233 @@ strcpy (char *__dest, __const char *__src)
 }
 
 
+#ifdef __USE_GNU
+# define _HAVE_STRING_ARCH_stpcpy 1
+/* Copy SRC to DEST.  */
+# define __stpcpy(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? (strlen (src) + 1 <= 8				      \
+		     ? __stpcpy_small (dest, src, strlen (src) + 1)	      \
+		     : __stpcpy_c (dest, src, strlen (src) + 1))	      \
+		  : __stpcpy_g (dest, src)))
+# define __stpcpy_c(dest, src, srclen) \
+  ((srclen) % 4 == 0							      \
+   ? __mempcpy_by4 (dest, src, srclen)					      \
+   : ((srclen) % 2 == 0							      \
+      ? __mempcpy_by2 (dest, src, srclen)				      \
+      : __mempcpy_byn (dest, src, srclen)))
+
+/* In glibc itself we use this symbol for namespace reasons.  */
+# define stpcpy(dest, src) __stpcpy (dest, src)
+
+__STRING_INLINE char *
+__stpcpy_small (char *__dest, __const char __src[], size_t __srclen)
+{
+  register char *__tmp = __dest;
+  switch (__srclen)
+    {
+    case 7:
+      *((unsigned short int *) __tmp)++ = *((unsigned short int *) __src)++;
+    case 5:
+      *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+      *((unsigned char *) __tmp) = '\0';
+      return __tmp;
+
+    case 8:
+      *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+    case 4:
+      *((unsigned int *) __tmp) = *((unsigned int *) __src);
+      return __tmp + 3;
+
+    case 6:
+      *((unsigned int *) __tmp)++ = *((unsigned int *) __src)++;
+    case 2:
+      *((unsigned short int *) __tmp) = *((unsigned short int *) __src);
+      return __tmp + 1;
+
+    case 3:
+      *((unsigned short int *) __tmp)++ = *((unsigned short int *) __src)++;
+    case 1:
+      *((unsigned char *) __tmp) = '\0';
+      return __tmp;
+
+    default:
+      break;
+    }
+  /* This should never happen.  */
+  return NULL;
+}
+
+__STRING_INLINE char *
+__mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b"
+     : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+     : "memory", "cc");
+  return __tmp - 1;
+}
+
+__STRING_INLINE char *
+__mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("shrl	$1,%3\n\t"
+     "jz	2f\n"                 /* only a word */
+     "1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b\n"
+     "2:\n\t"
+     "movw	(%2),%w0\n\t"
+     "movw	%w0,(%1)"
+     : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
+     : "memory", "cc");
+  return __tmp + 1;
+}
+
+__STRING_INLINE char *
+__mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
+{
+  register char *__tmp = __dest;
+  __asm__ __volatile__
+    ("cld\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	1f\n\t"
+     "movsb\n"
+     "1:\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	2f\n\t"
+     "movsw\n"
+     "2:\n\t"
+     "rep; movsl"
+     : "=D" (__tmp)
+     : "c" (__srclen), "0" (__tmp),"S" (__src)
+     : "cx", "di", "si", "memory", "cc");
+  return __tmp - 1;
+}
+
+__STRING_INLINE char *
+__stpcpy_g (char *__dest, __const char *__src)
+{
+  register char *__tmp = __dest;
+  register char __dummy;
+  __asm__ __volatile__
+    (
+     "1:\n\t"
+     "movb	(%0),%b2\n\t"
+     "leal	1(%0),%0\n\t"
+     "movb	%b2,(%1)\n\t"
+     "leal	1(%1),%1\n\t"
+     "testb	%b2,%b2\n\t"
+     "jne	1b"
+     : "=r" (__src), "=r" (__tmp), "=q" (__dummy)
+     : "0" (__src), "1" (__tmp)
+     : "memory", "cc");
+  return __tmp - 1;
+}
+#endif
+
+
 /* Copy no more than N characters of SRC to DEST.  */
+#define _HAVE_STRING_ARCH_strncpy 1
+#define strncpy(dest, src, n) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? ((strlen (src) + 1 >= ((size_t) (n))		      \
+		      ? (char *) memcpy (dest, src, n)			      \
+		      : __strncpy_cg (dest, src, strlen (src) + 1, n)))	      \
+		  : __strncpy_gg (dest, src, n)))
+#define __strncpy_cg(dest, src, srclen, n) \
+  (((srclen) % 4 == 0)							      \
+   ? __strncpy_by4 (dest, src, srclen, n)				      \
+   : (((srclen) % 2 == 0)						      \
+      ? __strncpy_by2 (dest, src, srclen, n)				      \
+      : __strncpy_byn (dest, src, srclen, n)))
+
+__STRING_INLINE char *
+__strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b"
+     : "=r" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
+     : "memory", "cc");
+  (void) memset (__tmp, '\0', __n - __srclen);
+  return __dest;
+}
+
 __STRING_INLINE char *
-strncpy (char *__dest, __const char *__src, size_t __n)
+__strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+  register char *__tmp = __dest;
+  register int __dummy1, __dummy2;
+  __asm__ __volatile__
+    ("shrl	$1,%3\n\t"
+     "jz	2f\n"                 /* only a word */
+     "1:\n\t"
+     "movl	(%2),%0\n\t"
+     "leal	4(%2),%2\n\t"
+     "movl	%0,(%1)\n\t"
+     "leal	4(%1),%1\n\t"
+     "decl	%3\n\t"
+     "jnz	1b\n"
+     "2:\n\t"
+     "movw	(%2),%w0\n\t"
+     "movw	%w0,(%1)\n\t"
+     : "=q" (__dummy1), "=r" (__tmp), "=r" (__src), "=r" (__dummy2)
+     : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
+     : "memory", "cc");
+  (void) memset (__tmp + 2, '\0', __n - __srclen);
+  return __dest;
+}
+
+__STRING_INLINE char *
+__strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
+{
+  register char *__tmp = __dest;
+  __asm__ __volatile__
+    ("cld\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	1f\n\t"
+     "movsb\n"
+     "1:\n\t"
+     "shrl	$1,%%ecx\n\t"
+     "jnc	2f\n\t"
+     "movsw\n"
+     "2:\n\t"
+     "rep; movsl"
+     : "=D" (__tmp)
+     : "c" (__srclen), "0" (__tmp),"S" (__src)
+     : "cx", "di", "si", "memory", "cc");
+  (void) memset (__tmp, '\0', __n - __srclen);
+  return __dest;
+}
+
+__STRING_INLINE char *
+__strncpy_gg (char *__dest, __const char *__src, size_t __n)
 {
   register char *__tmp = __dest;
   register char __dummy;
@@ -390,14 +635,35 @@ strncpy (char *__dest, __const char *__src, size_t __n)
 
 
 /* Append SRC onto DEST.  */
+#define _HAVE_STRING_ARCH_strcat 1
+#define strcat(dest, src) \
+  (__extension__ (__builtin_constant_p (src)				      \
+		  ? __strcat_c (dest, src, strlen (src) + 1)		      \
+		  : __strcat_g (dest, src)))
+
+__STRING_INLINE char *
+__strcat_c (char *__dest, __const char __src[], size_t __srclen)
+{
+  register char *__tmp = __dest - 1;
+  __asm__ __volatile__
+    ("1:\n\t"
+     "incl	%0\n\t"
+     "cmpb	$0,(%0)\n\t"
+     "jne	1b\n"
+     : "=r" (__tmp)
+     : "0" (__tmp)
+     : "cc");
+  (void) memcpy (__tmp, __src, __srclen);
+  return __dest;
+}
+
 __STRING_INLINE char *
-strcat (char *__dest, __const char *__src)
+__strcat_g (char *__dest, __const char *__src)
 {
   register char *__tmp = __dest - 1;
   register char __dummy;
   __asm__ __volatile__
-    (
-     "1:\n\t"
+    ("1:\n\t"
      "incl	%1\n\t"
      "cmpb	$0,(%1)\n\t"
      "jne	1b\n"
@@ -416,16 +682,23 @@ strcat (char *__dest, __const char *__src)
 
 
 /* Append no more than N characters from SRC onto DEST.  */
+#define _HAVE_STRING_ARCH_strncat 1
+#define strncat(dest, src, n) \
+  (__extension__ (__builtin_constant_p (src) && __builtin_constant_p (n)      \
+		  ? (strlen (src) < ((size_t) (n))			      \
+		     ? strcat (dest, src)				      \
+		     : (memcpy (strchr (dest, '\0'), src, n), dest))	      \
+		  : __strncat_g (dest, src, n)))
+
 __STRING_INLINE char *
-strncat (char *__dest, __const char *__src, size_t __n)
+__strncat_g (char *__dest, __const char __src[], size_t __n)
 {
   register char *__tmp = __dest - 1;
   register char __dummy;
   __asm__ __volatile__
-    (
-     "1:\n\t"
-     "incl	%1\n\t"
-     "cmpb	$0,(%1)\n\t"
+    ("1:\n\t"
+     "cmpb	$0,1(%1)\n\t"
+     "leal	1(%1),%1\n\t"
      "jne	1b\n"
      "2:\n\t"
      "decl	%3\n\t"
@@ -435,7 +708,8 @@ strncat (char *__dest, __const char *__src, size_t __n)
      "movb	%b0,(%1)\n\t"
      "leal	1(%1),%1\n\t"
      "testb	%b0,%b0\n\t"
-     "jne	2b\n"
+     "jne	2b\n\t"
+     "decl	%1\n"
      "3:\n\t"
      "movb	$0,(%1)\n\t"
      : "=q" (__dummy), "=r" (__tmp), "=r" (__src), "=r" (__n)
@@ -446,6 +720,7 @@ strncat (char *__dest, __const char *__src, size_t __n)
 
 
 /* Compare S1 and S2.  */
+#define _HAVE_STRING_ARCH_strcmp 1
 __STRING_INLINE int
 strcmp (__const char *__s1, __const char *__s2)
 {
@@ -474,8 +749,16 @@ strcmp (__const char *__s1, __const char *__s2)
 
 
 /* Compare N characters of S1 and S2.  */
+#define _HAVE_STRING_ARCH_strncmp 1
+#define strncmp(s1, s2, n) \
+  (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n))   \
+		  ? strcmp (s1, s2)					      \
+		  : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
+		     ? strcmp (s1, s2)					      \
+		     : __strncmp_g (s1, s2, n))))
+
 __STRING_INLINE int
-strncmp (__const char *__s1, __const char *__s2, size_t __n)
+__strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
 {
   register int __res;
   __asm__ __volatile__
@@ -505,18 +788,18 @@ strncmp (__const char *__s1, __const char *__s2, size_t __n)
 
 
 /* Find the first occurrence of C in S.  */
+#define _HAVE_STRING_ARCH_strchr 1
 #define strchr(s, c) \
   (__extension__ (__builtin_constant_p (c)				      \
 		  ? __strchr_c (s, ((c) & 0xff) << 8)			      \
 		  : __strchr_g (s, c)))
 
 __STRING_INLINE char *
-__strchr_g (__const char *__s, int __c)
+__strchr_c (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("movb	%%al,%%ah\n"
-     "1:\n\t"
+    ("1:\n\t"
      "movb	(%0),%%al\n\t"
      "cmpb	%%ah,%%al\n\t"
      "je	2f\n\t"
@@ -532,11 +815,12 @@ __strchr_g (__const char *__s, int __c)
 }
 
 __STRING_INLINE char *
-__strchr_c (__const char *__s, int __c)
+__strchr_g (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("1:\n\t"
+    ("movb	%%al,%%ah\n"
+     "1:\n\t"
      "movb	(%0),%%al\n\t"
      "cmpb	%%ah,%%al\n\t"
      "je	2f\n\t"
@@ -553,18 +837,56 @@ __strchr_c (__const char *__s, int __c)
 
 
 /* Find the last occurrence of C in S.  */
+#define _HAVE_STRING_ARCH_strrchr 1
 #define strrchr(s, c) \
   (__extension__ (__builtin_constant_p (c)				      \
 		  ? __strrchr_c (s, ((c) & 0xff) << 8)			      \
 		  : __strrchr_g (s, c)))
 
+#ifdef __i686__
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "cmovne	%%esi,%0\n\t"
+     "testb	%%al,%%al\n\t"
+     "jne 1b"
+     : "=d" (__res)
+     : "0" (1), "S" (__s),"a" (__c)
+     : "ax", "si", "cc");
+  return __res - 1;
+}
+
 __STRING_INLINE char *
 __strrchr_g (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t"
-     "movb	%%al,%%ah\n"
+    ("movb	%%al,%%ah\n"
+     "cld\n\t"
+     "1:\n\t"
+     "lodsb\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "cmovne	%%esi,%0\n\t"
+     "testb	%%al,%%al\n\t"
+     "jne 1b"
+     : "=r" (__res)
+     : "0" (1), "S" (__s),"a" (__c)
+     : "ax", "si", "cc");
+  return __res - 1;
+}
+#else
+__STRING_INLINE char *
+__strrchr_c (__const char *__s, int __c)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("cld\n"
      "1:\n\t"
      "lodsb\n\t"
      "cmpb	%%ah,%%al\n\t"
@@ -580,11 +902,12 @@ __strrchr_g (__const char *__s, int __c)
 }
 
 __STRING_INLINE char *
-__strrchr_c (__const char *__s, int __c)
+__strrchr_g (__const char *__s, int __c)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t"
+    ("movb	%%al,%%ah\n"
+     "cld\n\t"
      "1:\n\t"
      "lodsb\n\t"
      "cmpb	%%ah,%%al\n\t"
@@ -593,66 +916,140 @@ __strrchr_c (__const char *__s, int __c)
      "2:\n\t"
      "testb	%%al,%%al\n\t"
      "jne 1b"
-     : "=d" (__res)
+     : "=r" (__res)
      : "0" (0), "S" (__s),"a" (__c)
      : "ax", "si", "cc");
   return __res;
 }
+#endif
 
 
 /* Return the length of the initial segment of S which
    consists entirely of characters not in REJECT.  */
-#ifdef __PIC__
+#define _HAVE_STRING_ARCH_strcspn 1
+#define strcspn(s, reject) \
+  (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1  \
+		  ? ((reject)[0] == '\0'				      \
+		     ? strlen (s)					      \
+		     : ((reject)[1] == '\0'				      \
+			? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00))     \
+			: __strcspn_cg (s, reject, strlen (reject))))	      \
+		  : __strcspn_g (s, reject)))
+
 __STRING_INLINE size_t
-strcspn (__const char *__s, __const char *__reject)
+__strcspn_c1 (__const char *__s, int __reject)
 {
   register char *__res;
   __asm__ __volatile__
-    ("push	%%ebx\n\t"
-     "cld\n\t"
+    ("1:\n\t"
+     "movb	(%0),%%al\n\t"
+     "leal	1(%0),%0\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "je	2f\n\t"
+     "testb	%%al,%%al\n\t"
+     "jne	1b\n"
+     "2:"
+     : "=r" (__res)
+     : "a" (__reject), "0" (__s)
+     : "ax", "cc");
+  return (__res - 1) - __s;
+}
+
+#ifdef __PIC__
+__STRING_INLINE size_t
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
      "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n"
+     "2:\n\t"
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=&m" (__mem)
+     : "c" (__reject_len), "0" (__s), "r" (__reject), "1" (__mem)
+     : "ax", "cx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%5,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "leal	-1(%%ecx),%%ebx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%5,%%edi\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n"
      "2:\n\t"
-     "popl	%%ebx"
-     : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=&m" (__mem)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject), "1" (__mem)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
 #else
 __STRING_INLINE size_t
-strcspn (__const char *__s, __const char *__reject)
+__strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
 {
-  register char *__res;
+  register __const char *__res;
+  __asm__ __volatile__
+    ("cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n"
+     "2:"
+     : "=S" (__res)
+     : "d" (__reject_len), "0" (__s), "b" (__reject)
+     : "ax", "cx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strcspn_g (__const char *__s, __const char *__reject)
+{
+  register __const char *__res;
   __asm__ __volatile__
     ("cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%edx\n"
+     "leal	-1(%%ecx),%%edx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n"
      "2:"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__reject)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__reject), "D" (__reject)
      : "ax", "cx", "dx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -661,57 +1058,129 @@ strcspn (__const char *__s, __const char *__reject)
 
 /* Return the length of the initial segment of S which
    consists entirely of characters in ACCEPT.  */
-#ifdef __PIC__
+#define _HAVE_STRING_ARCH_strspn 1
+#define strspn(s, accept) \
+  (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
+		  ? ((accept)[0] == '\0'				      \
+		     ? 0						      \
+		     : ((accept)[1] == '\0'				      \
+			? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00))     \
+			: __strspn_cg (s, accept, strlen (accept))))	      \
+		  : __strspn_g (s, accept)))
+
 __STRING_INLINE size_t
-strspn (__const char *__s, __const char *__accept)
+__strspn_c1 (__const char *__s, int __accept)
 {
   register char *__res;
+  /* Please note that __accept never can be '\0'.  */
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
+    ("1:\n\t"
+     "movb	(%0),%%al\n\t"
+     "leal	1(%0),%0\n\t"
+     "cmpb	%%ah,%%al\n\t"
+     "je	1b\n"
+     "2:"
+     : "=r" (__res)
+     : "a" (__accept), "0" (__s)
+     : "ax", "cc");
+  return (__res - 1) - __s;
+}
+
+#ifdef __PIC__
+__STRING_INLINE size_t
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%edx,%%edi\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "je	1b\n"
+     "2:\n\t"
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+     : "ax", "cx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+  register __const char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
      "cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "leal	-1(%%ecx),%%ebx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%edx,%%edi\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repne; scasb\n\t"
      "je	1b\n"
      "2:\n\t"
-     "popl	%%ebx"
-     : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "d" (__accept), "1" (__mem),
+       "D" (__accept)
      : "ax", "cx", "di", "cc");
   return (__res - 1) - __s;
 }
 #else
 __STRING_INLINE size_t
-strspn (__const char *__s, __const char *__accept)
+__strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
-  register char *__res;
+  register __const char *__res;
+  __asm__ __volatile__
+    ("cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "je	1b\n"
+     "2:"
+     : "=S" (__res)
+     : "d" (__accept_len), "0" (__s), "b" (__accept), "D" (__accept)
+     : "ax", "cx", "dx", "di", "cc");
+  return (__res - 1) - __s;
+}
+
+__STRING_INLINE size_t
+__strspn_g (__const char *__s, __const char *__accept)
+{
+  register __const char *__res;
   __asm__ __volatile__
     ("cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%edx\n"
+     "leal	-1(%%ecx),%%edx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repne; scasb\n\t"
      "je	1b\n"
      "2:"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__accept), "D" (__accept)
      : "ax", "cx", "dx", "di", "cc");
   return (__res - 1) - __s;
 }
@@ -719,24 +1188,63 @@ strspn (__const char *__s, __const char *__accept)
 
 
 /* Find the first occurrence in S of any character in ACCEPT.  */
+#define _HAVE_STRING_ARCH_strpbrk 1
+#define strpbrk(s, accept) \
+  (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
+		  ? ((accept)[0] == '\0'				      \
+		     ? NULL						      \
+		     : ((accept)[1] == '\0'				      \
+			? strchr (s, (accept)[0])			      \
+			: __strpbrk_cg (s, accept, strlen (accept))))	      \
+		  : __strpbrk_g (s, accept)))
+
 #ifdef __PIC__
 __STRING_INLINE char *
-strpbrk (__const char *__s, __const char *__accept)
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
   register char *__res;
+  int __mem;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%edx,%%edi\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n\t"
+     "decl	%0\n\t"
+     "jmp	3f\n"
+     "2:\n\t"
+     "xorl	%0,%0\n"
+     "3:\n\t"
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "c" (__accept_len), "0" (__s), "d" (__accept), "1" (__mem)
+     : "ax", "cx", "di", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+  register char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%edx,%%edi\n\t"
      "cld\n\t"
-     "movl	%4,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "leal	-1(%%ecx),%%ebx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%edx,%%edi\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n\t"
@@ -745,29 +1253,54 @@ strpbrk (__const char *__s, __const char *__accept)
      "2:\n\t"
      "xorl	%0,%0\n"
      "3:\n\t"
-     "popl	%%ebx"
-     : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     "movl	%1,%%ebx"
+     : "=S" (__res), "=m" (__mem)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "d" (__accept), "1" (__mem)
      : "ax", "cx", "di", "cc");
   return __res;
 }
 #else
 __STRING_INLINE char *
-strpbrk (__const char *__s, __const char *__accept)
+__strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t"
-     "movl	%4,%%edi\n\t"
+    ("movl	%%ebx,%%edi\n\t"
+     "cld\n"
+     "1:\n\t"
+     "lodsb\n\t"
+     "testb	%%al,%%al\n\t"
+     "je	2f\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repne; scasb\n\t"
+     "jne	1b\n\t"
+     "decl	%0\n\t"
+     "jmp	3f\n"
+     "2:\n\t"
+     "xorl	%0,%0\n"
+     "3:"
+     : "=S" (__res)
+     : "d" (__accept_len), "0" (__s), "b" (__accept)
+     : "ax", "cx", "dx", "di", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strpbrk_g (__const char *__s, __const char *__accept)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("movl	%%ebx,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
-     "decl	%%ecx\n\t"
-     "movl	%%ecx,%%edx\n"
+     "leal	-1(%%ecx),%%edx\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n\t"
@@ -777,7 +1310,7 @@ strpbrk (__const char *__s, __const char *__accept)
      "xorl	%0,%0\n"
      "3:"
      : "=S" (__res)
-     : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
+     : "a" (0), "c" (0xffffffff), "0" (__s), "b" (__accept)
      : "ax", "cx", "dx", "di", "cc");
   return __res;
 }
@@ -785,63 +1318,138 @@ strpbrk (__const char *__s, __const char *__accept)
 
 
 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
+#define _HAVE_STRING_ARCH_strstr 1
 #ifdef __PIC__
+/* XXX GCC has problems to spill the registers.  */
+# define strstr(haystack, needle) \
+  (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
+		  ? ((needle)[0] == '\0'				      \
+		     ? haystack						      \
+		     : ((needle)[1] == '\0'				      \
+			? strchr (haystack, (needle)[0])		     \
+			: strstr (haystack, needle)))			      \
+		  : strstr (haystack, needle)))
+
+# if 0
+/* Please note that this function need not handle NEEDLEs with a
+   length shorter than two.  */
 __STRING_INLINE char *
-strstr (__const char *__haystack, __const char *__needle)
+__strstr_cg (__const char *__haystack, __const char __needle[],
+	     size_t __needle_len)
 {
   register char *__res;
+  int __mem;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
-     "cld\n\t" \
-     "movl	%4,%%edi\n\t"
+    ("movl	%%ebx,%1\n\t"
+     "movl	%%ecx,%%ebx\n"
+     "cld\n" \
+     "1:\n\t"
+     "movl	%%edx,%%edi\n\t"
+     "movl	%%esi,%%eax\n\t"
+     "movl	%%ebx,%%ecx\n\t"
+     "repe; cmpsb\n\t"
+     "je	2f\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
+     "jne	1b\n\t"
+     "xorl	%%eax,%%eax\n"
+     "2:\n\t"
+     "movl	%1,%%ebx"
+     : "=a" (__res), "=m" (__mem)
+     : "c" (__needle_len), "S" (__haystack), "d" (__needle), "1" (__mem)
+     : "cx", "di", "si", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+  register char *__res;
+  int __mem;
+  __asm__ __volatile__
+    ("movl	%2,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
+     "movl	%%ebx,%1\n\t"
      "decl	%%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
      "movl	%%ecx,%%ebx\n"
      "1:\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%edx,%%edi\n\t"
      "movl	%%esi,%%eax\n\t"
      "movl	%%ebx,%%ecx\n\t"
      "repe; cmpsb\n\t"
      "je	2f\n\t"		/* also works for empty string, see above */
-     "xchgl	%%eax,%%esi\n\t"
-     "incl	%%esi\n\t"
-     "cmpb	$0,-1(%%eax)\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
      "jne	1b\n\t"
-     "xorl	%%eax,%%eax\n\t"
+     "xorl	%%eax,%%eax\n"
      "2:\n\t"
-     "popl	%%ebx"
-     : "=a" (__res)
-     : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+     "movl	%1,%%ebx"
+     : "=a" (__res), "=&m" (__mem)
+     : "0" (0), "c" (0xffffffff), "S" (__haystack), "d" (__needle), "1" (__mem)
      : "cx", "di", "si", "cc");
   return __res;
 }
+# endif
 #else
+# define strstr(haystack, needle) \
+  (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
+		  ? ((needle)[0] == '\0'				      \
+		     ? haystack						      \
+		     : ((needle)[1] == '\0'				      \
+			? strchr (haystack, (needle)[0]) 		      \
+			: __strstr_cg (haystack, needle, strlen (needle))))   \
+		  : __strstr_g (haystack, needle)))
+
 __STRING_INLINE char *
-strstr (__const char *__haystack, __const char *__needle)
+__strstr_cg (__const char *__haystack, __const char __needle[],
+	     size_t __needle_len)
 {
   register char *__res;
   __asm__ __volatile__
-    ("cld\n\t" \
-     "movl	%4,%%edi\n\t"
+    ("cld\n" \
+     "1:\n\t"
+     "movl	%%ebx,%%edi\n\t"
+     "movl	%%esi,%%eax\n\t"
+     "movl	%%edx,%%ecx\n\t"
+     "repe; cmpsb\n\t"
+     "je	2f\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
+     "jne	1b\n\t"
+     "xorl	%%eax,%%eax\n"
+     "2:"
+     : "=a" (__res)
+     : "d" (__needle_len), "S" (__haystack), "b" (__needle)
+     : "cx", "dx", "di", "si", "cc");
+  return __res;
+}
+
+__STRING_INLINE char *
+__strstr_g (__const char *__haystack, __const char *__needle)
+{
+  register char *__res;
+  __asm__ __volatile__
+    ("movl	%1,%%edi\n\t"
+     "cld\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
      "decl	%%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
      "movl	%%ecx,%%edx\n"
      "1:\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%%ebx,%%edi\n\t"
      "movl	%%esi,%%eax\n\t"
      "movl	%%edx,%%ecx\n\t"
      "repe; cmpsb\n\t"
      "je	2f\n\t"		/* also works for empty string, see above */
-     "xchgl	%%eax,%%esi\n\t"
-     "incl	%%esi\n\t"
-     "cmpb	$0,-1(%%eax)\n\t"
+     "cmpb	$0,-1(%%esi)\n\t"
+     "leal	1(%%eax),%%esi\n\t"
      "jne	1b\n\t"
-     "xorl	%%eax,%%eax\n\t"
+     "xorl	%%eax,%%eax\n"
      "2:"
      : "=a" (__res)
-     : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
+     : "0" (0), "c" (0xffffffff), "S" (__haystack), "b" (__needle)
      : "cx", "dx", "di", "si", "cc");
   return __res;
 }
diff --git a/sysdeps/i386/machine-gmon.h b/sysdeps/i386/machine-gmon.h
index 496a57eb84..e1155989d4 100644
--- a/sysdeps/i386/machine-gmon.h
+++ b/sysdeps/i386/machine-gmon.h
@@ -1,4 +1,4 @@
-/* i386-specific implemetation of profiling support.
+/* i386-specific implementation of profiling support.
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -36,6 +36,6 @@ void mcount_internal (u_long frompc, u_long selfpc);
 void mcount_internal (u_long frompc, u_long selfpc)
 
 
-/* Define MCOUNT as empty since we have a the implementation in another
+/* Define MCOUNT as empty since we have the implementation in another
    file.  */
 #define MCOUNT
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
index 454c7385af..0cb6578df6 100644
--- a/sysdeps/i386/memset.c
+++ b/sysdeps/i386/memset.c
@@ -23,6 +23,8 @@
 
 #ifdef	__GNUC__
 
+#undef memset
+
 void *
 memset (void *dstpp, int c, size_t len)
 {
diff --git a/sysdeps/mach/hurd/profil.c b/sysdeps/mach/hurd/profil.c
index d76cc25a3c..365b11bed3 100644
--- a/sysdeps/mach/hurd/profil.c
+++ b/sysdeps/mach/hurd/profil.c
@@ -103,7 +103,7 @@ __profile_frequency (void)
 }
 
 int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 {
   error_t err;
 
@@ -132,6 +132,7 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 
   return err ? __hurd_fail (err) : 0;
 }
+weak_alias (__profil, profil)
 
 /* Fetch PC samples.  This function must be very careful not to depend
    on Hurd threadvar variables.  We arrange that by using a special
diff --git a/sysdeps/posix/defs.c b/sysdeps/posix/defs.c
index bc0d34bf15..b25b9b0fea 100644
--- a/sysdeps/posix/defs.c
+++ b/sysdeps/posix/defs.c
@@ -63,7 +63,7 @@ FILE *__stdio_head = &stdstreams[0];
    to cause _cleanup to be linked in.  */
 
 void
-_cleanup ()
+_cleanup (void)
 {
   __fcloseall ();
 }
diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c
index fa3cf98c74..865bd3fa6a 100644
--- a/sysdeps/posix/getcwd.c
+++ b/sysdeps/posix/getcwd.c
@@ -326,7 +326,7 @@ __getcwd (buf, size)
 	{
 	  size_t namlen = _D_EXACT_NAMLEN (d);
 
-	  if ((size_t) (pathp - path) < namlen)
+	  if ((size_t) (pathp - path) <= namlen)
 	    {
 	      if (buf != NULL)
 		{
diff --git a/sysdeps/posix/pipestream.c b/sysdeps/posix/pipestream.c
index 6041f830e7..31348b8976 100644
--- a/sysdeps/posix/pipestream.c
+++ b/sysdeps/posix/pipestream.c
@@ -41,8 +41,8 @@ struct child
    These all simply call the corresponding
    original function with the original cookie.  */
 
-#define FUNC(type, name, args)						      \
-  static type __CONCAT(child_,name) args __CONCAT(name,decl)		      \
+#define FUNC(type, name, proto, args)					      \
+  static type __CONCAT(child_,name) proto				      \
   {									      \
     struct child *c = (struct child *) cookie;				      \
     {									      \
@@ -51,16 +51,12 @@ struct child
     }									      \
   }
 
-#define readdecl void *cookie; register char *buf; register size_t n;
-FUNC (int, read, (cookie, buf, n))
-#define writedecl void *cookie; register const char *buf; register size_t n;
-FUNC (int, write, (cookie, buf, n))
-#define seekdecl void *cookie; fpos_t *pos; int whence;
-FUNC (int, seek, (cookie, pos, whence))
-#define closedecl void *cookie;
-FUNC (int, close, (cookie))
-#define filenodecl void *cookie;
-FUNC (int, fileno, (cookie))
+FUNC (int, read, (void *cookie, char *buf, size_t n), (cookie, buf, n))
+FUNC (int, write, (void *cookie, const char *buf, size_t n), (cookie, buf, n))
+FUNC (int, seek, (void *cookie, fpos_t *pos, int whence),
+      (cookie, pos, whence))
+FUNC (int, close, (void *cookie), (cookie))
+FUNC (int, fileno, (void *cookie), (cookie))
 
 static const __io_functions child_funcs
   = { child_read, child_write, child_seek, child_close, child_fileno };
diff --git a/sysdeps/posix/profil.c b/sysdeps/posix/profil.c
index a51baf3713..734111efbb 100644
--- a/sysdeps/posix/profil.c
+++ b/sysdeps/posix/profil.c
@@ -60,7 +60,7 @@ profil_count (void *pc)
    disable profiling.  Returns zero on success, -1 on error.  */
 
 int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 {
   static struct sigaction act, oact;
   static struct itimerval timer, otimer;
@@ -103,5 +103,6 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
   timer.it_interval = timer.it_value;
   return setitimer (ITIMER_PROF, &timer, &otimer);
 }
+weak_alias (__profil, profil)
 
 #endif
diff --git a/sysdeps/posix/sleep.c b/sysdeps/posix/sleep.c
index e6d8de45ad..5933be6835 100644
--- a/sysdeps/posix/sleep.c
+++ b/sysdeps/posix/sleep.c
@@ -25,8 +25,7 @@
 /* SIGALRM signal handler for `sleep'.  This does nothing but return,
    but SIG_IGN isn't supposed to break `pause'.  */
 static void
-sleep_handler (sig)
-     int sig;
+sleep_handler (int sig)
 {
   return;
 }
diff --git a/sysdeps/posix/stdio_init.c b/sysdeps/posix/stdio_init.c
index 6847d1fdc9..4dc7028133 100644
--- a/sysdeps/posix/stdio_init.c
+++ b/sysdeps/posix/stdio_init.c
@@ -26,8 +26,7 @@
    If no buffer is allocated, but the bufsize is set,
    the bufsize will be used to allocate the buffer.  */
 void
-__stdio_init_stream (stream)
-     FILE *stream;
+__stdio_init_stream (FILE *stream)
 {
   const int fd = (int) stream->__cookie;
   struct stat statb;
diff --git a/sysdeps/powerpc/Makefile b/sysdeps/powerpc/Makefile
index 0a50956640..3e8f22b573 100644
--- a/sysdeps/powerpc/Makefile
+++ b/sysdeps/powerpc/Makefile
@@ -11,3 +11,21 @@ tests += test-arith test-arithf
 LDLIBS-test-arith = libm
 LDLIBS-test-arithf = libm
 endif
+
+ifeq ($(subdir),gmon)
+sysdep_routines += ppc-mcount
+endif
+
+# On PPC, -fpic works until the GOT contains 2^15 bytes, and possibly
+# more depending on how clever the linker is.  Each GOT entry takes 4 bytes,
+# so that's at least 8192 entries.  Since libc only uses about 1200 entries,
+# we want to use -fpic, because this generates fewer relocs.
+ifeq (yes,$(build-shared))
+CFLAGS-.os = -fpic -fno-common
+endif
+
+# The initfini generation code doesn't work in the presence of -fPIC, so
+# we use -fpic instead which is much better.
+ifeq ($(subdir),csu)
+CFLAGS-initfini.s = -g0 -fpic
+endif
diff --git a/sysdeps/powerpc/add_n.S b/sysdeps/powerpc/add_n.S
new file mode 100644
index 0000000000..2bd59ae4a7
--- /dev/null
+++ b/sysdeps/powerpc/add_n.S
@@ -0,0 +1,68 @@
+/* Add two limb vectors of equal, non-zero length for PowerPC.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+                        mp_size_t size)
+   Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.  */
+
+/* Note on optimisation: This code is optimal for the 601.  Almost every other
+   possible 2-unrolled inner loop will not be.  Also, watch out for the
+   alignment...  */
+
+EALIGN(__mpn_add_n,3,0)
+/* Set up for loop below.  */
+	mtcrf 0x01,%r6
+	srwi. %r7,%r6,1
+	li    %r10,0
+	mtctr %r7
+	bt    31,2f
+
+/* Clear the carry.  */
+	addic %r0,%r0,0
+/* Adjust pointers for loop.  */
+	addi  %r3,%r3,-4
+	addi  %r4,%r4,-4
+	addi  %r5,%r5,-4
+	b     0f
+
+2:	lwz  %r7,0(%r5)
+	lwz  %r6,0(%r4)
+	addc %r6,%r6,%r7
+	stw  %r6,0(%r3)
+        beq  1f
+
+/* The loop.  */
+
+/* Align start of loop to an odd word boundary to guarantee that the
+   last two words can be fetched in one access (for 601).  */
+0:	lwz  %r9,4(%r4)
+	lwz  %r8,4(%r5)
+	lwzu %r6,8(%r4)
+	lwzu %r7,8(%r5)
+	adde %r8,%r9,%r8
+	stw  %r8,4(%r3)
+	adde %r6,%r6,%r7
+	stwu %r6,8(%r3)
+	bdnz 0b
+/* Return the carry.  */
+1:	addze %r3,%r10
+	blr
+END(__mpn_add_n)
diff --git a/sysdeps/powerpc/add_n.s b/sysdeps/powerpc/add_n.s
deleted file mode 100644
index 609f0a502a..0000000000
--- a/sysdeps/powerpc/add_n.s
+++ /dev/null
@@ -1,68 +0,0 @@
- # Add two limb vectors of equal, non-zero length for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_add_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
- #                      mp_size_t size)
- # Calculate s1+s2 and put result in res_ptr; return carry, 0 or 1.
-
- # Note on optimisation: This code is optimal for the 601.  Almost every other
- # possible 2-unrolled inner loop will not be.  Also, watch out for the
- # alignment...
-
-	.align 3
-	.globl __mpn_add_n
-	.type	 __mpn_add_n,@function
-__mpn_add_n:
- # Set up for loop below.
-	mtcrf 0x01,%r6
-	srwi. %r7,%r6,1
-	li    %r10,0
-	mtctr %r7
-	bt    31,2f
-
- # Clear the carry.
-	addic %r0,%r0,0
- # Adjust pointers for loop.
-	addi  %r3,%r3,-4
-	addi  %r4,%r4,-4
-	addi  %r5,%r5,-4
-	b     0f
-
-2:	lwz  %r7,0(%r5)
-	lwz  %r6,0(%r4)
-	addc %r6,%r6,%r7
-	stw  %r6,0(%r3)
-        beq  1f
-
- # The loop.
-
- # Align start of loop to an odd word boundary to guarantee that the
- # last two words can be fetched in one access (for 601).
-0:	lwz  %r9,4(%r4)
-	lwz  %r8,4(%r5)
-	lwzu %r6,8(%r4)
-	lwzu %r7,8(%r5)
-	adde %r8,%r9,%r8
-	stw  %r8,4(%r3)
-	adde %r6,%r6,%r7
-	stwu %r6,8(%r3)
-	bdnz 0b
- # return the carry
-1:	addze %r3,%r10
-	blr
diff --git a/sysdeps/powerpc/addmul_1.S b/sysdeps/powerpc/addmul_1.S
new file mode 100644
index 0000000000..dc762fcc43
--- /dev/null
+++ b/sysdeps/powerpc/addmul_1.S
@@ -0,0 +1,49 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+   Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+                           mp_size_t s1_size, mp_limb_t s2_limb)
+   Calculate res+s1*s2 and put result back in res; return carry.  */
+ENTRY(__mpn_addmul_1)
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,0(%r3)
+	addc	%r8,%r7,%r9
+	addi	%r3,%r3,-4		/* adjust res_ptr */
+	bdz	1f
+
+0:	lwzu	%r0,4(%r4)
+	stwu	%r8,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,4(%r3)
+	addze   %r10,%r10
+	addc    %r8,%r7,%r9
+	bdnz	0b
+
+1:	stw	%r8,4(%r3)
+	addze	%r3,%r10
+	blr
+END(__mpn_addmul_1)
diff --git a/sysdeps/powerpc/addmul_1.s b/sysdeps/powerpc/addmul_1.s
deleted file mode 100644
index cf8fd2a555..0000000000
--- a/sysdeps/powerpc/addmul_1.s
+++ /dev/null
@@ -1,50 +0,0 @@
- # Multiply a limb vector by a single limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_addmul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- #                         mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate res+s1*s2 and put result back in res; return carry.
-
-	.align 2
-	.globl __mpn_addmul_1
-	.type	 __mpn_addmul_1,@function
-__mpn_addmul_1:
-	mtctr	%r5
-
-	lwz	%r0,0(%r4)
-	mullw	%r7,%r0,%r6
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,0(%r3)
-	addc	%r8,%r7,%r9
-	addi	%r3,%r3,-4		# adjust res_ptr
-	bdz	Lend
-
-Loop:	lwzu	%r0,4(%r4)
-	stwu	%r8,4(%r3)
-	mullw	%r8,%r0,%r6
-	adde	%r7,%r8,%r10
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,4(%r3)
-	addze   %r10,%r10
-	addc    %r8,%r7,%r9
-	bdnz	Loop
-
-Lend:	stw	%r8,4(%r3)
-	addze	%r3,%r10
-	blr
diff --git a/sysdeps/powerpc/bsd-_setjmp.S b/sysdeps/powerpc/bsd-_setjmp.S
index ffd90d5bd2..ef31f841c4 100644
--- a/sysdeps/powerpc/bsd-_setjmp.S
+++ b/sysdeps/powerpc/bsd-_setjmp.S
@@ -25,9 +25,5 @@
 
 ENTRY (_setjmp)
 	li %r4,0			/* Set second argument to 0.  */
-#ifdef PIC
-	b __sigsetjmp@plt
-#else
-	b __sigsetjmp
-#endif
+	b JUMPTARGET(__sigsetjmp)
 END (_setjmp)
diff --git a/sysdeps/powerpc/bsd-setjmp.S b/sysdeps/powerpc/bsd-setjmp.S
index f02d7815ed..d26b3fc93e 100644
--- a/sysdeps/powerpc/bsd-setjmp.S
+++ b/sysdeps/powerpc/bsd-setjmp.S
@@ -25,11 +25,7 @@
 
 ENTRY (__setjmp)
 	li %r4,1			/* Set second argument to 1.  */
-#ifdef PIC
-	b __sigsetjmp@plt
-#else
-	b __sigsetjmp
-#endif
+	b JUMPTARGET(__sigsetjmp)
 END (__setjmp)
 
 	.globl setjmp
diff --git a/sysdeps/powerpc/dl-machine.h b/sysdeps/powerpc/dl-machine.h
index 917e4f7970..771b711a14 100644
--- a/sysdeps/powerpc/dl-machine.h
+++ b/sysdeps/powerpc/dl-machine.h
@@ -149,33 +149,34 @@ elf_machine_load_address (void)
 #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. */
+   and then redirect to the address it returns.  It is called
+   from code built in the PLT by elf_machine_runtime_setup.  */
 #define ELF_MACHINE_RUNTIME_TRAMPOLINE asm ("\
 	.section \".text\"
 	.align 2
 	.globl _dl_runtime_resolve
 	.type _dl_runtime_resolve,@function
 _dl_runtime_resolve:
- # We need to save the registers used to pass parameters.
- # We build a stack frame to put them in.
+ # 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 1,-48(1)
-	mflr 0
+	stw 0,12(1)
 	stw 3,16(1)
 	stw 4,20(1)
-	stw 0,52(1)
+ # The code that calls this has put parameters for `fixup' in r12 and r11.
+	mr 3,12
 	stw 5,24(1)
- # We also need to save some of the condition register fields.
-	mfcr 0
+	mr 4,11
 	stw 6,28(1)
+	mflr 0
+ # We also need to save some of the condition register fields.
 	stw 7,32(1)
+	stw 0,52(1)
 	stw 8,36(1)
+	mfcr 0
 	stw 9,40(1)
 	stw 10,44(1)
-	stw 0,12(1)
- # The code that calls this has put parameters for `fixup' in r12 and r11.
-	mr 3,12
-	mr 4,11
+	stw 0,8(1)
 	bl fixup@local
  # 'fixup' returns the address we want to branch to.
 	mtctr 3
@@ -184,20 +185,21 @@ _dl_runtime_resolve:
 	lwz 10,44(1)
 	lwz 9,40(1)
 	mtlr 0
-	lwz 0,12(1)
 	lwz 8,36(1)
+	lwz 0,8(1)
 	lwz 7,32(1)
 	lwz 6,28(1)
 	mtcrf 0xFF,0
 	lwz 5,24(1)
 	lwz 4,20(1)
 	lwz 3,16(1)
+	lwz 0,12(1)
  # ...unwind the stack frame, and jump to the PLT entry we updated.
 	addi 1,1,48
 	bctr
 0:
 	.size	 _dl_runtime_resolve,0b-_dl_runtime_resolve
- # undo '.section text'.
+ # Undo '.section text'.
 	.previous
 ");
 
@@ -213,20 +215,20 @@ asm ("\
 	.type _start,@function
 _start:
  # We start with the following on the stack, from top:
- # argc (4 bytes)
- # arguments for program (terminated by NULL)
- # environment variables (terminated by NULL)
- # arguments for the program loader
+ # argc (4 bytes);
+ # arguments for program (terminated by NULL);
+ # environment variables (terminated by NULL);
+ # arguments for the program loader.
  # FIXME: perhaps this should do the same trick as elf/start.c?
 
  # Call _dl_start with one parameter pointing at argc
-	mr 3,1
+	mr   3,1
  #  (we have to frob the stack pointer a bit to allow room for
  #   _dl_start to save the link register)
-	li 4,0
+	li   4,0
 	addi 1,1,-16
-	stw 4,0(1)
-	bl _dl_start@local
+	stw  4,0(1)
+	bl   _dl_start@local
 
  # Now, we do our main work of calling initialisation procedures.
  # The ELF ABI doesn't say anything about parameters for these,
@@ -234,70 +236,72 @@ _start:
  # Changing these is strongly discouraged (not least because argc is
  # passed by value!).
 
- #  put our GOT pointer in r31
-	bl _GLOBAL_OFFSET_TABLE_-4@local
+ #  Put our GOT pointer in r31,
+	bl   _GLOBAL_OFFSET_TABLE_-4@local
 	mflr 31
- #  the address of _start in r30
-	mr 30,3
- #  &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28
-	lwz 28,_dl_default_scope@got(31)
-	lwz 29,_dl_argc@got(31)
-	lwz 27,_dl_argv@got(31)
+ #  the address of _start in r30,
+	mr   30,3
+ #  &_dl_argc in 29, &_dl_argv in 27, and _dl_default_scope in 28.
+	lwz  28,_dl_default_scope@got(31)
+	lwz  29,_dl_argc@got(31)
+	lwz  27,_dl_argv@got(31)
 0:
- #  call initfunc = _dl_init_next(_dl_default_scope[2])
-	lwz 3,8(28)
-	bl _dl_init_next@plt
- # if initfunc is NULL, we exit the loop
-	mr. 0,3
-	beq 1f
+ #  Set initfunc = _dl_init_next(_dl_default_scope[2])
+	lwz  3,8(28)
+	bl   _dl_init_next@plt
+ # If initfunc is NULL, we exit the loop; otherwise,
+	cmpwi 3,0
+	beq  1f
  # call initfunc(_dl_argc, _dl_argv, _dl_argv+_dl_argc+1)
-	mtlr 0
-	lwz 3,0(29)
-	lwz 4,0(27)
+	mtlr 3
+	lwz  3,0(29)
+	lwz  4,0(27)
 	slwi 5,3,2
-	add 5,4,5
+	add  5,4,5
 	addi 5,5,4
 	blrl
  # and loop.
-	b 0b
+	b    0b
 1:
  # Now, to conform to the ELF ABI, we have to:
- # pass argv (actually _dl_argv) in r4
-	lwz 4,0(27)
- # pass argc (actually _dl_argc) in r3
-	lwz 3,0(29)
- # pass envp (actually _dl_argv+_dl_argc+1) in r5
+ # Pass argc (actually _dl_argc) in r3;
+	lwz  3,0(29)
+ # pass argv (actually _dl_argv) in r4;
+	lwz  4,0(27)
+ # pass envp (actually _dl_argv+_dl_argc+1) in r5;
 	slwi 5,3,2
-	add 5,4,5
-	addi 5,5,4
- # pass the auxilary vector in r6. This is passed just after _envp.
-	addi 6,5,-4
+	add  6,4,5
+	addi 5,6,4
+ # pass the auxilary vector in r6. This is passed to us just after _envp.
 2:	lwzu 0,4(6)
-	cmpwi 1,0,0
-	bne 2b
+	cmpwi 0,0,0
+	bne  2b
 	addi 6,6,4
- # pass a termination function pointer (in this case _dl_fini) in r7
-	lwz 7,_dl_fini@got(31)
- # now, call the start function in r30...
+ # Pass a termination function pointer (in this case _dl_fini) in r7.
+	lwz  7,_dl_fini@got(31)
+ # Now, call the start function in r30...
 	mtctr 30
- # pass the stack pointer in r1 (so far so good), pointing to a NULL value
- # (this lets our startup code distinguish between a program linked statically,
+	lwz  26,_dl_starting_up@got(31)
+ # Pass the stack pointer in r1 (so far so good), pointing to a NULL value.
+ # (This lets our startup code distinguish between a program linked statically,
  # which linux will call with argc on top of the stack which will hopefully
  # never be zero, and a dynamically linked program which will always have
  # a NULL on the top of the stack).
  # Take the opportunity to clear LR, so anyone who accidentally returns
- # from _start gets SEGV.
-	li 0,0
-	stw 0,0(1)
-	mtlr 0
- # and also clear _dl_starting_up
-	lwz 26,_dl_starting_up@got(31)
-	stw 0,0(26)
- # go do it!
+ # from _start gets SEGV.  Also clear the next few words of the stack.
+	li   31,0
+	stw  31,0(1)
+	mtlr 31
+	stw  31,4(1)
+ 	stw  31,8(1)
+	stw  31,12(1)
+ # Clear _dl_starting_up.
+	stw  31,0(26)
+ # Go do it!
 	bctr
 0:
 	.size	 _start,0b-_start
- # undo '.section text'.
+ # Undo '.section text'.
 	.previous
 ");
 
@@ -346,7 +350,7 @@ static ElfW(Addr) _dl_preferred_address = 1
 
 /* We require the address of the PLT entry returned from fixup, not
    the first word of the PLT entry. */
-#define ELF_FIXUP_RETURN_VALUE(map, result)  (&(result))
+#define ELF_FIXUP_RETURN_VALUE(map, result)  ((Elf32_Addr) &(result))
 
 /* Nonzero iff TYPE should not be allowed to resolve to one of
    the main executable's symbols, as for a COPY reloc.  */
@@ -396,7 +400,7 @@ elf_machine_runtime_setup (struct link_map *map, int lazy, int profile)
 {
   if (map->l_info[DT_JMPREL])
     {
-      int i;
+      Elf32_Word i;
       /* Fill in the PLT. Its initial contents are directed to a
 	 function earlier in the PLT which arranges for the dynamic
 	 linker to be called back.  */
@@ -516,10 +520,10 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 {
 #ifndef RTLD_BOOTSTRAP
   const Elf32_Sym *const refsym = sym;
+  extern char **_dl_argv;
 #endif
   Elf32_Word loadbase, finaladdr;
   const int rinfo = ELF32_R_TYPE (reloc->r_info);
-  extern char **_dl_argv;
 
   if (rinfo == R_PPC_NONE)
     return;
@@ -551,9 +555,9 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 		     + reloc->r_addend);
     }
 
-  /* This is an if/else if chain because GCC 2.7.2.[012] turns case
-     statements into non-PIC table lookups.  When a later version
-     comes out that fixes this, this should be changed.  */
+  /* This is still an if/else if chain because GCC uses the GOT to find
+     the table for table-based switch statements, and we haven't set it
+     up yet.  */
   if (rinfo == R_PPC_UADDR32 ||
       rinfo == R_PPC_GLOB_DAT ||
       rinfo == R_PPC_ADDR32 ||
@@ -561,6 +565,7 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     {
       *reloc_addr = finaladdr;
     }
+#ifndef RTLD_BOOTSTRAP
   else if (rinfo == R_PPC_ADDR16_LO)
     {
       *(Elf32_Half*) reloc_addr = finaladdr;
@@ -573,7 +578,6 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
     {
       *(Elf32_Half*) reloc_addr = (finaladdr + 0x8000) >> 16;
     }
-#ifndef RTLD_BOOTSTRAP
   else if (rinfo == R_PPC_REL24)
     {
       Elf32_Sword delta = finaladdr - (Elf32_Word) (char *) reloc_addr;
@@ -693,12 +697,14 @@ elf_machine_rela (struct link_map *map, const Elf32_Rela *reloc,
 #endif
     }
 
+#ifndef RTLD_BOOTSTRAP
   if (rinfo == R_PPC_ADDR16_LO ||
       rinfo == R_PPC_ADDR16_HI ||
       rinfo == R_PPC_ADDR16_HA ||
       rinfo == R_PPC_REL24 ||
       rinfo == R_PPC_ADDR24)
     MODIFIED_CODE_NOQUEUE (reloc_addr);
+#endif
 }
 
 #define ELF_MACHINE_NO_REL 1
diff --git a/sysdeps/powerpc/lshift.S b/sysdeps/powerpc/lshift.S
new file mode 100644
index 0000000000..b1487a1c17
--- /dev/null
+++ b/sysdeps/powerpc/lshift.S
@@ -0,0 +1,123 @@
+/* Shift a limb left, low level routine.
+   Copyright (C) 1996, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
+  			 unsigned int cnt)  */
+
+EALIGN(__mpn_lshift,3,0)
+	mtctr	%r5		# copy size into CTR
+	cmplwi	%cr0,%r5,16	# is size < 16
+	slwi	%r0,%r5,2
+	add	%r7,%r3,%r0	# make r7 point at end of res
+	add	%r4,%r4,%r0	# make r4 point at end of s1
+	lwzu	%r11,-4(%r4)	# load first s1 limb
+	subfic	%r8,%r6,32
+	srw	%r3,%r11,%r8	# compute function return value
+	bge	%cr0,L(big)	# branch if size >= 16
+
+	bdz	L(end1)
+
+0:	lwzu	%r10,-4(%r4)
+	slw	%r9,%r11,%r6
+	srw	%r12,%r10,%r8
+	or	%r9,%r9,%r12
+	stwu	%r9,-4(%r7)
+	bdz	L(end2)
+	lwzu	%r11,-4(%r4)
+	slw	%r9,%r10,%r6
+	srw	%r12,%r11,%r8
+	or	%r9,%r9,%r12
+	stwu	%r9,-4(%r7)
+	bdnz	0b
+
+L(end1):slw	%r0,%r11,%r6
+	stw	%r0,-4(%r7)
+	blr
+
+
+/* Guaranteed not to succeed.  */
+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
+	bltl-   %cr0,L(boom)	# Never taken, only used to set LR.
+	slwi    %r10,%r6,4
+	mflr    %r12
+	add     %r10,%r12,%r10
+	slwi	%r8,%r6,5
+	add     %r10,%r8,%r10
+	mtctr   %r10
+	addi	%r5,%r5,-1
+	mtlr    %r9
+	bctr
+
+L(end2):slw	%r0,%r10,%r6
+	stw	%r0,-4(%r7)
+	blr
+
+#define DO_LSHIFT(n) \
+	mtctr	%r5;							\
+0:	lwzu	%r10,-4(%r4);						\
+	slwi	%r9,%r11,n;						\
+	inslwi	%r9,%r10,n,32-n;					\
+	stwu	%r9,-4(%r7);						\
+	bdz-	L(end2);						\
+	lwzu	%r11,-4(%r4);						\
+	slwi	%r9,%r10,n;						\
+	inslwi	%r9,%r11,n,32-n;					\
+	stwu	%r9,-4(%r7);						\
+	bdnz	0b;							\
+	b	L(end1)
+
+	DO_LSHIFT(1)
+	DO_LSHIFT(2)
+	DO_LSHIFT(3)
+	DO_LSHIFT(4)
+	DO_LSHIFT(5)
+	DO_LSHIFT(6)
+	DO_LSHIFT(7)
+	DO_LSHIFT(8)
+	DO_LSHIFT(9)
+	DO_LSHIFT(10)
+	DO_LSHIFT(11)
+	DO_LSHIFT(12)
+	DO_LSHIFT(13)
+	DO_LSHIFT(14)
+	DO_LSHIFT(15)
+	DO_LSHIFT(16)
+	DO_LSHIFT(17)
+	DO_LSHIFT(18)
+	DO_LSHIFT(19)
+	DO_LSHIFT(20)
+	DO_LSHIFT(21)
+	DO_LSHIFT(22)
+	DO_LSHIFT(23)
+	DO_LSHIFT(24)
+	DO_LSHIFT(25)
+	DO_LSHIFT(26)
+	DO_LSHIFT(27)
+	DO_LSHIFT(28)
+	DO_LSHIFT(29)
+	DO_LSHIFT(30)
+	DO_LSHIFT(31)
+
+END(__mpn_lshift)
diff --git a/sysdeps/powerpc/lshift.s b/sysdeps/powerpc/lshift.s
deleted file mode 100644
index 9612a3dbec..0000000000
--- a/sysdeps/powerpc/lshift.s
+++ /dev/null
@@ -1,479 +0,0 @@
- # Shift a limb left, low level routine.
- # Copyright (C) 1996, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_lshift (mp_ptr wp, mp_srcptr up, mp_size_t usize,
- #			 unsigned int cnt)
-
-	.align 3
-	.globl __mpn_lshift
-	.type	 __mpn_lshift,@function
-__mpn_lshift:
-	mtctr	%r5		# copy size into CTR
-	cmplwi	%cr0,%r5,16	# is size < 16
-	slwi	%r0,%r5,2
-	add	%r7,%r3,%r0	# make r7 point at end of res
-	add	%r4,%r4,%r0	# make r4 point at end of s1
-	lwzu	%r11,-4(%r4)	# load first s1 limb
-	subfic	%r8,%r6,32
-	srw	%r3,%r11,%r8	# compute function return value
-	bge	%cr0,Lbig	# branch if size >= 16
-
-	bdz	Lend1
-
-Loop:	lwzu	%r10,-4(%r4)
-	slw	%r9,%r11,%r6
-	srw	%r12,%r10,%r8
-	or	%r9,%r9,%r12
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slw	%r9,%r10,%r6
-	srw	%r12,%r11,%r8
-	or	%r9,%r9,%r12
-	stwu	%r9,-4(%r7)
-	bdnz	Loop
-	b	Lend1
-
- # Guaranteed not to succeed.
-LBoom:	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.
-Lbig:	mflr    %r9
-	bltl    %cr0,LBoom      # Never taken, only used to set LR.
-	slwi    %r10,%r6,4
-	mflr    %r12
-	add     %r10,%r12,%r10
-	slwi	%r8,%r6,5
-	add     %r10,%r8,%r10
-	mtctr   %r10
-	addi	%r5,%r5,-1
-	mtlr    %r9
-	bctr
-
-Lend1:	slw	%r0,%r11,%r6
-	stw	%r0,-4(%r7)
-	blr
-
-	mtctr	%r5
-Loop1:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,1
-	inslwi	%r9,%r10,1,31
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,1
-	inslwi	%r9,%r11,1,31
-	stwu	%r9,-4(%r7)
-	bdnz	Loop1
-	b	Lend1
-
-	mtctr	%r5
-Loop2:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,2
-	inslwi	%r9,%r10,2,30
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,2
-	inslwi	%r9,%r11,2,30
-	stwu	%r9,-4(%r7)
-	bdnz	Loop2
-	b	Lend1
-
-	mtctr	%r5
-Loop3:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,3
-	inslwi	%r9,%r10,3,29
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,3
-	inslwi	%r9,%r11,3,29
-	stwu	%r9,-4(%r7)
-	bdnz	Loop3
-	b	Lend1
-
-	mtctr	%r5
-Loop4:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,4
-	inslwi	%r9,%r10,4,28
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,4
-	inslwi	%r9,%r11,4,28
-	stwu	%r9,-4(%r7)
-	bdnz	Loop4
-	b	Lend1
-
-	mtctr	%r5
-Loop5:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,5
-	inslwi	%r9,%r10,5,27
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,5
-	inslwi	%r9,%r11,5,27
-	stwu	%r9,-4(%r7)
-	bdnz	Loop5
-	b	Lend1
-
-	mtctr	%r5
-Loop6:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,6
-	inslwi	%r9,%r10,6,26
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,6
-	inslwi	%r9,%r11,6,26
-	stwu	%r9,-4(%r7)
-	bdnz	Loop6
-	b	Lend1
-
-	mtctr	%r5
-Loop7:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,7
-	inslwi	%r9,%r10,7,25
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,7
-	inslwi	%r9,%r11,7,25
-	stwu	%r9,-4(%r7)
-	bdnz	Loop7
-	b	Lend1
-
-	mtctr	%r5
-Loop8:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,8
-	inslwi	%r9,%r10,8,24
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,8
-	inslwi	%r9,%r11,8,24
-	stwu	%r9,-4(%r7)
-	bdnz	Loop8
-	b	Lend1
-
-	mtctr	%r5
-Loop9:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,9
-	inslwi	%r9,%r10,9,23
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,9
-	inslwi	%r9,%r11,9,23
-	stwu	%r9,-4(%r7)
-	bdnz	Loop9
-	b	Lend1
-
-	mtctr	%r5
-Loop10:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,10
-	inslwi	%r9,%r10,10,22
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,10
-	inslwi	%r9,%r11,10,22
-	stwu	%r9,-4(%r7)
-	bdnz	Loop10
-	b	Lend1
-
-	mtctr	%r5
-Loop11:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,11
-	inslwi	%r9,%r10,11,21
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,11
-	inslwi	%r9,%r11,11,21
-	stwu	%r9,-4(%r7)
-	bdnz	Loop11
-	b	Lend1
-
-	mtctr	%r5
-Loop12:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,12
-	inslwi	%r9,%r10,12,20
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,12
-	inslwi	%r9,%r11,12,20
-	stwu	%r9,-4(%r7)
-	bdnz	Loop12
-	b	Lend1
-
-	mtctr	%r5
-Loop13:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,13
-	inslwi	%r9,%r10,13,19
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,13
-	inslwi	%r9,%r11,13,19
-	stwu	%r9,-4(%r7)
-	bdnz	Loop13
-	b	Lend1
-
-	mtctr	%r5
-Loop14:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,14
-	inslwi	%r9,%r10,14,18
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,14
-	inslwi	%r9,%r11,14,18
-	stwu	%r9,-4(%r7)
-	bdnz	Loop14
-	b	Lend1
-
-	mtctr	%r5
-Loop15:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,15
-	inslwi	%r9,%r10,15,17
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,15
-	inslwi	%r9,%r11,15,17
-	stwu	%r9,-4(%r7)
-	bdnz	Loop15
-	b	Lend1
-
-	mtctr	%r5
-Loop16:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,16
-	inslwi	%r9,%r10,16,16
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,16
-	inslwi	%r9,%r11,16,16
-	stwu	%r9,-4(%r7)
-	bdnz	Loop16
-	b	Lend1
-
-	mtctr	%r5
-Loop17:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,17
-	inslwi	%r9,%r10,17,15
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,17
-	inslwi	%r9,%r11,17,15
-	stwu	%r9,-4(%r7)
-	bdnz	Loop17
-	b	Lend1
-
-	mtctr	%r5
-Loop18:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,18
-	inslwi	%r9,%r10,18,14
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,18
-	inslwi	%r9,%r11,18,14
-	stwu	%r9,-4(%r7)
-	bdnz	Loop18
-	b	Lend1
-
-	mtctr	%r5
-Loop19:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,19
-	inslwi	%r9,%r10,19,13
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,19
-	inslwi	%r9,%r11,19,13
-	stwu	%r9,-4(%r7)
-	bdnz	Loop19
-	b	Lend1
-
-	mtctr	%r5
-Loop20:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,20
-	inslwi	%r9,%r10,20,12
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,20
-	inslwi	%r9,%r11,20,12
-	stwu	%r9,-4(%r7)
-	bdnz	Loop20
-	b	Lend1
-
-	mtctr	%r5
-Loop21:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,21
-	inslwi	%r9,%r10,21,11
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,21
-	inslwi	%r9,%r11,21,11
-	stwu	%r9,-4(%r7)
-	bdnz	Loop21
-	b	Lend1
-
-	mtctr	%r5
-Loop22:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,22
-	inslwi	%r9,%r10,22,10
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,22
-	inslwi	%r9,%r11,22,10
-	stwu	%r9,-4(%r7)
-	bdnz	Loop22
-	b	Lend1
-
-	mtctr	%r5
-Loop23:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,23
-	inslwi	%r9,%r10,23,9
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,23
-	inslwi	%r9,%r11,23,9
-	stwu	%r9,-4(%r7)
-	bdnz	Loop23
-	b	Lend1
-
-	mtctr	%r5
-Loop24:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,24
-	inslwi	%r9,%r10,24,8
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,24
-	inslwi	%r9,%r11,24,8
-	stwu	%r9,-4(%r7)
-	bdnz	Loop24
-	b	Lend1
-
-	mtctr	%r5
-Loop25:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,25
-	inslwi	%r9,%r10,25,7
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,25
-	inslwi	%r9,%r11,25,7
-	stwu	%r9,-4(%r7)
-	bdnz	Loop25
-	b	Lend1
-
-	mtctr	%r5
-Loop26:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,26
-	inslwi	%r9,%r10,26,6
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,26
-	inslwi	%r9,%r11,26,6
-	stwu	%r9,-4(%r7)
-	bdnz	Loop26
-	b	Lend1
-
-	mtctr	%r5
-Loop27:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,27
-	inslwi	%r9,%r10,27,5
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,27
-	inslwi	%r9,%r11,27,5
-	stwu	%r9,-4(%r7)
-	bdnz	Loop27
-	b	Lend1
-
-	mtctr	%r5
-Loop28:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,28
-	inslwi	%r9,%r10,28,4
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,28
-	inslwi	%r9,%r11,28,4
-	stwu	%r9,-4(%r7)
-	bdnz	Loop28
-	b	Lend1
-
-	mtctr	%r5
-Loop29:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,29
-	inslwi	%r9,%r10,29,3
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,29
-	inslwi	%r9,%r11,29,3
-	stwu	%r9,-4(%r7)
-	bdnz	Loop29
-	b	Lend1
-
-	mtctr	%r5
-Loop30:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,30
-	inslwi	%r9,%r10,30,2
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,30
-	inslwi	%r9,%r11,30,2
-	stwu	%r9,-4(%r7)
-	bdnz	Loop30
-	b	Lend1
-
-	mtctr	%r5
-Loop31:	lwzu	%r10,-4(%r4)
-	slwi	%r9,%r11,31
-	inslwi	%r9,%r10,31,1
-	stwu	%r9,-4(%r7)
-	bdz	Lend2
-	lwzu	%r11,-4(%r4)
-	slwi	%r9,%r10,31
-	inslwi	%r9,%r11,31,1
-	stwu	%r9,-4(%r7)
-	bdnz	Loop31
-	b	Lend1
-
-Lend2:	slw	%r0,%r10,%r6
-	stw	%r0,-4(%r7)
-	blr
diff --git a/sysdeps/unix/sysv/linux/powerpc/_exit.S b/sysdeps/powerpc/machine-gmon.h
index a1ca375d54..ba53807308 100644
--- a/sysdeps/unix/sysv/linux/powerpc/_exit.S
+++ b/sysdeps/powerpc/machine-gmon.h
@@ -1,5 +1,7 @@
-/* Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
+/* PowerPC-specific implementation of profiling support.
+   Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
@@ -16,11 +18,15 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <sysdep.h>
+/* We need a special version of the `mcount' function because it has
+   to preserve more registers than your usual function.  */
 
-/* The 'exit' syscall does not return.  */
+void __mcount_internal (unsigned long frompc, unsigned long selfpc);
 
-	.text
-ENTRY(_exit)
-	DO_CALL (SYS_ify (exit))
-PSEUDO_END (_exit)
+#define _MCOUNT_DECL(frompc, selfpc) \
+void __mcount_internal (unsigned long frompc, unsigned long selfpc)
+
+
+/* Define MCOUNT as empty since we have the implementation in another
+   file.  */
+#define MCOUNT
diff --git a/sysdeps/powerpc/memset.S b/sysdeps/powerpc/memset.S
new file mode 100644
index 0000000000..6ac32ddc99
--- /dev/null
+++ b/sysdeps/powerpc/memset.S
@@ -0,0 +1,199 @@
+/* Optimized memset implementation for PowerPC.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+EALIGN(memset,5,1)
+/* __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
+   Returns 's'.
+
+   The memset is done in three sizes: byte (8 bits), word (32 bits),
+   cache line (256 bits). There is a special case for setting cache lines
+   to 0, to take advantage of the dcbz instruction.
+   r6:	current address we are storing at
+   r7:	number of bytes we are setting now (when aligning)  */
+
+/* take care of case for size <= 4  */
+	cmplwi %cr1,%r5,4
+	andi.  %r7,%r3,3
+	mr     %r6,%r3
+	ble-   %cr1,L(small)
+/* align to word boundary  */
+	cmplwi %cr5,%r5,31
+	rlwimi %r4,%r4,8,16,23
+	beq+   L(aligned)		# 8th instruction from .align
+	mtcrf  0x01,%r3
+	subfic %r7,%r7,4
+	add    %r6,%r6,%r7
+	sub    %r5,%r5,%r7
+	bf+    31,0f
+	stb    %r4,0(%r3)
+	bt     30,L(aligned)
+0:	sth    %r4,-2(%r6)		#  16th instruction from .align
+/* take care of case for size < 31 */
+L(aligned):
+	mtcrf  0x01,%r5
+	rlwimi %r4,%r4,16,0,15
+	ble    %cr5,L(medium)
+/* align to cache line boundary...  */
+	andi.  %r7,%r6,0x1C
+	subfic %r7,%r7,0x20
+	beq    L(caligned)
+	mtcrf  0x01,%r7
+	add    %r6,%r6,%r7
+	sub    %r5,%r5,%r7
+	cmplwi %cr1,%r7,0x10
+	mr     %r8,%r6
+	bf     28,1f
+	stw    %r4,-4(%r8)
+	stwu   %r4,-8(%r8)
+1:	blt    %cr1,2f
+	stw    %r4,-4(%r8)	# 32nd instruction from .align
+	stw    %r4,-8(%r8)
+	stw    %r4,-12(%r8)
+	stwu   %r4,-16(%r8)
+2:	bf     29,L(caligned)
+	stw    %r4,-4(%r8)
+/* now aligned to a cache line.  */
+L(caligned):
+	cmplwi %cr1,%r4,0
+	clrrwi. %r7,%r5,5
+	mtcrf  0x01,%r5		# 40th instruction from .align
+	beq    %cr1,L(zloopstart) # special case for clearing memory using dcbz
+	srwi   %r0,%r7,5
+	mtctr  %r0
+	beq    L(medium)	# we may not actually get to do a full line
+	clrlwi. %r5,%r5,27
+	add    %r6,%r6,%r7
+0:	li     %r8,-0x40
+	bdz    L(cloopdone)	# 48th instruction from .align
+
+3:	dcbz   %r8,%r6
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stw    %r4,-16(%r6)
+	nop			# let 601 fetch last 4 instructions of loop
+	stw    %r4,-20(%r6)
+	stw    %r4,-24(%r6)	# 56th instruction from .align
+	nop			# let 601 fetch first 8 instructions of loop
+	stw    %r4,-28(%r6)
+	stwu   %r4,-32(%r6)
+	bdnz   3b
+L(cloopdone):
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stw    %r4,-16(%r6)	# 64th instruction from .align
+	stw    %r4,-20(%r6)
+	cmplwi %cr1,%r5,16
+	stw    %r4,-24(%r6)
+	stw    %r4,-28(%r6)
+	stwu   %r4,-32(%r6)
+	beqlr
+	add    %r6,%r6,%r7
+	b      L(medium_tail2)	# 72nd instruction from .align
+
+	.align 5
+	nop
+/* Clear lines of memory in 128-byte chunks.  */
+L(zloopstart):
+	clrlwi %r5,%r5,27
+	mtcrf  0x02,%r7
+	srwi.  %r0,%r7,7
+	mtctr  %r0
+	li     %r7,0x20
+	li     %r8,-0x40
+	cmplwi %cr1,%r5,16	# 8
+	bf     26,0f
+	dcbz   0,%r6
+	addi   %r6,%r6,0x20
+0:	li     %r9,-0x20
+	bf     25,1f
+	dcbz   0,%r6
+	dcbz   %r7,%r6
+	addi   %r6,%r6,0x40	# 16
+1:	cmplwi %cr5,%r5,0
+	beq    L(medium)
+L(zloop):
+	dcbz   0,%r6
+	dcbz   %r7,%r6
+	addi   %r6,%r6,0x80
+	dcbz   %r8,%r6
+	dcbz   %r9,%r6
+	bdnz   L(zloop)
+	beqlr  %cr5
+	b      L(medium_tail2)
+
+	.align 5
+L(small):
+/* Memset of 4 bytes or less.  */
+	cmplwi %cr5,%r5,1
+	cmplwi %cr1,%r5,3
+	bltlr  %cr5
+	stb    %r4,0(%r6)
+	beqlr  %cr5
+	nop
+	stb    %r4,1(%r6)
+	bltlr  %cr1
+	stb    %r4,2(%r6)
+	beqlr  %cr1
+	nop
+	stb    %r4,3(%r6)
+	blr
+
+/* Memset of 0-31 bytes.  */
+	.align 5
+L(medium):
+	cmplwi %cr1,%r5,16
+L(medium_tail2):
+	add    %r6,%r6,%r5
+L(medium_tail):
+	bt-    31,L(medium_31t)
+	bt-    30,L(medium_30t)
+L(medium_30f):
+	bt-    29,L(medium_29t)
+L(medium_29f):
+	bge-   %cr1,L(medium_27t)
+	bflr-  28
+	stw    %r4,-4(%r6)		# 8th instruction from .align
+	stw    %r4,-8(%r6)
+	blr
+
+L(medium_31t):
+	stbu   %r4,-1(%r6)
+	bf-    30,L(medium_30f)
+L(medium_30t):
+	sthu   %r4,-2(%r6)
+	bf-    29,L(medium_29f)
+L(medium_29t):
+	stwu   %r4,-4(%r6)
+	blt-   %cr1,L(medium_27f)	# 16th instruction from .align
+L(medium_27t):
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	stw    %r4,-12(%r6)
+	stwu   %r4,-16(%r6)
+L(medium_27f):
+	bflr-  28
+L(medium_28t):
+	stw    %r4,-4(%r6)
+	stw    %r4,-8(%r6)
+	blr
+END(memset)
diff --git a/sysdeps/powerpc/memset.s b/sysdeps/powerpc/memset.s
deleted file mode 100644
index 4c8bf8c6b4..0000000000
--- a/sysdeps/powerpc/memset.s
+++ /dev/null
@@ -1,202 +0,0 @@
- # Optimized memset implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
-	.section ".text"
-	.align 5
-	nop
-	
-	.globl memset
-	.type memset,@function
-memset:	
- # __ptr_t [r3] memset (__ptr_t s [r3], int c [r4], size_t n [r5]));
- # Returns 's'.
-
- # The memset is done in three sizes: byte (8 bits), word (32 bits),
- # cache line (256 bits). There is a special case for setting cache lines
- # to 0, to take advantage of the dcbz instruction.
- # r6:	current address we are storing at
- # r7:	number of bytes we are setting now (when aligning)
-
- # take care of case for size <= 4
-	cmplwi %cr1,%r5,4	
-	andi.  %r7,%r3,3
-	mr     %r6,%r3
-	ble-   %cr1,small
- # align to word boundary
-	cmplwi %cr5,%r5,31
-	rlwimi %r4,%r4,8,16,23
-	beq+   aligned			# 8th instruction from .align
-	mtcrf  0x01,%r3
-	subfic %r7,%r7,4
-	add    %r6,%r6,%r7
-	sub    %r5,%r5,%r7
-	bf+    31,0f
-	stb    %r4,0(%r3)
-	bt     30,aligned
-0:	sth    %r4,-2(%r6)		#  16th instruction from .align
- # take care of case for size < 31
-aligned:
-	mtcrf  0x01,%r5
-	rlwimi %r4,%r4,16,0,15
-	ble    %cr5,medium
- # align to cache line boundary...
-	andi.  %r7,%r6,0x1C
-	subfic %r7,%r7,0x20
-	beq    caligned
-	mtcrf  0x01,%r7
-	add    %r6,%r6,%r7
-	sub    %r5,%r5,%r7
-	cmplwi %cr1,%r7,0x10
-	mr     %r8,%r6
-	bf     28,1f
-	stw    %r4,-4(%r8)
-	stwu   %r4,-8(%r8)
-1:	blt    %cr1,2f
-	stw    %r4,-4(%r8)	# 32nd instruction from .align
-	stw    %r4,-8(%r8)
-	stw    %r4,-12(%r8)
-	stwu   %r4,-16(%r8)
-2:	bf     29,caligned
-	stw    %r4,-4(%r8)
- # now aligned to a cache line.
-caligned:
-	cmplwi %cr1,%r4,0
-	clrrwi. %r7,%r5,5
-	mtcrf  0x01,%r5		# 40th instruction from .align
-	beq    %cr1,zloopstart	# special case for clearing memory using dcbz
-	srwi   %r0,%r7,5
-	mtctr  %r0
-	beq    medium		# we may not actually get to do a full line
-	clrlwi. %r5,%r5,27
-	add    %r6,%r6,%r7
-0:	li     %r8,-0x40
-	bdz    cloopdone	# 48th instruction from .align
-	
-cloop:	dcbz   %r8,%r6
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	stw    %r4,-12(%r6)
-	stw    %r4,-16(%r6)
-	nop			# let 601 fetch last 4 instructions of loop
-	stw    %r4,-20(%r6)
-	stw    %r4,-24(%r6)	# 56th instruction from .align
-	nop			# let 601 fetch first 8 instructions of loop
-	stw    %r4,-28(%r6)
-	stwu   %r4,-32(%r6)
-	bdnz   cloop
-cloopdone:
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	stw    %r4,-12(%r6)
-	stw    %r4,-16(%r6)	# 64th instruction from .align
-	stw    %r4,-20(%r6)
-	cmplwi %cr1,%r5,16
-	stw    %r4,-24(%r6)
-	stw    %r4,-28(%r6)
-	stwu   %r4,-32(%r6)
-	beqlr
-	add    %r6,%r6,%r7
-	b      medium_tail2	# 72nd instruction from .align
-
-	.align 5
-	nop
-# clear lines of memory in 128-byte chunks.
-zloopstart:
-	clrlwi %r5,%r5,27
-	mtcrf  0x02,%r7
-	srwi.  %r0,%r7,7
-	mtctr  %r0
-	li     %r7,0x20
-	li     %r8,-0x40
-	cmplwi %cr1,%r5,16	# 8
-	bf     26,0f	
-	dcbz   0,%r6
-	addi   %r6,%r6,0x20
-0:	li     %r9,-0x20
-	bf     25,1f
-	dcbz   0,%r6
-	dcbz   %r7,%r6
-	addi   %r6,%r6,0x40	# 16
-1:	cmplwi %cr5,%r5,0
-	beq    medium
-zloop:	
-	dcbz   0,%r6
-	dcbz   %r7,%r6
-	addi   %r6,%r6,0x80
-	dcbz   %r8,%r6
-	dcbz   %r9,%r6
-	bdnz   zloop
-	beqlr  %cr5
-	b      medium_tail2
-	
-	.align 5	
-small:
- # Memset of 4 bytes or less.
-	cmplwi %cr5,%r5,1
-	cmplwi %cr1,%r5,3
-	bltlr  %cr5
-	stb    %r4,0(%r6)
-	beqlr  %cr5
-	nop
-	stb    %r4,1(%r6)
-	bltlr  %cr1
-	stb    %r4,2(%r6)
-	beqlr  %cr1
-	nop
-	stb    %r4,3(%r6)
-	blr
-
-# memset of 0-31 bytes
-	.align 5
-medium:
-	cmplwi %cr1,%r5,16
-medium_tail2:
-	add    %r6,%r6,%r5
-medium_tail:
-	bt-    31,medium_31t
-	bt-    30,medium_30t
-medium_30f:
-	bt-    29,medium_29t
-medium_29f:
-	bge-   %cr1,medium_27t
-	bflr-  28
-	stw    %r4,-4(%r6)	# 8th instruction from .align
-	stw    %r4,-8(%r6)
-	blr
-
-medium_31t:	
-	stbu   %r4,-1(%r6)
-	bf-    30,medium_30f
-medium_30t:
-	sthu   %r4,-2(%r6)
-	bf-    29,medium_29f
-medium_29t:
-	stwu   %r4,-4(%r6)
-	blt-   %cr1,medium_27f	# 16th instruction from .align
-medium_27t:
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	stw    %r4,-12(%r6)
-	stwu   %r4,-16(%r6)
-medium_27f:
-	bflr-  28
-medium_28t:
-	stw    %r4,-4(%r6)
-	stw    %r4,-8(%r6)
-	blr
diff --git a/sysdeps/powerpc/mul_1.S b/sysdeps/powerpc/mul_1.S
new file mode 100644
index 0000000000..d48bd8fa19
--- /dev/null
+++ b/sysdeps/powerpc/mul_1.S
@@ -0,0 +1,46 @@
+/* Multiply a limb vector by a limb, for PowerPC.
+   Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+                        mp_size_t s1_size, mp_limb_t s2_limb)
+   Calculate s1*s2 and put result in res_ptr; return carry.  */
+
+ENTRY(__mpn_mul_1)
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	addi	%r3,%r3,-4		# adjust res_ptr
+	addic	%r5,%r5,0		# clear cy with dummy insn
+	bdz	1f
+
+0:	lwzu	%r0,4(%r4)
+	stwu	%r7,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	bdnz	0b
+
+1:	stw	%r7,4(%r3)
+	addze	%r3,%r10
+	blr
+END(__mpn_mul_1)
diff --git a/sysdeps/powerpc/mul_1.s b/sysdeps/powerpc/mul_1.s
deleted file mode 100644
index d6eb623bd4..0000000000
--- a/sysdeps/powerpc/mul_1.s
+++ /dev/null
@@ -1,47 +0,0 @@
- # Multiply a limb vector by a limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_mul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- #                      mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate s1*s2 and put result in res_ptr; return carry.
-
-	.align 2
-	.globl __mpn_mul_1
-	.type	 __mpn_mul_1,@function
-
-__mpn_mul_1:
-	mtctr	%r5
-
-	lwz	%r0,0(%r4)
-	mullw	%r7,%r0,%r6
-	mulhwu	%r10,%r0,%r6
-	addi	%r3,%r3,-4		# adjust res_ptr
-	addic	%r5,%r5,0		# clear cy with dummy insn
-	bdz	Lend
-
-Loop:	lwzu	%r0,4(%r4)
-	stwu	%r7,4(%r3)
-	mullw	%r8,%r0,%r6
-	adde	%r7,%r8,%r10
-	mulhwu	%r10,%r0,%r6
-	bdnz	Loop
-
-Lend:	stw	%r7,4(%r3)
-	addze	%r3,%r10
-	blr
diff --git a/sysdeps/powerpc/ppc-mcount.S b/sysdeps/powerpc/ppc-mcount.S
new file mode 100644
index 0000000000..06f1fcda12
--- /dev/null
+++ b/sysdeps/powerpc/ppc-mcount.S
@@ -0,0 +1,84 @@
+/* PowerPC-specific implementation of profiling support.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.	*/
+
+/* This would be bad.  */
+#ifdef PROF
+#undef PROF
+#endif
+
+#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).
+
+   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)
+/* We need to save the parameter-passing registers.  */
+	stw	%r3, 12(%r1)
+	stw	%r4, 16(%r1)
+	stw	%r5, 20(%r1)
+	stw	%r6, 24(%r1)
+	mflr	%r4
+	lwz	%r3, 52(%r1)
+	mfcr	%r5
+	stw	%r7, 28(%r1)
+	stw	%r8, 32(%r1)
+	stw	%r9, 36(%r1)
+	stw	%r10,40(%r1)
+	stw	%r4, 44(%r1)
+	stw	%r5,  8(%r1)
+	bl	JUMPTARGET(__mcount_internal)
+ /* Restore the registers...  */
+	lwz     %r6,  8(%r1)
+	lwz	%r0, 44(%r1)
+	lwz	%r3, 12(%r1)
+	mtctr	%r0
+	lwz	%r4, 16(%r1)
+	mtcrf	0xff,%r6
+	lwz	%r5, 20(%r1)
+	lwz	%r6, 24(%r1)
+	lwz	%r0, 52(%r1)
+	lwz	%r7, 28(%r1)
+	lwz	%r8, 32(%r1)
+	mtlr	%r0
+	lwz	%r9, 36(%r1)
+	lwz	%r10,40(%r1)
+ /* ...unwind the stack frame, and return to your usual programming.  */
+	addi	%r1,%r1,48
+	bctr
+END(_mcount)
diff --git a/sysdeps/powerpc/rshift.S b/sysdeps/powerpc/rshift.S
new file mode 100644
index 0000000000..eb1f562bed
--- /dev/null
+++ b/sysdeps/powerpc/rshift.S
@@ -0,0 +1,56 @@
+/* Shift a limb right, low level routine.
+   Copyright (C) 1995, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* INPUT PARAMETERS
+   res_ptr	r3
+   s1_ptr	r4
+   size		r5
+   cnt		r6  */
+
+ENTRY(__mpn_rshift)
+	mtctr	5		# copy size into CTR
+	addi	7,3,-4		# move adjusted res_ptr to free return reg
+	subfic	8,6,32
+	lwz	11,0(4)		# load first s1 limb
+	slw	3,11,8		# compute function return value
+	bdz	1f
+
+0:	lwzu	10,4(4)
+	srw	9,11,6
+	slw	12,10,8
+	or	9,9,12
+	stwu	9,4(7)
+	bdz	2f
+	lwzu	11,4(4)
+	srw	9,10,6
+	slw	12,11,8
+	or	9,9,12
+	stwu	9,4(7)
+	bdnz	0b
+
+1:	srw	0,11,6
+	stw	0,4(7)
+	blr
+
+2:	srw	0,10,6
+	stw	0,4(7)
+	blr
+END(__mpn_rshift)
diff --git a/sysdeps/powerpc/rshift.s b/sysdeps/powerpc/rshift.s
deleted file mode 100644
index 20f09ad86a..0000000000
--- a/sysdeps/powerpc/rshift.s
+++ /dev/null
@@ -1,59 +0,0 @@
-# PowerPC-32 __mpn_rshift --
-
-# Copyright (C) 1995 Free Software Foundation, Inc.
-
-# This file is part of the GNU MP Library.
-
-# The GNU MP Library is free software; you can redistribute it and/or modify
-# it under the terms of the GNU Library General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or (at your
-# option) any later version.
-
-# The GNU MP 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 Library General Public
-# License for more details.
-
-# You should have received a copy of the GNU Library General Public License
-# along with the GNU MP Library; see the file COPYING.LIB.  If not, write to
-# the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
-# MA 02111-1307, USA.
-
-
-# INPUT PARAMETERS
-# res_ptr	r3
-# s1_ptr	r4
-# size		r5
-# cnt		r6
-
-	.align 3
-	.globl __mpn_rshift
-	.type	 __mpn_rshift,@function
-__mpn_rshift:
-	mtctr	5		# copy size into CTR
-	addi	7,3,-4		# move adjusted res_ptr to free return reg
-	subfic	8,6,32
-	lwz	11,0(4)		# load first s1 limb
-	slw	3,11,8		# compute function return value
-	bdz	Lend1
-
-Loop:	lwzu	10,4(4)
-	srw	9,11,6
-	slw	12,10,8
-	or	9,9,12
-	stwu	9,4(7)
-	bdz	Lend2
-	lwzu	11,4(4)
-	srw	9,10,6
-	slw	12,11,8
-	or	9,9,12
-	stwu	9,4(7)
-	bdnz	Loop
-
-Lend1:	srw	0,11,6
-	stw	0,4(7)
-	blr
-
-Lend2:	srw	0,10,6
-	stw	0,4(7)
-	blr
diff --git a/sysdeps/powerpc/s_copysign.S b/sysdeps/powerpc/s_copysign.S
index adc7df226a..6d5ba82592 100644
--- a/sysdeps/powerpc/s_copysign.S
+++ b/sysdeps/powerpc/s_copysign.S
@@ -1,17 +1,17 @@
 /* Copy a sign bit between floating-point values.
    Copyright (C) 1997 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 Library General Public License as
    published by the Free Software Foundation; either version 2 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
    Library General Public License for more details.
-  
+
    You should have received a copy of the GNU Library General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
@@ -20,15 +20,12 @@
 /* This has been coded in assembler because GCC makes such a mess of it
    when it's coded in C.  */
 
-	.section ".text"
-	.align 2
-	.globl __copysign
-	.type __copysign,@function
-__copysign:	
+#include <sysdep.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)
 	stfd	%f2,8(%r1)
 	lwz	%r3,8(%r1)
@@ -39,22 +36,15 @@ __copysign:
 	blr
 0:	fnabs   %f1,%f1
 	blr
-0:
-	.size	 __copysign,0b-__copysign
-	
-	.globl copysign
-	.globl copysignf
-	.globl __copysignf
-	.weak copysign
-	.weak copysignf
-	.set copysign,__copysign
+	END (__copysign)
+
+weak_alias(__copysign,copysign)
+
 /* It turns out that it's safe to use this code even for single-precision.  */
-	.set __copysignf,__copysign
-	.set copysignf,__copysign
+weak_alias(__copysign,copysignf)
+strong_alias(__copysign,__copysignf)
+
 #ifdef NO_LONG_DOUBLE
-	.globl copysignl
-	.globl __copysignl
-	.weak copysignl
-	.set __copysignl,__copysign
-	.set copysignl,__copysign
+weak_alias(__copysign,copysignl)
+strong_alias(__copysign,__copysignl)
 #endif
diff --git a/sysdeps/powerpc/s_fabs.S b/sysdeps/powerpc/s_fabs.S
index a52733568d..3c6374b0aa 100644
--- a/sysdeps/powerpc/s_fabs.S
+++ b/sysdeps/powerpc/s_fabs.S
@@ -1,42 +1,37 @@
 /* Floating-point absolute value.  PowerPC version.
    Copyright (C) 1997 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 Library General Public License as
    published by the Free Software Foundation; either version 2 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
    Library General Public License for more details.
-  
+
    You should have received a copy of the GNU Library General Public
    License along with the GNU C Library; see the file COPYING.LIB.  If not,
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-	.section ".text"
-	.align 2
-	.globl __fabs
-	.type __fabs,@function
-__fabs:	
+#include <sysdep.h>
+
+ENTRY(__fabs)
 /* double [f1] fabs (double [f1] x); */
 	fabs %f1,%f1
 	blr
-0:
-	.size	 __fabs,0b-__fabs
+END(__fabs)
+
+weak_alias(__fabs,fabs)
 
-	.globl fabs,fabsf,__fabsf
-	.weak fabs,fabsf
-	.set fabs,__fabs
 /* It turns out that it's safe to use this code even for single-precision.  */
-	.set __fabsf,__fabs
-	.set fabsf,__fabs
+strong_alias(__fabs,__fabsf)
+weak_alias(__fabs,fabsf)
+
 #ifdef NO_LONG_DOUBLE
-	.globl fabsl,__fabsl
-	.weak fabsl
-	.set __fabsl,__fabs
-	.set fabsl,__fabs
+weak_alias(__fabs,__fabsl)
+weak_alias(__fabs,fabsl)
 #endif
diff --git a/sysdeps/powerpc/setjmp.S b/sysdeps/powerpc/setjmp.S
index ddfea7eed3..8fa863f161 100644
--- a/sysdeps/powerpc/setjmp.S
+++ b/sysdeps/powerpc/setjmp.S
@@ -62,9 +62,5 @@ ENTRY (__sigsetjmp)
 	stfd %f30,((JB_FPRS+16*2)*4)(3)
 	stw  %r31,((JB_GPRS+17)*4)(3)
 	stfd %f31,((JB_FPRS+17*2)*4)(3)
-#ifdef PIC
-	b __sigjmp_save@plt
-#else
-	b __sigjmp_save
-#endif
+	b JUMPTARGET(__sigjmp_save)
 END (__sigsetjmp)
diff --git a/sysdeps/powerpc/strchr.S b/sysdeps/powerpc/strchr.S
new file mode 100644
index 0000000000..156d4d155c
--- /dev/null
+++ b/sysdeps/powerpc/strchr.S
@@ -0,0 +1,111 @@
+/* Optimized strchr implementation for PowerPC.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* See strlen.s for comments on how this works.  */
+
+/* char * [r3] strchr (const char *s [r3] , int c [r4] )
+
+   r0:	a temporary
+   r3:	our return result.
+   r4:	byte we're looking for, spread over the whole word
+   r5:	the current word
+   r6:	the constant 0xfefefeff (-0x01010101)
+   r7:	the constant 0x7f7f7f7f
+   r8:	pointer to the current word.
+   r9:	a temporary
+   r10:	the number of bits we should ignore in the first word
+   r11:	a mask with the bits to ignore set to 0
+   r12:	a temporary  */
+ENTRY(strchr)
+	rlwimi %r4,%r4,8,16,23
+	li   %r11,-1
+	rlwimi %r4,%r4,16,0,15
+	lis  %r6,0xfeff
+	lis  %r7,0x7f7f
+	clrrwi %r8,%r3,2
+	addi %r7,%r7,0x7f7f
+	addi %r6,%r6,0xfffffeff
+	rlwinm %r10,%r3,3,27,28
+/* Test the first (partial?) word.  */
+	lwz  %r5,0(%r8)
+	srw  %r11,%r11,%r10
+	orc  %r5,%r5,%r11
+	add  %r0,%r6,%r5
+	nor  %r9,%r7,%r5
+	and. %r0,%r0,%r9
+	xor  %r12,%r4,%r5
+	orc  %r12,%r12,%r11
+	b    L(loopentry)
+
+/* The loop.  */
+
+L(loop):lwzu %r5,4(%r8)
+	and. %r0,%r0,%r9
+/* Test for 0.  */
+	add  %r0,%r6,%r5
+	nor  %r9,%r7,%r5
+	bne  L(foundit)
+	and. %r0,%r0,%r9
+/* Start test for the bytes we're looking for.  */
+	xor  %r12,%r4,%r5
+L(loopentry):
+	add  %r0,%r6,%r12
+	nor  %r9,%r7,%r12
+	beq  L(loop)
+/* There is a zero byte in the word, but may also be a matching byte (either
+   before or after the zero byte).  In fact, we may be looking for a
+   zero byte, in which case we return a match.  We guess that this hasn't
+   happened, though.  */
+L(missed):
+	and. %r0,%r0,%r9
+	li   %r3,0
+	beqlr
+/* It did happen. Decide which one was first...
+   I'm not sure if this is actually faster than a sequence of
+   rotates, compares, and branches (we use it anyway because it's shorter).  */
+	and  %r6,%r7,%r5
+	or   %r11,%r7,%r5
+	and  %r0,%r7,%r12
+	or   %r10,%r7,%r12
+	add  %r6,%r6,%r7
+	add  %r0,%r0,%r7
+	nor  %r5,%r11,%r6
+	nor  %r9,%r10,%r0
+	cmplw %r5,%r9
+	bgtlr
+	cntlzw %r4,%r9
+	srwi %r4,%r4,3
+	add  %r3,%r8,%r4
+	blr
+
+L(foundit):
+	and  %r0,%r7,%r12
+	or   %r10,%r7,%r12
+	add  %r0,%r0,%r7
+	nor  %r9,%r10,%r0
+	cntlzw %r4,%r9
+	subi %r8,%r8,4
+	srwi %r4,%r4,3
+	add  %r3,%r8,%r4
+	blr
+END(strchr)
+
+weak_alias(strchr,index)
diff --git a/sysdeps/powerpc/strchr.s b/sysdeps/powerpc/strchr.s
deleted file mode 100644
index c1df66f8dc..0000000000
--- a/sysdeps/powerpc/strchr.s
+++ /dev/null
@@ -1,118 +0,0 @@
- # Optimized strchr implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # See strlen.s for comments on how this works.
-
-	.section ".text"
-	.align 2
-	.globl strchr
-	.type strchr,@function
-strchr:
- # char * [r3] strchr (const char *s [r3] , int c [r4] )
-
- # r0:	a temporary
- # r3:	our return result.
- # r4:	byte we're looking for, spread over the whole word
- # r5:	the current word
- # r6:	the constant 0xfefefeff (-0x01010101)
- # r7:	the constant 0x7f7f7f7f
- # r8:	pointer to the current word.
- # r9:	a temporary
- # r10:	the number of bits we should ignore in the first word
- # r11:	a mask with the bits to ignore set to 0
- # r12:	a temporary
-	
-	rlwimi %r4,%r4,8,16,23
-	li   %r11,-1
-	rlwimi %r4,%r4,16,0,15
-	lis  %r6,0xfeff
-	lis  %r7,0x7f7f
-	clrrwi %r8,%r3,2
-	addi %r7,%r7,0x7f7f
-	addi %r6,%r6,0xfffffeff
-	rlwinm %r10,%r3,3,27,28
- # Test the first (partial?) word.
-	lwz  %r5,0(%r8)
-	srw  %r11,%r11,%r10
-	orc  %r5,%r5,%r11
-	add  %r0,%r6,%r5
-	nor  %r9,%r7,%r5
-	and. %r0,%r0,%r9
-	xor  %r12,%r4,%r5
-	orc  %r12,%r12,%r11
-	b    loopentry
-	
- # The loop.
-
-loop:	lwzu %r5,4(%r8)
-	and. %r0,%r0,%r9
- # Test for 0
-	add  %r0,%r6,%r5
-	nor  %r9,%r7,%r5
-	bne  foundit
-	and. %r0,%r0,%r9
- # Start test for the bytes we're looking for
-	xor  %r12,%r4,%r5
-loopentry:
-	add  %r0,%r6,%r12
-	nor  %r9,%r7,%r12
-	beq  loop
- # There is a zero byte in the word, but may also be a matching byte (either
- # before or after the zero byte). In fact, we may be looking for a
- # zero byte, in which case we return a match. We guess that this hasn't
- # happened, though.
-missed:	
-	and. %r0,%r0,%r9
-	li   %r3,0
-	beqlr
- # It did happen. Decide which one was first...
- # I'm not sure if this is actually faster than a sequence of
- # rotates, compares, and branches (we use it anyway because it's shorter).
-	and  %r6,%r7,%r5
-	or   %r11,%r7,%r5
-	and  %r0,%r7,%r12
-	or   %r10,%r7,%r12
-	add  %r6,%r6,%r7
-	add  %r0,%r0,%r7
-	nor  %r5,%r11,%r6
-	nor  %r9,%r10,%r0
-	cmplw %r5,%r9
-	bgtlr
-	cntlzw %r4,%r9
-	srwi %r4,%r4,3
-	add  %r3,%r8,%r4
-	blr
-
-foundit:
-	and  %r0,%r7,%r12
-	or   %r10,%r7,%r12
-	add  %r0,%r0,%r7
-	nor  %r9,%r10,%r0
-	cntlzw %r4,%r9
-	subi %r8,%r8,4
-	srwi %r4,%r4,3
-	add  %r3,%r8,%r4
-	blr
-
-0:
-	.size	 strchr,0b-strchr
-
-	.globl index
-	.weak index
-	.set index,strchr
diff --git a/sysdeps/powerpc/strcmp.S b/sysdeps/powerpc/strcmp.S
new file mode 100644
index 0000000000..9f4d134419
--- /dev/null
+++ b/sysdeps/powerpc/strcmp.S
@@ -0,0 +1,115 @@
+/* Optimized strcmp implementation for PowerPC.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* See strlen.s for comments on how the end-of-string testing works.  */
+
+EALIGN(strcmp,4,0)
+/* int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])  */
+
+/* General register assignments:
+   r0:	temporary
+   r3:	pointer to previous word in s1
+   r4:	pointer to previous word in s2
+   r5:	current word from s1
+   r6:	current word from s2
+   r7:	0xfefefeff
+   r8:	0x7f7f7f7f
+   r9:	~(word in s1 | 0x7f7f7f7f)  */
+
+/* Register assignments in the prologue:
+   r10:	low 2 bits of p2-p1
+   r11:	mask to orc with r5/r6  */
+
+	or    %r0,%r4,%r3
+	clrlwi. %r0,%r0,30
+	lis   %r7,0xfeff
+	bne   L(unaligned)
+
+	lwz   %r5,0(%r3)
+	lwz   %r6,0(%r4)
+	lis   %r8,0x7f7f
+	addi  %r7,%r7,-0x101
+	addi  %r8,%r8,0x7f7f
+	b     1f
+
+0:	lwzu  %r5,4(%r3)
+	bne   %cr1,L(different)
+	lwzu  %r6,4(%r4)
+1:	add   %r0,%r7,%r5
+	nor   %r9,%r8,%r5
+	and.  %r0,%r0,%r9
+	cmpw  %cr1,%r5,%r6
+	beq+  0b
+L(endstring):
+/* OK. We've hit the end of the string. We need to be careful that
+   we don't compare two strings as different because of gunk beyond
+   the end of the strings...  */
+	and   %r0,%r8,%r5
+	beq   %cr1,L(equal)
+	add   %r0,%r0,%r8
+	xor.  %r10,%r5,%r6
+	andc  %r9,%r9,%r0
+	blt-  L(highbit)
+	cntlzw %r10,%r10
+	cntlzw %r9,%r9
+	addi  %r9,%r9,7
+	cmpw  %cr1,%r9,%r10
+	sub   %r3,%r5,%r6
+	bgelr+ %cr1
+L(equal):
+	li    %r3,0
+	blr
+
+L(different):
+	lwz   %r5,-4(%r3)
+	xor.  %r10,%r5,%r6
+	sub   %r3,%r5,%r6
+	bgelr+
+L(highbit):
+	mr    %r3,%r6
+	blr
+
+
+/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+	.align 4
+L(unaligned):
+	lbz   %r5,0(%r3)
+	lbz   %r6,0(%r4)
+	b     1f
+
+0:	lbzu  %r5,1(%r3)
+	bne-  4f
+	lbzu  %r6,1(%r4)
+1:	cmpwi %cr1,%r5,0
+	beq-  %cr1,3f
+	cmpw  %r5,%r6
+	bne-  3f
+	lbzu  %r5,1(%r3)
+	lbzu  %r6,1(%r4)
+	cmpwi %cr1,%r5,0
+	cmpw  %r5,%r6
+	bne+  %cr1,0b
+3:	sub   %r3,%r5,%r6
+	blr
+4:	lbz   %r5,-1(%r3)
+	sub   %r3,%r5,%r6
+	blr
+END(strcmp)
diff --git a/sysdeps/powerpc/strcmp.s b/sysdeps/powerpc/strcmp.s
deleted file mode 100644
index f901b82ab1..0000000000
--- a/sysdeps/powerpc/strcmp.s
+++ /dev/null
@@ -1,273 +0,0 @@
- # Optimized strcmp implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # See strlen.s for comments on how the end-of-string testing works.
-
-	.section ".text"
-	.align 3
-	.globl strcmp
-	.type strcmp,@function
-strcmp:
- # int [r3] strcmp (const char *p1 [r3], const char *p2 [r4])
-
- # General register assignments:
- # r0:	temporary
- # r3:	pointer to previous word in s1
- # r4:	pointer to previous word in s2
- # r5:	current first word in s1
- # r6:	current first word in s2 (after re-alignment)
- # r7:	0xfefefeff
- # r8:	0x7f7f7f7f
- # r9:	~(word in s1 | 0x7f7f7f7f)
-	
- # Register assignments in the prologue:
- # r10:	low 2 bits of p2-p1
- # r11:	mask to orc with r5/r6
-	
-	subf. %r10,%r4,%r3
-	beq-  equal
-	andi. %r10,%r10,3
-	cmpi  %cr1,%r10,2
-	beq-  %cr1,align2
-	lis   %r7,0xfeff
-	lis   %r8,0x7f7f
-	addi  %r8,%r8,0x7f7f
-	addi  %r7,%r7,0xfffffeff
-	bgt-  %cr1,align3
-strcmp3:
-	rlwinm %r0,%r3,3,27,28
-	li    %r11,-1
-	srw   %r11,%r11,%r0
-	clrrwi %r3,%r3,2
-	clrrwi %r4,%r4,2
-	lwz   %r5,0(%r3)
-	lwz   %r6,0(%r4)
-	bne-  align1
-
- # The loop, case when both strings are aligned the same.
- # on entry, cr1.eq must be 1.
- # r10:	second word in s1
- # r11:	second word in s2 OR mask to orc with first two words.
-align0:	
-	andi. %r0,%r3,4
-	orc   %r5,%r5,%r11
-	orc   %r6,%r6,%r11
-	beq+  a0start
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	cmplw %cr1,%r5,%r6
-	subi  %r3,%r3,4
-	bne-  endstringeq
-	subi  %r4,%r4,4
-	bne-  %cr1,difference
-
-loopalign0:
-	lwzu  %r5,8(%r3)
-	bne-  %cr1,difference2
-	lwzu  %r6,8(%r4)
-a0start:
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	cmplw %cr1,%r5,%r6
-	lwz   %r10,4(%r3)
-	bne-  endstringeq
-	add   %r0,%r7,%r10
-	bne-  %cr1,difference
-	nor   %r9,%r8,%r10
-	lwz   %r11,4(%r4)
-	and.  %r0,%r0,%r9
-	cmplw %cr1,%r10,%r11
-	beq+  loopalign0
-
-	mr    %r5,%r10
-	mr    %r6,%r11
-
- # fall through to...
-
-endstringeq:
- # (like 'endstring', but an equality code is in cr1)
-	beq  %cr1,equal
-endstring:
- # OK. We've hit the end of the string. We need to be careful that
- # we don't compare two strings as different because of gunk beyond
- # the end of the strings. We do it like this...
-	and  %r0,%r8,%r5
-	add  %r0,%r0,%r8
-	xor. %r10,%r5,%r6
-	andc %r9,%r9,%r0
-	cntlzw %r10,%r10
-	cntlzw %r9,%r9
-	addi %r9,%r9,7
-	cmpw %cr1,%r9,%r10
-	blt  %cr1,equal
-	sub  %r3,%r5,%r6
-	bgelr+
-	mr   %r3,%r6
-	blr
-equal:	li   %r3,0
-	blr
-	
- # The loop, case when s2 is aligned 1 char behind s1.
- # r10:	current word in s2 (before re-alignment)
-
-align1:
-	cmpwi %cr1,%r0,0
-	orc   %r5,%r5,%r11
-	bne   %cr1,align1_123
- # When s1 is aligned to a word boundary, the startup processing is special.
-	slwi. %r6,%r6,24
-	bne+  a1entry_0
-	nor   %r9,%r8,%r5
-	b     endstring
-
-align1_123:
- # Otherwise (s1 not aligned to a word boundary):
-	mr    %r10,%r6
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	srwi  %r6,%r6,8
-	orc   %r6,%r6,%r11
-	cmplw %cr1,%r5,%r6
-	bne-  endstringeq
-	bne-  %cr1,difference
-
-loopalign1:
-	slwi. %r6,%r10,24
-	bne-  %cr1,a1difference
-	lwzu  %r5,4(%r3)
-	beq-  endstring1
-a1entry_0:
-	lwzu  %r10,4(%r4)
-a1entry_123:	
-	add   %r0,%r7,%r5
-	nor   %r9,%r8,%r5
-	and.  %r0,%r0,%r9
-	rlwimi %r6,%r10,24,8,31
-	cmplw %cr1,%r5,%r6
-	beq+  loopalign1
-	b     endstringeq
-
-endstring1:
-	srwi  %r3,%r5,24
-	blr
-
-a1difference:
-	lbz   %r6,-1(%r4)
-	slwi  %r6,%r6,24
-	rlwimi %r6,%r10,24,8,31
-
- # fall through to...
-		
-difference:	
- # The idea here is that we could just return '%r5 - %r6', except
- # that the result might overflow. Overflow can only happen when %r5
- # and %r6 have different signs (thus the xor), in which case we want to
- # return negative iff %r6 has its high bit set so %r5 < %r6.
- # A branch-free implementation of this is
- #	xor  %r0,%r5,%r6
- #	rlwinm %r0,%r0,1,31,31
- #	rlwnm %r5,%r5,%r0,1,31
- #	rlwnm %r6,%r6,%r0,1,31
- #	sub  %r3,%r5,%r6
- #	blr
- # but this is usually more expensive.
-	xor. %r0,%r5,%r6
-	sub  %r3,%r5,%r6
-	bgelr+
-	mr   %r3,%r6
-	blr
-
-difference2:
- # As for 'difference', but use registers r10 and r11 instead of r5 and r6.
-	xor. %r0,%r10,%r11
-	sub  %r3,%r10,%r11
-	bgelr+
-	mr   %r3,%r11
-	blr
-	
- # For the case when s2 is aligned 3 chars behind s1, we switch
- # s1 and s2...
- # r10:	used by 'align2' (see below)
- # r11:	used by 'align2' (see below)
- # r12:	saved link register
- # cr0.eq: must be left as 1.
-
-align3:	mflr %r12
-	mr   %r0,%r3
-	mr   %r3,%r4
-	mr   %r4,%r0
-	bl   strcmp3
-	mtlr %r12
-	neg  %r3,%r3
-	blr
-	
- # The loop, case when s2 and s1's alignments differ by 2
- # This is the ugly case...
- # FIXME: on a 601, the loop takes 7 cycles instead of the 6 you'd expect,
- # because there are too many branches. This loop should probably be
- # coded like the align1 case.
-	
-a2even:	lhz   %r5,0(%r3)
-	lhz   %r6,0(%r4)
-	b     a2entry
-	
-align2:
-	andi. %r0,%r3,1
-	beq+  a2even
-	subi  %r3,%r3,1
-	subi  %r4,%r4,1
-	lbz   %r5,1(%r3)
-	lbz   %r6,1(%r4)
-	cmpwi %cr0,%r5,0
-	cmpw  %cr1,%r5,%r6
-	beq-  align2end2
-	lhzu  %r5,2(%r3)
-	beq+  %cr1,a2entry1
-	lbz   %r5,-1(%r3)
-	sub   %r3,%r5,%r6
-	blr
-
-loopalign2:
-	cmpw  %cr1,%r5,%r6
-	beq-  align2end2
-	lhzu  %r5,2(%r3)
-	bne-  %cr1,align2different
-a2entry1:
-	lhzu  %r6,2(%r4)
-a2entry:	
-	cmpwi %cr5,%r5,0x00ff
-	andi. %r0,%r5,0x00ff
-	bgt+  %cr5,loopalign2
-
-align2end:
-	andi. %r3,%r6,0xff00
-	neg   %r3,%r3
-	blr
-
-align2different:
-	lhzu  %r5,-2(%r3)
-align2end2:
-	sub   %r3,%r5,%r6
-	blr
-		
-0:
-	.size	 strcmp,0b-strcmp
diff --git a/sysdeps/powerpc/strlen.S b/sysdeps/powerpc/strlen.S
new file mode 100644
index 0000000000..dc6660b8fc
--- /dev/null
+++ b/sysdeps/powerpc/strlen.S
@@ -0,0 +1,144 @@
+/* Optimized strlen implementation for PowerPC.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* The algorithm here uses the following techniques:
+
+   1) Given a word 'x', we can test to see if it contains any 0 bytes
+      by subtracting 0x01010101, and seeing if any of the high bits of each
+      byte changed from 0 to 1. This works because the least significant
+      0 byte must have had no incoming carry (otherwise it's not the least
+      significant), so it is 0x00 - 0x01 == 0xff. For all other
+      byte values, either they have the high bit set initially, or when
+      1 is subtracted you get a value in the range 0x00-0x7f, none of which
+      have their high bit set. The expression here is
+      (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
+      there were no 0x00 bytes in the word.
+
+   2) Given a word 'x', we can test to see _which_ byte was zero by
+      calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
+      This produces 0x80 in each byte that was zero, and 0x00 in all
+      the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
+      byte, and the '| x' part ensures that bytes with the high bit set
+      produce 0x00. The addition will carry into the high bit of each byte
+      iff that byte had one of its low 7 bits set. We can then just see
+      which was the most significant bit set and divide by 8 to find how
+      many to add to the index.
+      This is from the book 'The PowerPC Compiler Writer's Guide',
+      by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
+
+   We deal with strings not aligned to a word boundary by taking the
+   first word and ensuring that bytes not part of the string
+   are treated as nonzero. To allow for memory latency, we unroll the
+   loop a few times, being careful to ensure that we do not read ahead
+   across cache line boundaries.
+
+   Questions to answer:
+   1) How long are strings passed to strlen? If they're often really long,
+   we should probably use cache management instructions and/or unroll the
+   loop more. If they're often quite short, it might be better to use
+   fact (2) in the inner loop than have to recalculate it.
+   2) How popular are bytes with the high bit set? If they are very rare,
+   on some processors it might be useful to use the simpler expression
+   ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
+   ALU), but this fails when any character has its high bit set.  */
+
+/* Some notes on register usage: Under the SVR4 ABI, we can use registers
+   0 and 3 through 12 (so long as we don't call any procedures) without
+   saving them. We can also use registers 14 through 31 if we save them.
+   We can't use r1 (it's the stack pointer), r2 nor r13 because the user
+   program may expect them to hold their usual value if we get sent
+   a signal. Integer parameters are passed in r3 through r10.
+   We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
+   them, the others we must save.  */
+
+ENTRY(strlen)
+/* On entry, r3 points to the string, and it's left that way.
+   We use r6 to store 0xfefefeff, and r7 to store 0x7f7f7f7f.
+   r4 is used to keep the current index into the string; r5 holds
+   the number of padding bits we prepend to the string to make it
+   start at a word boundary. r8 holds the 'current' word.
+   r9-12 are temporaries. r0 is used as a temporary and for discarded
+   results.  */
+	clrrwi %r4,%r3,2
+	lis   %r7,0x7f7f
+	rlwinm %r5,%r3,3,27,28
+	lwz   %r8,0(%r4)
+	li    %r9,-1
+	addi  %r7,%r7,0x7f7f
+/* That's the setup done, now do the first pair of words.
+   We make an exception and use method (2) on the first two words, to reduce
+   overhead.  */
+	srw   %r9,%r9,%r5
+	and   %r0,%r7,%r8
+	or    %r10,%r7,%r8
+	add   %r0,%r0,%r7
+	nor   %r0,%r10,%r0
+	and.  %r8,%r0,%r9
+	mtcrf 0x01,%r3
+	bne   L(done0)
+	lis   %r6,0xfeff
+	addi  %r6,%r6,-0x101
+/* Are we now aligned to a doubleword boundary?  */
+	bt    29,L(loop)
+
+/* Handle second word of pair.  */
+	lwzu  %r8,4(%r4)
+	and   %r0,%r7,%r8
+	or    %r10,%r7,%r8
+	add   %r0,%r0,%r7
+	nor.  %r8,%r10,%r0
+	bne   L(done0)
+
+/* The loop.  */
+
+L(loop):
+	lwz   %r8,4(%r4)
+	lwzu  %r9,8(%r4)
+	add   %r0,%r6,%r8
+	nor   %r10,%r7,%r8
+	and.  %r0,%r0,%r10
+	add   %r11,%r6,%r9
+	nor   %r12,%r7,%r9
+	bne   L(done1)
+	and.  %r0,%r11,%r12
+	beq   L(loop)
+
+	and   %r0,%r7,%r9
+	add   %r0,%r0,%r7
+	andc  %r8,%r12,%r0
+	b     L(done0)
+
+L(done1):
+	and   %r0,%r7,%r8
+	subi  %r4,%r4,4
+	add   %r0,%r0,%r7
+	andc  %r8,%r10,%r0
+
+/* When we get to here, r4 points to the first word in the string that
+   contains a zero byte, and the most significant set bit in r8 is in that
+   byte.  */
+L(done0):
+	cntlzw %r11,%r8
+	subf  %r0,%r3,%r4
+	srwi  %r11,%r11,3
+	add   %r3,%r0,%r11
+	blr
+END(strlen)
diff --git a/sysdeps/powerpc/strlen.s b/sysdeps/powerpc/strlen.s
deleted file mode 100644
index ea809772eb..0000000000
--- a/sysdeps/powerpc/strlen.s
+++ /dev/null
@@ -1,144 +0,0 @@
- # Optimized strlen implementation for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # The algorithm here uses the following techniques:
- #
- # 1) Given a word 'x', we can test to see if it contains any 0 bytes
- #    by subtracting 0x01010101, and seeing if any of the high bits of each
- #    byte changed from 0 to 1. This works because the least significant
- #    0 byte must have had no incoming carry (otherwise it's not the least
- #    significant), so it is 0x00 - 0x01 == 0xff. For all other
- #    byte values, either they have the high bit set initially, or when
- #    1 is subtracted you get a value in the range 0x00-0x7f, none of which
- #    have their high bit set. The expression here is
- #    (x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
- #    there were no 0x00 bytes in the word.
- #
- # 2) Given a word 'x', we can test to see _which_ byte was zero by
- #    calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
- #    This produces 0x80 in each byte that was zero, and 0x00 in all
- #    the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
- #    byte, and the '| x' part ensures that bytes with the high bit set
- #    produce 0x00. The addition will carry into the high bit of each byte
- #    iff that byte had one of its low 7 bits set. We can then just see
- #    which was the most significant bit set and divide by 8 to find how
- #    many to add to the index.
- #    This is from the book 'The PowerPC Compiler Writer's Guide',
- #    by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
- #
- # We deal with strings not aligned to a word boundary by taking the
- # first word and ensuring that bytes not part of the string
- # are treated as nonzero. To allow for memory latency, we unroll the
- # loop a few times, being careful to ensure that we do not read ahead
- # across cache line boundaries.
- #
- # Questions to answer:
- # 1) How long are strings passed to strlen? If they're often really long,
- # we should probably use cache management instructions and/or unroll the
- # loop more. If they're often quite short, it might be better to use
- # fact (2) in the inner loop than have to recalculate it.
- # 2) How popular are bytes with the high bit set? If they are very rare,
- # on some processors it might be useful to use the simpler expression
- # ~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
- # ALU), but this fails when any character has its high bit set.
-
- # Some notes on register usage: Under the SVR4 ABI, we can use registers
- # 0 and 3 through 12 (so long as we don't call any procedures) without
- # saving them. We can also use registers 14 through 31 if we save them.
- # We can't use r1 (it's the stack pointer), r2 nor r13 because the user
- # program may expect them to hold their usual value if we get sent
- # a signal. Integer parameters are passed in r3 through r10.
- # We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
- # them, the others we must save.
-
-	.section ".text"
-	.align 2
-	.globl strlen
-	.type strlen,@function
-strlen:
- # On entry, r3 points to the string, and it's left that way.
- # We use r6 to store 0xfefefeff, and r7 to store 0x7f7f7f7f.
- # r4 is used to keep the current index into the string; r5 holds
- # the number of padding bits we prepend to the string to make it
- # start at a word boundary. r8 holds the 'current' word.
- # r9-12 are temporaries. r0 is used as a temporary and for discarded
- # results.
-	clrrwi %r4,%r3,2
-	lis   %r7,0x7f7f
-	rlwinm %r5,%r3,3,27,28
-	lwz   %r8,0(%r4)
-	li    %r9,-1
-	addi  %r7,%r7,0x7f7f
- # That's the setup done, now do the first pair of words.
- # We make an exception and use method (2) on the first two words, to reduce
- # overhead.
-	srw   %r9,%r9,%r5
-	and   %r0,%r7,%r8
-	or    %r10,%r7,%r8
-	add   %r0,%r0,%r7
-	nor   %r0,%r10,%r0
-	and.  %r8,%r0,%r9
-	mtcrf 0x01,%r3
-	bne   done0
-	lis   %r6,0xfeff
-	addi  %r6,%r6,-0x101
- # Are we now aligned to a doubleword boundary?
-	bt    29,loop
-
- # Handle second word of pair.
-	lwzu  %r8,4(%r4)
-	and   %r0,%r7,%r8
-	or    %r10,%r7,%r8
-	add   %r0,%r0,%r7
-	nor.  %r8,%r10,%r0
-	bne   done0
-
- # The loop.
-
-loop:	lwz   %r8,4(%r4)
-	lwzu  %r9,8(%r4)
-	add   %r0,%r6,%r8
-	nor   %r10,%r7,%r8
-	and.  %r0,%r0,%r10
-	add   %r11,%r6,%r9
-	nor   %r12,%r7,%r9
-	bne   done1
-	and.  %r0,%r11,%r12
-	beq   loop
-
-	and   %r0,%r7,%r9
-	add   %r0,%r0,%r7
-	andc  %r8,%r12,%r0
-	b     done0
-
-done1:	and   %r0,%r7,%r8
-	subi  %r4,%r4,4
-	add   %r0,%r0,%r7
-	andc  %r8,%r10,%r0
-
- # When we get to here, r4 points to the first word in the string that
- # contains a zero byte, and the most significant set bit in r8 is in that
- # byte.
-done0:	cntlzw %r11,%r8
-	subf  %r0,%r3,%r4
-	srwi  %r11,%r11,3
-	add   %r3,%r0,%r11
-	blr
-0:
-	.size	 strlen,0b-strlen
diff --git a/sysdeps/powerpc/sub_n.S b/sysdeps/powerpc/sub_n.S
new file mode 100644
index 0000000000..7af577d835
--- /dev/null
+++ b/sysdeps/powerpc/sub_n.S
@@ -0,0 +1,68 @@
+/* Subtract two limb vectors of equal, non-zero length for PowerPC.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
+                        mp_size_t size)
+   Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.  */
+
+/* Note on optimisation: This code is optimal for the 601.  Almost every other
+   possible 2-unrolled inner loop will not be.  Also, watch out for the
+   alignment...  */
+
+EALIGN(__mpn_sub_n,3,1)
+/* Set up for loop below.  */
+	mtcrf 0x01,%r6
+	srwi. %r7,%r6,1
+	mtctr %r7
+	bt    31,2f
+
+/* Set the carry (clear the borrow).  */
+	subfc %r0,%r0,%r0
+/* Adjust pointers for loop.  */
+	addi  %r3,%r3,-4
+	addi  %r4,%r4,-4
+	addi  %r5,%r5,-4
+	b     0f
+
+2:	lwz   %r7,0(%r5)
+	lwz   %r6,0(%r4)
+	subfc %r6,%r7,%r6
+	stw   %r6,0(%r3)
+        beq   1f
+
+/* Align start of loop to an odd word boundary to guarantee that the
+   last two words can be fetched in one access (for 601).  This turns
+   out to be important.  */
+0:
+	lwz   %r9,4(%r4)
+	lwz   %r8,4(%r5)
+	lwzu  %r6,8(%r4)
+	lwzu  %r7,8(%r5)
+	subfe %r8,%r8,%r9
+	stw   %r8,4(%r3)
+	subfe %r6,%r7,%r6
+	stwu  %r6,8(%r3)
+	bdnz  0b
+/* Return the borrow. */
+1:	subfe %r3,%r3,%r3
+	neg   %r3,%r3
+	blr
+END(__mpn_sub_n)
diff --git a/sysdeps/powerpc/sub_n.s b/sysdeps/powerpc/sub_n.s
deleted file mode 100644
index 8711bf9a40..0000000000
--- a/sysdeps/powerpc/sub_n.s
+++ /dev/null
@@ -1,69 +0,0 @@
- # Subtract two limb vectors of equal, non-zero length for PowerPC.
- # Copyright (C) 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_sub_n (mp_ptr res_ptr, mp_srcptr s1_ptr, mp_srcptr s2_ptr,
- #                      mp_size_t size)
- # Calculate s1-s2 and put result in res_ptr; return borrow, 0 or 1.
-
- # Note on optimisation: This code is optimal for the 601.  Almost every other
- # possible 2-unrolled inner loop will not be.  Also, watch out for the
- # alignment...
-
-	.align 3
-	.globl __mpn_sub_n
-	.type	 __mpn_sub_n,@function
-	nop
-__mpn_sub_n:
- # Set up for loop below.
-	mtcrf 0x01,%r6
-	srwi. %r7,%r6,1
-	mtctr %r7
-	bt    31,2f
-
- # Set the carry (clear the borrow).
-	subfc %r0,%r0,%r0
- # Adjust pointers for loop.
-	addi  %r3,%r3,-4
-	addi  %r4,%r4,-4
-	addi  %r5,%r5,-4
-	b     0f
-
-2:	lwz   %r7,0(%r5)
-	lwz   %r6,0(%r4)
-	subfc %r6,%r7,%r6
-	stw   %r6,0(%r3)
-        beq   1f
-
- # Align start of loop to an odd word boundary to guarantee that the
- # last two words can be fetched in one access (for 601).  This turns
- # out to be important.
-0:
-	lwz   %r9,4(%r4)
-	lwz   %r8,4(%r5)
-	lwzu  %r6,8(%r4)
-	lwzu  %r7,8(%r5)
-	subfe %r8,%r8,%r9
-	stw   %r8,4(%r3)
-	subfe %r6,%r7,%r6
-	stwu  %r6,8(%r3)
-	bdnz  0b
- # return the borrow
-1:	subfe %r3,%r3,%r3
-	neg   %r3,%r3
-	blr
diff --git a/sysdeps/powerpc/submul_1.S b/sysdeps/powerpc/submul_1.S
new file mode 100644
index 0000000000..80da8ec8c1
--- /dev/null
+++ b/sysdeps/powerpc/submul_1.S
@@ -0,0 +1,52 @@
+/* Multiply a limb vector by a single limb, for PowerPC.
+   Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <sysdep.h>
+
+/* mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
+                           mp_size_t s1_size, mp_limb_t s2_limb)
+   Calculate res-s1*s2 and put result back in res; return carry.  */
+
+ENTRY(__mpn_submul_1)
+	mtctr	%r5
+
+	lwz	%r0,0(%r4)
+	mullw	%r7,%r0,%r6
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,0(%r3)
+	subf 	%r8,%r7,%r9
+	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
+	addi	%r3,%r3,-4		# adjust res_ptr
+	bdz	1f
+
+0:	lwzu	%r0,4(%r4)
+	stwu	%r8,4(%r3)
+	mullw	%r8,%r0,%r6
+	adde	%r7,%r8,%r10
+	mulhwu	%r10,%r0,%r6
+	lwz     %r9,4(%r3)
+	addze   %r10,%r10
+	subf    %r8,%r7,%r9
+	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
+	bdnz	0b
+
+1:	stw	%r8,4(%r3)
+	addze	%r3,%r10
+	blr
+END(__mpn_submul_1)
diff --git a/sysdeps/powerpc/submul_1.s b/sysdeps/powerpc/submul_1.s
deleted file mode 100644
index 999430d744..0000000000
--- a/sysdeps/powerpc/submul_1.s
+++ /dev/null
@@ -1,52 +0,0 @@
- # Multiply a limb vector by a single limb, for PowerPC.
- # Copyright (C) 1993, 1994, 1995, 1997 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 Library General Public License as
- # published by the Free Software Foundation; either version 2 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
- # Library General Public License for more details.
- #
- # You should have received a copy of the GNU Library General Public
- # License along with the GNU C Library; see the file COPYING.LIB.  If not,
- # write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- # Boston, MA 02111-1307, USA.
-
- # mp_limb_t mpn_submul_1 (mp_ptr res_ptr, mp_srcptr s1_ptr,
- #                         mp_size_t s1_size, mp_limb_t s2_limb)
- # Calculate res-s1*s2 and put result back in res; return carry.
-
-	.align 2
-	.globl __mpn_submul_1
-	.type	 __mpn_submul_1,@function
-__mpn_submul_1:
-	mtctr	%r5
-
-	lwz	%r0,0(%r4)
-	mullw	%r7,%r0,%r6
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,0(%r3)
-	subf 	%r8,%r7,%r9
-	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
-	addi	%r3,%r3,-4		# adjust res_ptr
-	bdz	Lend
-
-Loop:	lwzu	%r0,4(%r4)
-	stwu	%r8,4(%r3)
-	mullw	%r8,%r0,%r6
-	adde	%r7,%r8,%r10
-	mulhwu	%r10,%r0,%r6
-	lwz     %r9,4(%r3)
-	addze   %r10,%r10
-	subf    %r8,%r7,%r9
-	addc    %r7,%r7,%r8		# invert cy (r7 is junk)
-	bdnz	Loop
-
-Lend:	stw	%r8,4(%r3)
-	addze	%r3,%r10
-	blr
diff --git a/sysdeps/powerpc/test-arith.c b/sysdeps/powerpc/test-arith.c
index c846b0d0ec..9e1be88098 100644
--- a/sysdeps/powerpc/test-arith.c
+++ b/sysdeps/powerpc/test-arith.c
@@ -226,7 +226,7 @@ check_result(int line, const char *rm, tocheck_t expected, tocheck_t actual)
   if (memcmp(&expected, &actual, sizeof(tocheck_t)) != 0)
     {
       unsigned char *ex, *ac;
-      int i;
+      size_t i;
 
       printf("%s:%d:round %s:result failed\n"
 	     " expected result 0x", __FILE__, line, rm);
@@ -323,7 +323,7 @@ check_excepts(int line, const char *rm, int expected, int actual)
     expected = expected & ~excepts_missing | FE_INVALID_SNAN;
   if ((expected & all_exceptions) != actual)
     {
-      int i;
+      size_t i;
       printf("%s:%d:round %s:exceptions failed\n"
 	     " expected exceptions ", __FILE__, line,rm);
       for (i = 0; i < sizeof(excepts)/sizeof(excepts[0]); i++)
@@ -419,7 +419,7 @@ static const optest_t optests[] = {
   {__LINE__,B_NEG, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
   {__LINE__,B_NEG, 0,P_Z,P_Z1,  0,0,0, R_ALL, 0, 1,P_Z,P_Z1 },
   {__LINE__,B_NEG, 1,P_Z,P_Z1,  0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-  
+
   /* Absolute value.  */
   {__LINE__,B_ABS, 0,P_Z,P_Z,   0,0,0, R_ALL, 0, 0,P_Z,P_Z },
   {__LINE__,B_ABS, 1,P_Z,P_Z,   0,0,0, R_ALL, 0, 0,P_Z,P_Z },
@@ -433,7 +433,7 @@ static const optest_t optests[] = {
   {__LINE__,B_ABS, 1,P_1Z,P_1Z1, 0,0,0, R_ALL, 0, 0,P_1Z,P_1Z1 },
   {__LINE__,B_ABS, 0,P_Z,P_Z1,  0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
   {__LINE__,B_ABS, 1,P_Z,P_Z1,  0,0,0, R_ALL, 0, 0,P_Z,P_Z1 },
-  
+
   /* Square root.  */
   {__LINE__,B_SQRT, 0,P_Z,P_Z,   0,0,0, R_ALL, 0, 0,P_Z,P_Z },
   {__LINE__,B_SQRT, 1,P_Z,P_Z,   0,0,0, R_ALL, 0, 1,P_Z,P_Z },
@@ -459,7 +459,8 @@ static const optest_t optests[] = {
 static void
 check_op(void)
 {
-  int i, j;
+  size_t i;
+  int j;
   tocheck_t r, a, b, x;
   int raised;
 
@@ -497,7 +498,7 @@ static void
 fail_xr(int line, const char *rm, tocheck_t x, tocheck_t r, tocheck_t xx,
 	int xflag)
 {
-  int i;
+  size_t i;
   unsigned char *cx, *cr, *cxx;
 
   printf("%s:%d:round %s:fail\n with x=0x", __FILE__, line,rm);
@@ -539,7 +540,7 @@ check_sqrt(tocheck_t a)
 	  r0 = delta(r1,-1); r2 = delta(r1,1);
 	  switch (1 << j)
 	    {
-	    case R_NEAREST: 
+	    case R_NEAREST:
 	      x0 = r0 * r0 - a; x2 = r2 * r2 - a;
 	      ok = fabs(x0) >= fabs(x1) && fabs(x1) <= fabs(x2);
 	      break;
diff --git a/sysdeps/stub/atomicity.h b/sysdeps/stub/atomicity.h
new file mode 100644
index 0000000000..3916eebbcf
--- /dev/null
+++ b/sysdeps/stub/atomicity.h
@@ -0,0 +1,53 @@
+/* Low-level functions for atomitc operations.  ix86 version, x >= 4.
+   Copyright (C) 1997 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 Library General Public License as
+   published by the Free Software Foundation; either version 2 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#ifndef _ATOMICITY_H
+#define _ATOMICITY_H	1
+
+#include <inttypes.h>
+
+
+static inline int
+__attribute__ ((unused))
+exchange_and_add (uint32_t *mem, int val)
+{
+  int result = *mem;
+  *mem += val;
+  return result;
+}
+
+static inline void
+__attribute__ ((unused))
+atomic_add (uint32_t *mem, int val)
+{
+  *mem += val;
+}
+
+static inline int
+__attribute__ ((unused))
+compare_and_swap (long int *p, long int oldval, long int newval)
+{
+  if (*p != oldval)
+    return 0;
+
+  *p = newval;
+  return 1;
+}
+
+#endif /* atomicity.h */
diff --git a/sysdeps/stub/ftruncate.c b/sysdeps/stub/ftruncate.c
index b70bbc1746..c84ed4ab1b 100644
--- a/sysdeps/stub/ftruncate.c
+++ b/sysdeps/stub/ftruncate.c
@@ -18,6 +18,7 @@
 
 #include <sys/types.h>
 #include <errno.h>
+#include <unistd.h>
 
 /* Truncate the file FD refers to to LENGTH bytes.  */
 int
diff --git a/sysdeps/stub/getdents.c b/sysdeps/stub/getdents.c
index a773347f50..652eda2bc7 100644
--- a/sysdeps/stub/getdents.c
+++ b/sysdeps/stub/getdents.c
@@ -19,6 +19,7 @@
 #include <stddef.h>
 #include <errno.h>
 #include <sys/types.h>
+#include <dirent.h>
 
 ssize_t
 __getdirentries (fd, buf, nbytes, basep)
diff --git a/sysdeps/stub/init-posix.c b/sysdeps/stub/init-posix.c
index 0d632d6fb6..8e37bb6861 100644
--- a/sysdeps/stub/init-posix.c
+++ b/sysdeps/stub/init-posix.c
@@ -19,7 +19,7 @@
 #ifndef	HAVE_GNU_LD
 
 void
-__init_posix ()
+__init_posix (void)
 {
   return;
 }
diff --git a/sysdeps/stub/profil.c b/sysdeps/stub/profil.c
index a0ae3324e9..9613108e3a 100644
--- a/sysdeps/stub/profil.c
+++ b/sysdeps/stub/profil.c
@@ -28,7 +28,7 @@
    disable profiling.  Returns zero on success, -1 on error.  */
 
 int
-profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
+__profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
 {
   if (scale == 0)
     /* Disable profiling.  */
@@ -37,4 +37,5 @@ profil (u_short *sample_buffer, size_t size, size_t offset, u_int scale)
   __set_errno (ENOSYS);
   return -1;
 }
+weak_alias (__profil, profil)
 stub_warning (profil)
diff --git a/sysdeps/stub/reboot.c b/sysdeps/stub/reboot.c
index ae4465d1d9..8139aee83f 100644
--- a/sysdeps/stub/reboot.c
+++ b/sysdeps/stub/reboot.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <unistd.h>
+#include <sys/reboot.h>
 
 /* Reboot the system.  */
 int
diff --git a/sysdeps/stub/swapon.c b/sysdeps/stub/swapon.c
index d580a9a732..cbaa1c2fe3 100644
--- a/sysdeps/stub/swapon.c
+++ b/sysdeps/stub/swapon.c
@@ -18,6 +18,7 @@
 
 #include <errno.h>
 #include <unistd.h>
+#include <sys/swap.h>
 
 /* Make the block special device PATH available to the system for swapping.
    This call is restricted to the super-user.  */
diff --git a/sysdeps/stub/syscall.c b/sysdeps/stub/syscall.c
index 183ffc2893..4903b409b5 100644
--- a/sysdeps/stub/syscall.c
+++ b/sysdeps/stub/syscall.c
@@ -18,6 +18,7 @@
 
 #include <sysdep.h>
 #include <errno.h>
+#include <unistd.h>
 
 /* Do system call CALLNO, passing it the remaining arguments.
    This only makes sense in certain operating systems.  */
diff --git a/sysdeps/stub/ualarm.c b/sysdeps/stub/ualarm.c
index d8e0b0aff8..5972e240eb 100644
--- a/sysdeps/stub/ualarm.c
+++ b/sysdeps/stub/ualarm.c
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <unistd.h>
 
 /* Set an alarm to go off (generating a SIGALRM signal) in VALUE microseconds.
    If INTERVAL is nonzero, when the alarm goes off, the timer is reset to go
diff --git a/sysdeps/stub/usleep.c b/sysdeps/stub/usleep.c
index 412461b4f9..7ee41b63fa 100644
--- a/sysdeps/stub/usleep.c
+++ b/sysdeps/stub/usleep.c
@@ -17,6 +17,7 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <errno.h>
+#include <unistd.h>
 
 /* Sleep USECONDS microseconds, or until a previously set timer goes off.  */
 unsigned int
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c
index c0ffbcedf6..36863db486 100644
--- a/sysdeps/unix/sysv/linux/if_index.c
+++ b/sysdeps/unix/sysv/linux/if_index.c
@@ -26,6 +26,7 @@
 #include <bits/libc-lock.h>
 
 /* Try to get a socket to talk to the kernel.  */
+#if defined SIOGIFINDEX || defined SIOGIFNAME
 static int
 opensock (void)
 {
@@ -63,6 +64,7 @@ opensock (void)
   __libc_lock_unlock (lock);
   return fd;
 }
+#endif
 
 unsigned int
 if_nametoindex (const char *ifname)
diff --git a/sysdeps/unix/sysv/linux/net/if.h b/sysdeps/unix/sysv/linux/net/if.h
index 01e9f00943..f4c1a48579 100644
--- a/sysdeps/unix/sysv/linux/net/if.h
+++ b/sysdeps/unix/sysv/linux/net/if.h
@@ -42,7 +42,10 @@ enum
     IFF_MASTER = 0x400,		/* Master of a load balancer.  */
     IFF_SLAVE = 0x800,		/* Slave of a load balancer.  */
 
-    IFF_MULTICAST = 0x1000	/* Supports multicast.  */
+    IFF_MULTICAST = 0x1000,	/* Supports multicast.  */
+
+    IFF_PORTSEL = 0x2000,	/* Can set media type.  */
+    IFF_AUTOMEDIA = 0x4000	/* Auto media select active.  */
   };
 
 /* The ifaddr structure contains information about one address of an
diff --git a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
index da5ad0eb45..6d240c4b7a 100644
--- a/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
+++ b/sysdeps/unix/sysv/linux/powerpc/bits/mman.h
@@ -1,4 +1,4 @@
-/* Definitions for POSIX memory map inerface.  Linux/MIPS version.
+/* Definitions for POSIX memory map inerface.  Linux/PowerPC version.
    Copyright (C) 1997 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -46,26 +46,15 @@
 #define MAP_FIXED	0x010		/* Interpret addr exactly.  */
 #ifdef __USE_MISC
 # define MAP_FILE	0x000
-# define MAP_ANONYMOUS	0x800		/* Don't use a file.  */
+# define MAP_ANONYMOUS	0x020		/* Don't use a file.  */
 # define MAP_ANON	MAP_ANONYMOUS
 #endif
 
-/* Not used by Linux, but here to make sure we don't clash with ABI
-   defines.  */
-#ifdef __USE_MISC
-# define MAP_RENAME	0x020		/* Assign page to file.  */
-# define MAP_AUTOGROW	0x040		/* File may grow by writing.  */
-# define MAP_LOCAL	0x080		/* Copy on fork/sproc.  */
-# define MAP_AUTORSRV	0x100		/* Logical swap reserved on demand.  */
-#endif
-
 /* These are Linux-specific.  */
 #ifdef __USE_MISC
-# define MAP_GROWSDOWN	0x1000		/* Stack-like segment.  */
-# define MAP_DENYWRITE	0x2000		/* ETXTBSY */
-# define MAP_EXECUTABLE	0x4000		/* Mark it as an executable.  */
-# define MAP_LOCKED	0x8000		/* Lock the mapping.  */
-# define MAP_NORESERVE	0x0400		/* Don't check for reservations.  */
+# define MAP_GROWSDOWN	0x0100		/* Stack-like segment.  */
+# define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+# define MAP_EXECUTABLE	0x1000		/* Mark it as an executable.  */
 #endif
 
 /* Flags to `msync'.  */
@@ -74,10 +63,11 @@
 #define MS_INVALIDATE	2		/* Invalidate the caches.  */
 
 /* Flags for `mlockall'.  */
-#define MCL_CURRENT	1		/* Lock all currently mapped pages.  */
-#define MCL_FUTURE	2		/* Lock all additions to address
+#define MCL_CURRENT	0x2000		/* Lock all currently mapped pages.  */
+#define MCL_FUTURE	0x4000		/* Lock all additions to address
 					   space.  */
 
+
 /* Flags for `mremap'.  */
 #ifdef __USE_GNU
 # define MREMAP_MAYMOVE	1
diff --git a/sysdeps/unix/sysv/linux/powerpc/brk.c b/sysdeps/unix/sysv/linux/powerpc/brk.S
index e9826bd098..f4a3f3bcec 100644
--- a/sysdeps/unix/sysv/linux/powerpc/brk.c
+++ b/sysdeps/unix/sysv/linux/powerpc/brk.S
@@ -18,30 +18,32 @@
    Boston, MA 02111-1307, USA.  */
 
 #include <sysdep.h>
-#include <errno.h>
+#define _ERRNO_H	1
+#include <bits/errno.h>
+
+	.comm	__curbrk,4,4
+	.section ".text"
+ENTRY(__brk)
+	stwu    %r1,-16(%r1)
+	stw	%r3,8(%r1)
+	DO_CALL(SYS_ify(brk))
+	lwz     %r6,8(%r1)
+#ifdef PIC
+	mflr    %r4
+	bl      _GLOBAL_OFFSET_TABLE_@local-4
+	mflr    %r5
+	lwz     %r5,__curbrk@got(%r5)
+	mtlr    %r4
+	stw     %r3,0(%r5)
+#else
+	stw     %r3,__curbrk@sdarel(%r13)
+#endif
+	cmplw   %r6,%r3
+	addi    %r1,%r1,16
+	li	%r3,0
+	blelr+
+	li      %r3,ENOMEM
+	b	JUMPTARGET(__syscall_error)
+END (__brk)
 
-void *__curbrk;
-
-int
-__brk (void *addr)
-{
-  register void *syscall_arg asm ("r3") = addr;
-  register int syscall_number asm ("r0") = SYS_ify (brk);
-  register void *newbrk asm ("r3");
-  asm ("sc"
-       : "=r" (newbrk)
-       : "r" (syscall_arg), "r" (syscall_number)
-       : "r4","r5","r6","r7","r8","r9","r10","r11","r12",
-         "ctr", "mq", "cr0", "cr1", "cr6", "cr7");
-
-  __curbrk = newbrk;
-
-  if (newbrk < addr)
-    {
-      __set_errno (ENOMEM);
-      return -1;
-    }
-
-  return 0;
-}
 weak_alias (__brk, brk)
diff --git a/sysdeps/unix/sysv/linux/powerpc/clone.S b/sysdeps/unix/sysv/linux/powerpc/clone.S
index cca63fe0bc..6209922b6b 100644
--- a/sysdeps/unix/sysv/linux/powerpc/clone.S
+++ b/sysdeps/unix/sysv/linux/powerpc/clone.S
@@ -30,13 +30,12 @@
 ENTRY(__clone)
 	/* Set up stack frame, save registers.  */
 	stwu  %r1,-32(%r1)
-	stw   %r31,16(%r1)
-	stw   %r30,20(%r1)
-
 	/* Check for child_stack == NULL || fn == NULL.  */
 	cmpwi %cr0,%r4,0
-	beq-  %cr0,badargs
+	stw   %r31,16(%r1)
 	cmpwi %cr1,%r3,0
+	stw   %r30,20(%r1)
+	beq-  %cr0,badargs
 	beq-  %cr1,badargs
 
 	/* Set up stack frame for child.  */
@@ -45,7 +44,7 @@ ENTRY(__clone)
 	li    %r0,0
 	stw   %r0,0(%r4)
 
-	/* Save new stack, fn, args across syscall.  */
+	/* Save fn, args across syscall.  */
 	mr    %r30,%r3		/* Function in r30.  */
 	mr    %r31,%r6		/* Arguments in r31.  */
 
@@ -70,21 +69,15 @@ child:
 	mr    %r3,%r31
 	blrl
 	/* Call _exit with result from procedure.  */
-#ifdef PIC
-	b _exit@plt
-#else
-	b _exit
-#endif
+	b JUMPTARGET(_exit)
 
 badargs:
-	li 3,-EINVAL
+	li    %r3,EINVAL
 error:
-#ifdef PIC
-	b __syscall_error@plt
-#else
-	b __syscall_error
-#endif
-
-PSEUDO_END (__clone)
+	lwz   %r31,16(%r1)
+	lwz   %r30,20(%r1)
+	addi  %r1,%r1,32
+	b JUMPTARGET(__syscall_error)
+END (__clone)
 
 weak_alias (__clone, clone)
diff --git a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
index fed0913574..4be6f11270 100644
--- a/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
+++ b/sysdeps/unix/sysv/linux/powerpc/profil-counter.h
@@ -17,10 +17,18 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <signal.h>
+#include <sys/ptrace.h>
+
+/* You can also do this by using
+   void
+   profil_counter (int signo, struct pt_regs *pt)
+   {
+     profil_count ((void *) pt->nip);
+   }
+   */
 
 void
-profil_counter (int signo, struct sigcontext sc)
+profil_counter (int signo, void **regs)
 {
-  profil_count ((void *) sc.regs->nip);
+  profil_count (regs[PT_NIP]);
 }
diff --git a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
index 748c26761f..9b9413e2f3 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
+++ b/sysdeps/unix/sysv/linux/powerpc/sigreturn.S
@@ -18,9 +18,6 @@
 
 #include <sysdep.h>
 
-/* The 'sigreturn' syscall does not return.  */
-
-	.text
-ENTRY(__sigreturn)
-	DO_CALL(SYS_ify(sigreturn))
-PSEUDO_END (__sigreturn)
+PSEUDO (__sigreturn, sigreturn, 1)
+	/* Shouldn't get here.  */
+PSEUDO_END(__sigreturn)
diff --git a/sysdeps/unix/sysv/linux/powerpc/socket.S b/sysdeps/unix/sysv/linux/powerpc/socket.S
index 904bca4dc3..681f7e6445 100644
--- a/sysdeps/unix/sysv/linux/powerpc/socket.S
+++ b/sysdeps/unix/sysv/linux/powerpc/socket.S
@@ -71,17 +71,11 @@ ENTRY(P(__,socket))
 #if NARGS >= 9
 #error too many arguments!
 #endif
-	li   %r3,P(SOCKOP_,socket)
-	addi %r4,%r1,stackblock
+	li	%r3,P(SOCKOP_,socket)
+	addi	%r4,%r1,stackblock
 	DO_CALL(SYS_ify(socketcall))
-	addi %r1,%r1,48
-	bnslr
-#ifdef PIC
-	b __syscall_error@plt
-#else
-	b __syscall_error
-#endif
-
+	addi	%r1,%r1,48
+	PSEUDO_RET
 PSEUDO_END (P(__,socket))
 
 weak_alias (P(__,socket), socket)
diff --git a/sysdeps/unix/sysv/linux/powerpc/syscall.S b/sysdeps/unix/sysv/linux/powerpc/syscall.S
index 2cb548245b..4d55076907 100644
--- a/sysdeps/unix/sysv/linux/powerpc/syscall.S
+++ b/sysdeps/unix/sysv/linux/powerpc/syscall.S
@@ -18,7 +18,6 @@
 
 #include <sysdep.h>
 
-	.text
 ENTRY (syscall)
 	mr   %r0,%r3
 	mr   %r3,%r4
@@ -27,10 +26,5 @@ ENTRY (syscall)
 	mr   %r6,%r7
 	mr   %r7,%r8
 	sc
-	bnslr
-#ifdef PIC
-	b __syscall_error@plt
-#else
-	b __syscall_error
-#endif
+	PSEUDO_RET
 PSEUDO_END (syscall)
diff --git a/sysdeps/unix/sysv/linux/powerpc/sysdep.h b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
index 577809acb8..944793d56f 100644
--- a/sysdeps/unix/sysv/linux/powerpc/sysdep.h
+++ b/sysdeps/unix/sysv/linux/powerpc/sysdep.h
@@ -31,32 +31,113 @@
 
 #ifdef ASSEMBLER
 
-#define ENTRY(name)                                                           \
-  .globl name;							              \
-  .type name,@function;						              \
-  .align 2;								      \
+/* This seems to always be the case on PPC.  */
+#define ALIGNARG(log2) log2
+/* For ELF we need the `.type' directive to make shared libs work right.  */
+#define ASM_TYPE_DIRECTIVE(name,typearg) .type name,typearg;
+#define ASM_SIZE_DIRECTIVE(name) .size name,.-name
+
+/* If compiled for profiling, call `_mcount' at the start of each function.  */
+#ifdef	PROF
+/* 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;								      \
+  mflr  %r0;								      \
+  stw   %r0,4(%r1);	       						      \
+  bl    _GLOBAL_OFFSET_TABLE_@local-4;					      \
+  mflr  %r11;								      \
+  lwz   %r0,0b@got(%r11);						      \
+  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 */
+
+#define	ENTRY(name)							      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT
+
+#define EALIGN_W_0  /* No words to insert.  */
+#define EALIGN_W_1  nop
+#define EALIGN_W_2  nop;nop
+#define EALIGN_W_3  nop;nop;nop
+#define EALIGN_W_4  EALIGN_W_3;nop
+#define EALIGN_W_5  EALIGN_W_4;nop
+#define EALIGN_W_6  EALIGN_W_5;nop
+#define EALIGN_W_7  EALIGN_W_6;nop
+
+/* EALIGN is like ENTRY, but does alignment to 'words'*4 bytes
+   past a 2^align boundary.  */
+#ifdef PROF
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
+  .align ALIGNARG(2);							      \
+  C_LABEL(name)								      \
+  CALL_MCOUNT								      \
+  b 0f;									      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
+  0:
+#else /* PROF */
+#define EALIGN(name, alignt, words)					      \
+  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME(name);				      \
+  ASM_TYPE_DIRECTIVE (C_SYMBOL_NAME(name),@function)			      \
+  .align ALIGNARG(alignt);						      \
+  EALIGN_W_##words;							      \
   C_LABEL(name)
+#endif
+
+#undef	END
+#define END(name)							      \
+  ASM_SIZE_DIRECTIVE(name)
 
 #define DO_CALL(syscall)				      		      \
     li 0,syscall;						              \
     sc
 
 #ifdef PIC
+#define JUMPTARGET(name) name##@plt
+#else
+#define JUMPTARGET(name) name
+#endif
+
 #define PSEUDO(name, syscall_name, args)				      \
   .section ".text";							      \
   ENTRY (name)								      \
-    DO_CALL (SYS_ify (syscall_name));					      \
+    DO_CALL (SYS_ify (syscall_name));
+
+#define PSEUDO_RET							      \
     bnslr;								      \
-    b __syscall_error@plt
-#else
-#define PSEUDO(name, syscall_name, args)                                      \
-  .section ".text";							      \
-  ENTRY (name)                                                                \
-    DO_CALL (SYS_ify (syscall_name));				              \
-    bnslr;                                                                    \
-    b __syscall_error
-#endif
+    b JUMPTARGET(__syscall_error)
+#define ret PSEUDO_RET
+
+#undef	PSEUDO_END
+#define	PSEUDO_END(name)						      \
+  END (name)
 
-#define ret	/* Nothing (should be 'blr', but never reached).  */
+/* Local labels stripped out by the linker.  */
+#define L(x) .L##x
 
 #endif	/* ASSEMBLER */
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
index 8a14f99f43..46867d8e41 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/ioctls.h
@@ -33,10 +33,10 @@
 #undef  TCSETS
 #undef  TCSETSW
 #undef  TCSETSF
-#define TCGETS	_IOR ('t', 19, struct __kernel_termios)
-#define TCSETS	_IOW ('t', 20, struct __kernel_termios)
-#define TCSETSW	_IOW ('t', 21, struct __kernel_termios)
-#define TCSETSF	_IOW ('t', 22, struct __kernel_termios)
+#define TCGETS	_IOR ('T', 8, struct __kernel_termios)
+#define TCSETS	_IOW ('T', 9, struct __kernel_termios)
+#define TCSETSW	_IOW ('T', 10, struct __kernel_termios)
+#define TCSETSF	_IOW ('T', 11, struct __kernel_termios)
 
 #include <linux/sockios.h>
 
diff --git a/sysdeps/unix/sysv/linux/sparc/bits/termios.h b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
index bf7aa1480f..54ac773b70 100644
--- a/sysdeps/unix/sysv/linux/sparc/bits/termios.h
+++ b/sysdeps/unix/sysv/linux/sparc/bits/termios.h
@@ -20,9 +20,9 @@
 #ifndef _SPARC_TERMBITS_H
 #define _SPARC_TERMBITS_H	1
 
-typedef unsigned char   cc_t;
-typedef unsigned int    speed_t;
-typedef unsigned long   tcflag_t;
+typedef unsigned char cc_t;
+typedef unsigned int speed_t;
+typedef unsigned int tcflag_t;
 
 #define NCCS 17
 struct termios
@@ -31,11 +31,11 @@ struct termios
     tcflag_t c_oflag;		/* output mode flags */
     tcflag_t c_cflag;		/* control mode flags */
     tcflag_t c_lflag;		/* local mode flags */
-    cc_t c_line;			/* line discipline */
+    cc_t c_line;		/* line discipline */
     cc_t c_cc[NCCS];		/* control characters */
 #ifdef __KERNEL__
 #define SIZEOF_USER_TERMIOS sizeof (struct termios) - (2*sizeof (cc_t))
-    cc_t _x_cc[2];                  /* We need them to hold vmin/vtime */
+    cc_t _x_cc[2];		/* We need them to hold vmin/vtime */
 #endif
   };
 
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
index c4563776b6..bcc134e09c 100644
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
+++ b/sysdeps/unix/sysv/linux/sparc/sparc64/longjmp.S
@@ -44,3 +44,5 @@ ENTRY(longjmp)
 END(longjmp)
 
 strong_alias(longjmp, __longjmp)
+eak_alias(longjmp, _longjmp)
+weak_alias(longjmp, siglongjmp)
diff --git a/sysdeps/vax/strcmp.s b/sysdeps/vax/strcmp.s
new file mode 100644
index 0000000000..c9c5b479ae
--- /dev/null
+++ b/sysdeps/vax/strcmp.s
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+	.asciz "@(#)strcmp.s	5.6 (Berkeley) 6/1/90"
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Compare string s1 lexicographically to string s2.
+ * Return:
+ *	0	s1 == s2
+ *	> 0	s1 > s2
+ *	< 0	s2 < s2
+ *
+ * strcmp(s1, s2)
+ *	char *s1, *s2;
+ */
+#include "DEFS.h"
+
+ENTRY(strcmp, 0)
+	movl	4(ap),r1	# r1 = s1
+	movl	8(ap),r3	# r3 = s2
+	subb3	(r3),(r1),r0	# quick check for first char different
+	beql	1f		# have to keep checking
+	cvtbl	r0,r0
+	ret
+1:
+	clrl	r5		# calculate min bytes to next page boundary
+	subb3	r1,$255,r5	# r5 = (bytes - 1) to end of page for s1
+	subb3	r3,$255,r0	# r0 = (bytes - 1) to end of page for s2
+	cmpb	r0,r5		# r5 = min(r0, r5);
+	bgtru	2f
+	movb	r0,r5
+2:
+	incl	r5		# r5 = min bytes to next page boundary
+	cmpc3	r5,(r1),(r3)	# compare strings
+	bneq	3f
+	subl2	r5,r1		# check if found null yet
+	locc	$0,r5,(r1)
+	beql	1b		# not yet done, continue checking
+	subl2	r0,r3
+	mnegb	(r3),r0		# r0 = '\0' - *s2
+	cvtbl	r0,r0
+	ret
+3:
+	subl2	r0,r5		# check for null in matching string
+	subl2	r5,r1
+	locc	$0,r5,(r1)
+	bneq	4f
+	subb3	(r3),(r1),r0	# r0 = *s1 - *s2
+	cvtbl	r0,r0
+	ret
+4:
+	clrl	r0		# both the same to null
+	ret