This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] powerp-cpu add-on for --with-cpu


A minor update with the addition of a POWER4/5 optimized strncmp for
both 32- and 64-bit. Also eliminated some reduncdant code using Implies
from power5 back to power4. At the moment the power5 looks bare but we
will be filling the power5 parts of the tree once we learn how best to
exploit the new "population count bytes" instruction.

I believe this configurartion is stable and I think it is ready to
commit to cvs. The rest of the work involves increamentally populating
the tree with optimizations.
2005-12-06  Steven Munroe  <sjmunroe@us.ibm.com>

	* Makefile: New file.
	* configure: New file.
	* sysdeps/powerpc/fpu/bits/mathinline.h: New file.
	* sysdeps/powerpc/powerpc32/power4/fpu/Implies: New file.
	* sysdeps/powerpc/powerpc32/power4/memcmp.S: New file.
	* sysdeps/powerpc/powerpc32/power4/memcpy.S: New file.
	* sysdeps/powerpc/powerpc32/power4/memset.S: New file.
	* sysdeps/powerpc/powerpc32/power4/strncmp.S: New file.
	* sysdeps/powerpc/powerpc32/power5/Implies: New file.
	* sysdeps/powerpc/powerpc32/power5/fpu/Implies: New file.
	* sysdeps/powerpc/powerpc32/powerpc64/Makefile: New file.
	* sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S: New file.
	* sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S: New file.
	* sysdeps/powerpc/powerpc32/powerpc64/hp-timing.c: New file.
	* sysdeps/powerpc/powerpc32/powerpc64/hp-timing.h: New file.
	* sysdeps/powerpc/powerpc64/power4/memcmp.S: New file.
	* sysdeps/powerpc/powerpc64/power4/memcpy.S: New file.
	* sysdeps/powerpc/powerpc64/power4/strncmp.S: New file.
	* sysdeps/powerpc/powerpc64/power5/Implies: New file.
	* sysdeps/unix/sysv/linux/powerpc/dl-procinfo.c: New file.
	* sysdeps/unix/sysv/linux/powerpc/dl-procinfo.h: New file.


diff -urN dummy-cpu/Makefile libc24/power-cpu/Makefile
--- dummy-cpu/Makefile	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/Makefile	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,6 @@
+# This boilerplate is necessary just because any add-on directory
+# gets added as a normal subdirectory for the glibc build process.
+
+subdir = $(notdir $(shell pwd))
+
+include ../Rules
diff -urN dummy-cpu/configure libc24/power-cpu/configure
--- dummy-cpu/configure	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/configure	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,3 @@
+# This is only to keep the GNU C library configure mechanism happy.
+# This is a shell script fragment sourced by the main configure script.
+# We have nothing we need to add here.
diff -urN dummy-cpu/sysdeps/powerpc/fpu/bits/mathinline.h libc24/power-cpu/sysdeps/powerpc/fpu/bits/mathinline.h
--- dummy-cpu/sysdeps/powerpc/fpu/bits/mathinline.h	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/fpu/bits/mathinline.h	Wed Nov 30 14:24:57 2005
@@ -0,0 +1,228 @@
+/* Inline math functions for powerpc.
+   Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2004
+   Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _MATH_H
+# error "Never use <bits/mathinline.h> directly; include <math.h> instead."
+#endif
+
+#ifdef __cplusplus
+# define __MATH_INLINE __inline
+#else
+# define __MATH_INLINE extern __inline
+#endif  /* __cplusplus */
+
+#if defined __GNUC__ && !defined _SOFT_FLOAT
+
+#ifdef __USE_ISOC99
+# if !__GNUC_PREREQ (2,97)
+#  define __unordered_cmp(x, y) \
+  (__extension__							      \
+   ({ __typeof__(x) __x = (x); __typeof__(y) __y = (y);			      \
+      unsigned __r;							      \
+      __asm__("fcmpu 7,%1,%2 ; mfcr %0" : "=r" (__r) : "f" (__x), "f"(__y)    \
+              : "cr7");  \
+      __r; }))
+
+#  undef isgreater
+#  undef isgreaterequal
+#  undef isless
+#  undef islessequal
+#  undef islessgreater
+#  undef isunordered
+
+#  define isgreater(x, y) (__unordered_cmp (x, y) >> 2 & 1)
+#  define isgreaterequal(x, y) ((__unordered_cmp (x, y) & 6) != 0)
+#  define isless(x, y) (__unordered_cmp (x, y) >> 3 & 1)
+#  define islessequal(x, y) ((__unordered_cmp (x, y) & 0xA) != 0)
+#  define islessgreater(x, y) ((__unordered_cmp (x, y) & 0xC) != 0)
+#  define isunordered(x, y) (__unordered_cmp (x, y) & 1)
+
+# endif /* __GNUC_PREREQ (2,97) */
+
+/* The gcc, version 2.7 or below, has problems with all this inlining
+   code.  So disable it for this version of the compiler.  */
+# if __GNUC_PREREQ (2, 8)
+/* Test for negative number.  Used in the signbit() macro.  */
+__MATH_INLINE int
+__NTH (__signbitf (float __x))
+{
+  __extension__ union { float __f; int __i; } __u = { __f: __x };
+  return __u.__i < 0;
+}
+__MATH_INLINE int
+__NTH (__signbit (double __x))
+{
+  __extension__ union { double __d; int __i[2]; } __u = { __d: __x };
+  return __u.__i[0] < 0;
+}
+# endif
+#endif /* __USE_ISOC99 */
+
+#if !defined __NO_MATH_INLINES && defined __OPTIMIZE__
+
+#ifdef __USE_ISOC99
+
+# ifndef __powerpc64__
+__MATH_INLINE long int lrint (double __x) __THROW;
+__MATH_INLINE long int
+__NTH (lrint (double __x))
+{
+  union {
+    double __d;
+    int __ll[2];
+  } __u;
+  __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
+  return __u.__ll[1];
+}
+__MATH_INLINE long int lrintf (float __x) __THROW;
+__MATH_INLINE long int
+__NTH (lrintf (float __x))
+{
+  union {
+    double __d;
+    int __ll[2];
+  } __u;
+  __asm__ ("fctiw %0,%1" : "=f"(__u.__d) : "f"(__x));
+  return __u.__ll[1];
+}
+
+#  if defined _ARCH_PWR4 || defined _ARCH_PWR5 || defined _ARCH_PWR5X
+/* All POWER4, POWER5, and POWER5X processors implement convert to
+   integer double which is available in 32-bit mode.  */
+__MATH_INLINE long long llrintf (float __x) __THROW;
+__MATH_INLINE long long
+__NTH (llrintf (float __x))
+{
+  union {
+    double __d;
+    long long __ll;
+  } __u;
+  __asm__ ("fctid %0,%1" : "=f"(__u.__d) : "f"(__x));
+  return __u.__ll;
+}
+__MATH_INLINE long long llrint (double __x) __THROW;
+__MATH_INLINE long long
+__NTH (llrint (double __x))
+{
+  union {
+    double __d;
+    long long __ll;
+  } __u;
+  __asm__ ("fctid %0,%1" : "=f"(__u.__d) : "f"(__x));
+  return __u.__ll;
+}
+#  endif
+# endif
+
+__MATH_INLINE double fdim (double __x, double __y) __THROW;
+__MATH_INLINE double
+__NTH (fdim (double __x, double __y))
+{
+  return __x <= __y ? 0 : __x - __y;
+}
+
+__MATH_INLINE float fdimf (float __x, float __y) __THROW;
+__MATH_INLINE float
+__NTH (fdimf (float __x, float __y))
+{
+  return __x <= __y ? 0 : __x - __y;
+}
+
+#endif /* __USE_ISOC99 */
+#endif /* !__NO_MATH_INLINES && __OPTIMIZE__ */
+
+/* This code is used internally in the GNU libc.  */
+#  ifdef __LIBC_INTERNAL_MATH_INLINES
+#   if defined _ARCH_PWR4 || defined _ARCH_PWR5 || defined _ARCH_PWR5X
+/* All POWER4, POWER5, and POWER5X processors implement fsqrt.  */
+__MATH_INLINE double
+__NTH (__ieee754_sqrt (double __x))
+{
+  double __z;
+
+     __asm __volatile (
+	"	fsqrt	%0,%1\n"
+		: "=f" (__z)
+		: "f" (__x));
+
+  return __z;
+}
+
+__MATH_INLINE float
+__NTH (__ieee754_sqrtf (float __x))
+{
+  float __z;
+     __asm __volatile (
+	"	fsqrts	%0,%1\n"
+		: "=f" (__z)
+		: "f" (__x));
+
+  return __z;
+}
+#   else
+#include <sysdep.h>
+#include <ldsodefs.h>
+
+extern double __slow_ieee754_sqrt (double);
+__MATH_INLINE double
+__NTH (__ieee754_sqrt (double __x))
+{
+  double __z;
+
+  /* If the CPU is 64-bit we can use the optional FP instructions.  */
+  if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+  {
+    /* Volatile is required to prevent the compiler from moving the
+       fsqrt instruction above the branch.  */
+     __asm __volatile (
+	"	fsqrt	%0,%1\n"
+		: "=f" (__z)
+		: "f" (__x));
+  }
+  else
+     __z = __slow_ieee754_sqrt(__x);
+
+  return __z;
+}
+
+extern float __slow_ieee754_sqrtf (float);
+__MATH_INLINE float
+__NTH (__ieee754_sqrtf (float __x))
+{
+  float __z;
+
+  /* If the CPU is 64-bit we can use the optional FP instructions we.  */
+  if ((GLRO(dl_hwcap) & PPC_FEATURE_64) != 0)
+  {
+    /* Volatile is required to prevent the compiler from moving the
+       fsqrts instruction above the branch.  */
+     __asm __volatile (
+	"	fsqrts	%0,%1\n"
+		: "=f" (__z)
+		: "f" (__x));
+  }
+  else
+     __z = __slow_ieee754_sqrtf(__x);
+
+  return __z;
+}
+#   endif /* _ARCH_PWR4++ */
+#  endif /* __LIBC_INTERNAL_MATH_INLINES */
+#endif /* __GNUC__ && !_SOFT_FLOAT */
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies
--- dummy-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,1 @@
+powerpc/powerpc32/powerpc64/fpu
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S
--- dummy-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,969 @@
+/* Optimized strcmp implementation for PowerPC64.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
+
+EALIGN (BP_SYM(memcmp), 4, 0)
+	CALL_MCOUNT
+
+#define rTMP	r0
+#define rRTN	r3
+#define rSTR1	r3	/* first string arg */
+#define rSTR2	r4	/* second string arg */
+#define rN	r5	/* max string length */
+#define rWORD1	r6	/* current word in s1 */
+#define rWORD2	r7	/* current word in s2 */
+#define rWORD3	r8	/* next word in s1 */
+#define rWORD4	r9	/* next word in s2 */
+#define rWORD5	r10	/* next word in s1 */
+#define rWORD6	r11	/* next word in s2 */
+#define rBITDIF	r12	/* bits that differ in s1 & s2 words */
+#define rWORD7	r30	/* next word in s1 */
+#define rWORD8	r31	/* next word in s2 */
+
+	xor	rTMP, rSTR2, rSTR1
+	cmplwi	cr6, rN, 0
+	cmplwi	cr1, rN, 12
+	clrlwi.	rTMP, rTMP, 30
+	clrlwi	rBITDIF, rSTR1, 30
+	cmplwi	cr5, rBITDIF, 0
+	beq-	cr6, L(zeroLength)
+	dcbt	0,rSTR1
+	dcbt	0,rSTR2
+/* If less than 8 bytes or not aligned, use the unaligned
+   byte loop.  */
+	blt	cr1, L(bytealigned)
+        stwu    1,-64(1)
+        stw     r31,48(1)  
+        stw     r30,44(1)
+	bne	L(unaligned)
+/* At this point we know both strings have the same alignment and the
+   compare length is at least 8 bytes.  rBITDIF contains the low order
+   2 bits of rSTR1 and cr5 contains the result of the logical compare
+   of rBITDIF to 0.  If rBITDIF == 0 then we are already word 
+   aligned and can perform the word aligned loop.
+  
+   Otherwise we know the two strings have the same alignment (but not
+   yet word aligned).  So we force the string addresses to the next lower
+   word boundary and special case this first word using shift left to
+   eliminate bits preceeding the first byte.  Since we want to join the
+   normal (word aligned) compare loop, starting at the second word,
+   we need to adjust the length (rN) and special case the loop
+   versioning for the first word. This insures that the loop count is
+   correct and the first word (shifted) is in the expected register pair. */
+	.align 4
+L(samealignment):
+	clrrwi	rSTR1, rSTR1, 2
+	clrrwi	rSTR2, rSTR2, 2
+	beq	cr5, L(Waligned)
+	add	rN, rN, rBITDIF
+	slwi	r11, rBITDIF, 3
+	srwi	rTMP, rN, 4	 /* Divide by 16 */
+	andi.	rBITDIF, rN, 12  /* Get the word remainder */
+	lwz	rWORD1, 0(rSTR1)
+	lwz	rWORD2, 0(rSTR2)
+	cmplwi	cr1, rBITDIF, 8
+	cmplwi	cr7, rN, 16
+	clrlwi	rN, rN, 30
+	beq	L(dPs4)
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	bgt	cr1, L(dPs3)
+	beq	cr1, L(dPs2)
+
+/* Remainder is 4 */
+	.align 3
+L(dsP1):
+	slw	rWORD5, rWORD1, r11
+	slw	rWORD6, rWORD2, r11
+	cmplw	cr5, rWORD5, rWORD6
+	blt	cr7, L(dP1x)
+/* Do something useful in this cycle since we have to branch anyway.  */
+	lwz	rWORD1, 4(rSTR1)
+	lwz	rWORD2, 4(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	b	L(dP1e)
+/* Remainder is 8 */
+	.align 4
+L(dPs2):
+	slw	rWORD5, rWORD1, r11
+	slw	rWORD6, rWORD2, r11
+	cmplw	cr6, rWORD5, rWORD6
+	blt	cr7, L(dP2x)
+/* Do something useful in this cycle since we have to branch anyway.  */
+	lwz	rWORD7, 4(rSTR1)
+	lwz	rWORD8, 4(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	b	L(dP2e)
+/* Remainder is 12 */
+	.align 4
+L(dPs3):
+	slw	rWORD3, rWORD1, r11
+	slw	rWORD4, rWORD2, r11
+	cmplw	cr1, rWORD3, rWORD4
+	b	L(dP3e)
+/* Count is a multiple of 16, remainder is 0 */
+	.align 4
+L(dPs4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	slw	rWORD1, rWORD1, r11
+	slw	rWORD2, rWORD2, r11
+	cmplw	cr0, rWORD1, rWORD2
+	b	L(dP4e)
+
+/* At this point we know both strings are word aligned and the
+   compare length is at least 8 bytes.  */
+	.align 4
+L(Waligned):
+	andi.	rBITDIF, rN, 12  /* Get the word remainder */
+	srwi	rTMP, rN, 4	 /* Divide by 16 */
+	cmplwi	cr1, rBITDIF, 8
+	cmplwi	cr7, rN, 16
+	clrlwi	rN, rN, 30
+	beq	L(dP4)
+	bgt	cr1, L(dP3)
+	beq	cr1, L(dP2)
+		
+/* Remainder is 4 */
+	.align 4
+L(dP1):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+/* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
+   (8-15 byte compare), we want to use only volatile registers.  This
+   means we can avoid restoring non-volatile registers since we did not
+   change any on the early exit path.  The key here is the non-early
+   exit path only cares about the condition code (cr5), not about which 
+   register pair was used.  */
+	lwz	rWORD5, 0(rSTR1)
+	lwz	rWORD6, 0(rSTR2)
+	cmplw	cr5, rWORD5, rWORD6
+	blt	cr7, L(dP1x)
+	lwz	rWORD1, 4(rSTR1)
+	lwz	rWORD2, 4(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+L(dP1e):
+	lwz	rWORD3, 8(rSTR1)
+	lwz	rWORD4, 8(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	lwz	rWORD5, 12(rSTR1)
+	lwz	rWORD6, 12(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr5, L(dLcr5)
+	bne	cr0, L(dLcr0)
+	
+	lwzu	rWORD7, 16(rSTR1)
+	lwzu	rWORD8, 16(rSTR2)
+	bne	cr1, L(dLcr1)
+	cmplw	cr5, rWORD7, rWORD8
+	bdnz	L(dLoop)
+	bne	cr6, L(dLcr6)
+        lwz     r30,44(1)
+        lwz     r31,48(1)
+	.align 3
+L(dP1x):
+	slwi.	r12, rN, 3
+	bne	cr5, L(dLcr5)
+	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+        lwz     1,0(1)
+	bne	L(d00)
+	li	rRTN, 0
+	blr
+		
+/* Remainder is 8 */
+	.align 4
+L(dP2):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	lwz	rWORD5, 0(rSTR1)
+	lwz	rWORD6, 0(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	blt	cr7, L(dP2x)
+	lwz	rWORD7, 4(rSTR1)
+	lwz	rWORD8, 4(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+L(dP2e):
+	lwz	rWORD1, 8(rSTR1)
+	lwz	rWORD2, 8(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	lwz	rWORD3, 12(rSTR1)
+	lwz	rWORD4, 12(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	addi	rSTR1, rSTR1, 4
+	addi	rSTR2, rSTR2, 4
+	bne	cr6, L(dLcr6)
+	bne	cr5, L(dLcr5)
+	b	L(dLoop2)
+/* Again we are on a early exit path (16-23 byte compare), we want to
+   only use volatile registers and avoid restoring non-volatile
+   registers.  */
+	.align 4
+L(dP2x):
+	lwz	rWORD3, 4(rSTR1)
+	lwz	rWORD4, 4(rSTR2)
+	cmplw	cr5, rWORD3, rWORD4
+	slwi.	r12, rN, 3
+	bne	cr6, L(dLcr6)
+	addi	rSTR1, rSTR1, 4
+	addi	rSTR2, rSTR2, 4
+	bne	cr5, L(dLcr5)
+	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+        lwz     1,0(1)
+	bne	L(d00)
+	li	rRTN, 0
+	blr
+		
+/* Remainder is 12 */
+	.align 4
+L(dP3):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	lwz	rWORD3, 0(rSTR1)
+	lwz	rWORD4, 0(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+L(dP3e):
+	lwz	rWORD5, 4(rSTR1)
+	lwz	rWORD6, 4(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	blt	cr7, L(dP3x)
+	lwz	rWORD7, 8(rSTR1)
+	lwz	rWORD8, 8(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	lwz	rWORD1, 12(rSTR1)
+	lwz	rWORD2, 12(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	bne	cr1, L(dLcr1)
+	bne	cr6, L(dLcr6)
+	b	L(dLoop1)
+/* Again we are on a early exit path (24-31 byte compare), we want to
+   only use volatile registers and avoid restoring non-volatile
+   registers.  */
+	.align 4
+L(dP3x):
+	lwz	rWORD1, 8(rSTR1)
+	lwz	rWORD2, 8(rSTR2)
+	cmplw	cr5, rWORD1, rWORD2
+	slwi.	r12, rN, 3
+	bne	cr1, L(dLcr1)
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	bne	cr6, L(dLcr6)
+	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+	bne	cr5, L(dLcr5)
+        lwz     1,0(1)
+	bne	L(d00)
+	li	rRTN, 0
+	blr
+	
+/* Count is a multiple of 16, remainder is 0 */
+	.align 4
+L(dP4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	lwz	rWORD1, 0(rSTR1)
+	lwz	rWORD2, 0(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+L(dP4e):
+	lwz	rWORD3, 4(rSTR1)
+	lwz	rWORD4, 4(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	lwz	rWORD5, 8(rSTR1)
+	lwz	rWORD6, 8(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	lwzu	rWORD7, 12(rSTR1)
+	lwzu	rWORD8, 12(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	bne	cr0, L(dLcr0)
+	bne	cr1, L(dLcr1)
+	bdz-	L(d24)		/* Adjust CTR as we start with +4 */
+/* This is the primary loop */
+	.align 4
+L(dLoop):
+	lwz	rWORD1, 4(rSTR1)
+	lwz	rWORD2, 4(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	bne	cr6, L(dLcr6)
+L(dLoop1):
+	lwz	rWORD3, 8(rSTR1)
+	lwz	rWORD4, 8(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr5, L(dLcr5)
+L(dLoop2):
+	lwz	rWORD5, 12(rSTR1)
+	lwz	rWORD6, 12(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	bne	cr0, L(dLcr0)
+L(dLoop3):
+	lwzu	rWORD7, 16(rSTR1)
+	lwzu	rWORD8, 16(rSTR2)
+	bne-	cr1, L(dLcr1)
+	cmplw	cr0, rWORD1, rWORD2
+	bdnz+	L(dLoop)	
+	
+L(dL4):
+	cmplw	cr1, rWORD3, rWORD4
+	bne	cr6, L(dLcr6)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr5, L(dLcr5)
+	cmplw	cr5, rWORD7, rWORD8
+L(d44):
+	bne	cr0, L(dLcr0)
+L(d34):
+	bne	cr1, L(dLcr1)
+L(d24):
+	bne	cr6, L(dLcr6)
+L(d14):
+	slwi.	r12, rN, 3
+	bne	cr5, L(dLcr5) 
+L(d04):
+        lwz     r30,44(1)
+        lwz     r31,48(1)
+        lwz     1,0(1)
+	subfic	rN, r12, 32	/* Shift count is 32 - (rN * 8).  */
+	beq	L(zeroLength)
+/* At this point we have a remainder of 1 to 3 bytes to compare.  Since
+   we are aligned it is safe to load the whole word, and use
+   shift right to eliminate bits beyond the compare length. */ 
+L(d00):
+	lwz	rWORD1, 4(rSTR1)
+	lwz	rWORD2, 4(rSTR2) 
+	srw	rWORD1, rWORD1, rN
+	srw	rWORD2, rWORD2, rN
+        cmplw   rWORD1,rWORD2
+        li      rRTN,0
+        beqlr
+        li      rRTN,1
+        bgtlr
+        li      rRTN,-1
+        blr
+
+	.align 4
+L(dLcr0):
+        lwz     r30,44(1)
+        lwz     r31,48(1)
+	li	rRTN, 1
+        lwz     1,0(1)
+	bgtlr	cr0
+	li	rRTN, -1
+	blr
+	.align 4
+L(dLcr1):
+        lwz     r30,44(1)
+        lwz     r31,48(1)
+	li	rRTN, 1
+        lwz     1,0(1)
+	bgtlr	cr1
+	li	rRTN, -1
+	blr
+	.align 4
+L(dLcr6):
+        lwz     r30,44(1)
+        lwz     r31,48(1)
+	li	rRTN, 1
+        lwz     1,0(1)
+	bgtlr	cr6
+	li	rRTN, -1
+	blr
+	.align 4
+L(dLcr5):
+        lwz     r30,44(1)
+        lwz     r31,48(1)
+L(dLcr5x):
+	li	rRTN, 1
+        lwz     1,0(1)
+	bgtlr	cr5
+	li	rRTN, -1
+	blr
+	
+	.align 4
+L(bytealigned):
+	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
+
+/* We need to prime this loop.  This loop is swing modulo scheduled
+   to avoid pipe delays.  The dependent instruction latencies (load to 
+   compare to conditional branch) is 2 to 3 cycles.  In this loop each
+   dispatch group ends in a branch and takes 1 cycle.  Effectively
+   the first iteration of the loop only serves to load operands and 
+   branches based on compares are delayed until the next loop. 
+
+   So we must precondition some registers and condition codes so that
+   we don't exit the loop early on the first iteration.  */
+   
+	lbz	rWORD1, 0(rSTR1)
+	lbz	rWORD2, 0(rSTR2)
+	bdz-	L(b11)
+	cmplw	cr0, rWORD1, rWORD2
+	lbz	rWORD3, 1(rSTR1)
+	lbz	rWORD4, 1(rSTR2)
+	bdz-	L(b12)
+	cmplw	cr1, rWORD3, rWORD4
+	lbzu	rWORD5, 2(rSTR1)
+	lbzu	rWORD6, 2(rSTR2)
+	bdz-	L(b13)
+	.align 4
+L(bLoop):
+	lbzu	rWORD1, 1(rSTR1)
+	lbzu	rWORD2, 1(rSTR2)
+	bne-	cr0, L(bLcr0)
+
+	cmplw	cr6, rWORD5, rWORD6
+	bdz-	L(b3i)
+	
+	lbzu	rWORD3, 1(rSTR1)
+	lbzu	rWORD4, 1(rSTR2)
+	bne-	cr1, L(bLcr1)
+
+	cmplw	cr0, rWORD1, rWORD2
+	bdz-	L(b2i)
+
+	lbzu	rWORD5, 1(rSTR1)
+	lbzu	rWORD6, 1(rSTR2)
+	bne-	cr6, L(bLcr6)
+
+	cmplw	cr1, rWORD3, rWORD4
+	bdnz+	L(bLoop)
+	
+/* We speculatively loading bytes before we have tested the previous
+   bytes.  But we must avoid overrunning the length (in the ctr) to
+   prevent these speculative loads from causing a segfault.  In this 
+   case the loop will exit early (before the all pending bytes are
+   tested.  In this case we must complete the pending operations
+   before returning.  */
+L(b1i):
+	bne-	cr0, L(bLcr0)
+	bne-	cr1, L(bLcr1)
+	b	L(bx56)
+	.align 4
+L(b2i):
+	bne-	cr6, L(bLcr6)
+	bne-	cr0, L(bLcr0)
+	b	L(bx34)
+	.align 4
+L(b3i):
+	bne-	cr1, L(bLcr1)
+	bne-	cr6, L(bLcr6)
+	b	L(bx12)
+	.align 4
+L(bLcr0):
+	li	rRTN, 1
+	bgtlr	cr0
+	li	rRTN, -1
+	blr
+L(bLcr1):
+	li	rRTN, 1
+	bgtlr	cr1
+	li	rRTN, -1
+	blr
+L(bLcr6):
+	li	rRTN, 1
+	bgtlr	cr6
+	li	rRTN, -1
+	blr
+
+L(b13):
+	bne-	cr0, L(bx12)
+	bne-	cr1, L(bx34)
+L(bx56):
+	sub	rRTN, rWORD5, rWORD6
+	blr
+	nop
+L(b12):
+	bne-	cr0, L(bx12)
+L(bx34):	
+	sub	rRTN, rWORD3, rWORD4
+	blr
+
+L(b11):
+L(bx12):
+	sub	rRTN, rWORD1, rWORD2
+	blr
+
+	.align 4 
+L(zeroLengthReturn):
+
+L(zeroLength):
+	li	rRTN, 0
+	blr
+
+	.align 4
+/* At this point we know the strings have different alignment and the
+   compare length is at least 8 bytes.  rBITDIF contains the low order
+   2 bits of rSTR1 and cr5 contains the result of the logical compare
+   of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is word aligned and can 
+   perform the Wunaligned loop.
+  
+   Otherwise we know that rSTR1 is not aready word aligned yet.
+   So we can force the string addresses to the next lower word
+   boundary and special case this first word using shift left to
+   eliminate bits preceeding the first byte.  Since we want to join the
+   normal (Wualigned) compare loop, starting at the second word,
+   we need to adjust the length (rN) and special case the loop
+   versioning for the first W. This insures that the loop count is
+   correct and the first W (shifted) is in the expected resister pair.  */
+#define rSHL		r29	/* Unaligned shift left count.  */
+#define rSHR		r28	/* Unaligned shift right count.  */
+#define rB		r27	/* Left rotation temp for rWORD2.  */
+#define rD		r26	/* Left rotation temp for rWORD4.  */
+#define rF		r25	/* Left rotation temp for rWORD6.  */
+#define rH		r24	/* Left rotation temp for rWORD8.  */
+#define rA		r0	/* Right rotation temp for rWORD2.  */
+#define rC		r12	/* Right rotation temp for rWORD4.  */
+#define rE		r0	/* Right rotation temp for rWORD6.  */
+#define rG		r12	/* Right rotation temp for rWORD8.  */
+L(unaligned):
+	stw     r29,40(r1)	
+	clrlwi	rSHL, rSTR2, 30
+        stw     r28,36(r1)
+	beq	cr5, L(Wunaligned)
+        stw     r27,32(r1)
+/* Adjust the logical start of rSTR2 to compensate for the extra bits
+   in the 1st rSTR1 W.  */
+	sub	r27, rSTR2, rBITDIF
+/* But do not attempt to address the W before that W that contains
+   the actual start of rSTR2.  */
+	clrrwi	rSTR2, rSTR2, 2
+        stw     r26,28(r1)
+/* Compute the left/right shift counts for the unalign rSTR2,
+   compensating for the logical (W aligned) start of rSTR1.  */ 
+	clrlwi	rSHL, r27, 30
+	clrrwi	rSTR1, rSTR1, 2	
+        stw     r25,24(r1)
+	slwi	rSHL, rSHL, 3
+	cmplw	cr5, r27, rSTR2
+	add	rN, rN, rBITDIF
+	slwi	r11, rBITDIF, 3
+        stw     r24,20(r1)
+	subfic	rSHR, rSHL, 32
+	srwi	rTMP, rN, 4      /* Divide by 16 */
+	andi.	rBITDIF, rN, 12  /* Get the W remainder */
+/* We normally need to load 2 Ws to start the unaligned rSTR2, but in
+   this special case those bits may be discarded anyway.  Also we
+   must avoid loading a W where none of the bits are part of rSTR2 as
+   this may cross a page boundary and cause a page fault.  */
+	li	rWORD8, 0
+	blt	cr5, L(dus0)
+	lwz	rWORD8, 0(rSTR2)
+	la	rSTR2, 4(rSTR2)
+	slw	rWORD8, rWORD8, rSHL
+
+L(dus0):
+	lwz	rWORD1, 0(rSTR1)
+	lwz	rWORD2, 0(rSTR2)
+	cmplwi	cr1, rBITDIF, 8
+	cmplwi	cr7, rN, 16
+	srw	rG, rWORD2, rSHR
+	clrlwi	rN, rN, 30
+	beq	L(duPs4)
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	or	rWORD8, rG, rWORD8
+	bgt	cr1, L(duPs3)
+	beq	cr1, L(duPs2)
+
+/* Remainder is 4 */
+	.align 4
+L(dusP1):
+	slw	rB, rWORD2, rSHL
+	slw	rWORD7, rWORD1, r11
+	slw	rWORD8, rWORD8, r11
+	bge	cr7, L(duP1e)
+/* At this point we exit early with the first word compare
+   complete and remainder of 0 to 3 bytes.  See L(du14) for details on
+   how we handle the remaining bytes.  */
+	cmplw	cr5, rWORD7, rWORD8
+	slwi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmplw	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	lwz	rWORD2, 4(rSTR2)
+	srw	rA, rWORD2, rSHR
+	b	L(dutrim)
+/* Remainder is 8 */
+	.align 4
+L(duPs2):
+	slw	rH, rWORD2, rSHL
+	slw	rWORD5, rWORD1, r11
+	slw	rWORD6, rWORD8, r11
+	b	L(duP2e)
+/* Remainder is 12 */
+	.align 4
+L(duPs3):
+	slw	rF, rWORD2, rSHL
+	slw	rWORD3, rWORD1, r11
+	slw	rWORD4, rWORD8, r11
+	b	L(duP3e)
+/* Count is a multiple of 16, remainder is 0 */
+	.align 4
+L(duPs4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	or	rWORD8, rG, rWORD8
+	slw	rD, rWORD2, rSHL
+	slw	rWORD1, rWORD1, r11
+	slw	rWORD2, rWORD8, r11
+	b	L(duP4e)
+
+/* At this point we know rSTR1 is word aligned and the
+   compare length is at least 8 bytes.  */
+	.align 4
+L(Wunaligned):
+        stw     r27,32(r1)
+	clrrwi	rSTR2, rSTR2, 2
+        stw     r26,28(r1)
+	srwi	rTMP, rN, 4	 /* Divide by 16 */
+        stw     r25,24(r1)
+	andi.	rBITDIF, rN, 12  /* Get the W remainder */
+        stw     r24,20(r1)
+	slwi	rSHL, rSHL, 3
+	lwz	rWORD6, 0(rSTR2)
+	lwzu	rWORD8, 4(rSTR2)
+	cmplwi	cr1, rBITDIF, 8
+	cmplwi	cr7, rN, 16
+	clrlwi	rN, rN, 30
+	subfic	rSHR, rSHL, 32
+	slw	rH, rWORD6, rSHL
+	beq	L(duP4)
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	bgt	cr1, L(duP3)
+	beq	cr1, L(duP2)
+		
+/* Remainder is 4 */
+	.align 4
+L(duP1):
+	srw	rG, rWORD8, rSHR
+	lwz	rWORD7, 0(rSTR1)
+	slw	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	blt	cr7, L(duP1x)
+L(duP1e):
+	lwz	rWORD1, 4(rSTR1)
+	lwz	rWORD2, 4(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	srw	rA, rWORD2, rSHR
+	slw	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+	lwz	rWORD3, 8(rSTR1)
+	lwz	rWORD4, 8(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	srw	rC, rWORD4, rSHR
+	slw	rF, rWORD4, rSHL
+	bne	cr5, L(duLcr5)
+	or	rWORD4, rC, rD
+	lwz	rWORD5, 12(rSTR1)
+	lwz	rWORD6, 12(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	srw	rE, rWORD6, rSHR
+	slw	rH, rWORD6, rSHL
+	bne	cr0, L(duLcr0)
+	or	rWORD6, rE, rF
+	cmplw	cr6, rWORD5, rWORD6
+	b	L(duLoop3)	
+	.align 4
+/* At this point we exit early with the first word compare
+   complete and remainder of 0 to 3 bytes.  See L(du14) for details on
+   how we handle the remaining bytes.  */
+L(duP1x):
+	cmplw	cr5, rWORD7, rWORD8
+	slwi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmplw	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	ld	rWORD2, 8(rSTR2)
+	srw	rA, rWORD2, rSHR
+	b	L(dutrim)
+/* Remainder is 8 */
+	.align 4
+L(duP2):
+	srw	rE, rWORD8, rSHR
+	lwz	rWORD5, 0(rSTR1)
+	or	rWORD6, rE, rH
+	slw	rH, rWORD8, rSHL
+L(duP2e):
+	lwz	rWORD7, 4(rSTR1)
+	lwz	rWORD8, 4(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	srw	rG, rWORD8, rSHR
+	slw	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	blt	cr7, L(duP2x)
+	lwz	rWORD1, 8(rSTR1)
+	lwz	rWORD2, 8(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	bne	cr6, L(duLcr6)
+	srw	rA, rWORD2, rSHR
+	slw	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+	lwz	rWORD3, 12(rSTR1)
+	lwz	rWORD4, 12(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	bne	cr5, L(duLcr5)
+	srw	rC, rWORD4, rSHR
+	slw	rF, rWORD4, rSHL
+	or	rWORD4, rC, rD
+	addi	rSTR1, rSTR1, 4
+	addi	rSTR2, rSTR2, 4
+	cmplw	cr1, rWORD3, rWORD4
+	b	L(duLoop2)
+	.align 4
+L(duP2x):
+	cmplw	cr5, rWORD7, rWORD8
+	addi	rSTR1, rSTR1, 4
+	addi	rSTR2, rSTR2, 4
+	bne	cr6, L(duLcr6)
+	slwi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmplw	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	lwz	rWORD2, 4(rSTR2)
+	srw	rA, rWORD2, rSHR
+	b	L(dutrim)
+		
+/* Remainder is 12 */
+	.align 4
+L(duP3):
+	srw	rC, rWORD8, rSHR
+	lwz	rWORD3, 0(rSTR1)
+	slw	rF, rWORD8, rSHL
+	or	rWORD4, rC, rH
+L(duP3e):
+	lwz	rWORD5, 4(rSTR1)
+	lwz	rWORD6, 4(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	srw	rE, rWORD6, rSHR
+	slw	rH, rWORD6, rSHL
+	or	rWORD6, rE, rF
+	lwz	rWORD7, 8(rSTR1)
+	lwz	rWORD8, 8(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr1, L(duLcr1)
+	srw	rG, rWORD8, rSHR
+	slw	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	blt	cr7, L(duP3x)
+	lwz	rWORD1, 12(rSTR1)
+	lwz	rWORD2, 12(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	bne	cr6, L(duLcr6)
+	srw	rA, rWORD2, rSHR
+	slw	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	cmplw	cr0, rWORD1, rWORD2
+	b	L(duLoop1)
+	.align 4
+L(duP3x):
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	bne	cr1, L(duLcr1)
+	cmplw	cr5, rWORD7, rWORD8
+	bne	cr6, L(duLcr6)
+	slwi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmplw	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	lwz	rWORD2, 4(rSTR2)
+	srw	rA, rWORD2, rSHR
+	b	L(dutrim)
+	
+/* Count is a multiple of 16, remainder is 0 */
+	.align 4
+L(duP4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	srw	rA, rWORD8, rSHR
+	lwz	rWORD1, 0(rSTR1)
+	slw	rD, rWORD8, rSHL
+	or	rWORD2, rA, rH
+L(duP4e):
+	lwz	rWORD3, 4(rSTR1)
+	lwz	rWORD4, 4(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	srw	rC, rWORD4, rSHR
+	slw	rF, rWORD4, rSHL
+	or	rWORD4, rC, rD
+	lwz	rWORD5, 8(rSTR1)
+	lwz	rWORD6, 8(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	bne	cr0, L(duLcr0)
+	srw	rE, rWORD6, rSHR
+	slw	rH, rWORD6, rSHL
+	or	rWORD6, rE, rF
+	lwzu	rWORD7, 12(rSTR1)
+	lwzu	rWORD8, 12(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr1, L(duLcr1)
+	srw	rG, rWORD8, rSHR
+	slw	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	cmplw	cr5, rWORD7, rWORD8
+	bdz-	L(du24)		/* Adjust CTR as we start with +4 */
+/* This is the primary loop */
+	.align 4
+L(duLoop):
+	lwz	rWORD1, 4(rSTR1)
+	lwz	rWORD2, 4(rSTR2)
+	cmplw	cr1, rWORD3, rWORD4
+	bne	cr6, L(duLcr6)
+	srw	rA, rWORD2, rSHR
+	slw	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+L(duLoop1):
+	lwz	rWORD3, 8(rSTR1)
+	lwz	rWORD4, 8(rSTR2)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr5, L(duLcr5)
+	srw	rC, rWORD4, rSHR
+	slw	rF, rWORD4, rSHL
+	or	rWORD4, rC, rD
+L(duLoop2):
+	lwz	rWORD5, 12(rSTR1)
+	lwz	rWORD6, 12(rSTR2)
+	cmplw	cr5, rWORD7, rWORD8
+	bne	cr0, L(duLcr0)
+	srw	rE, rWORD6, rSHR
+	slw	rH, rWORD6, rSHL
+	or	rWORD6, rE, rF
+L(duLoop3):
+	lwzu	rWORD7, 16(rSTR1)
+	lwzu	rWORD8, 16(rSTR2)
+	cmplw	cr0, rWORD1, rWORD2
+	bne-	cr1, L(duLcr1)
+	srw	rG, rWORD8, rSHR
+	slw	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	bdnz+	L(duLoop)	
+	
+L(duL4):
+	bne	cr1, L(duLcr1)
+	cmplw	cr1, rWORD3, rWORD4
+	bne	cr6, L(duLcr6)
+	cmplw	cr6, rWORD5, rWORD6
+	bne	cr5, L(duLcr5)
+	cmplw	cr5, rWORD7, rWORD8
+L(du44):
+	bne	cr0, L(duLcr0)
+L(du34):
+	bne	cr1, L(duLcr1)
+L(du24):
+	bne	cr6, L(duLcr6)
+L(du14):
+	slwi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+/* At this point we have a remainder of 1 to 3 bytes to compare.  We use
+   shift right to eliminate bits beyond the compare length. 
+
+   However it may not be safe to load rWORD2 which may be beyond the 
+   string length. So we compare the bit length of the remainder to
+   the right shift count (rSHR). If the bit count is less than or equal
+   we do not need to load rWORD2 (all significant bits are already in
+   rB).  */
+	cmplw	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	lwz	rWORD2, 4(rSTR2)
+	srw	rA, rWORD2, rSHR
+	.align 4
+L(dutrim):
+	lwz	rWORD1, 4(rSTR1)
+        lwz     r31,48(1)
+	subfic	rN, rN, 32	/* Shift count is 32 - (rN * 8).  */ 
+	or	rWORD2, rA, rB
+        lwz     r30,44(1)
+        lwz     r29,40(r1)
+	srw	rWORD1, rWORD1, rN
+	srw	rWORD2, rWORD2, rN
+        lwz     r28,36(r1)	
+        lwz     r27,32(r1)
+        cmplw   rWORD1,rWORD2
+        li      rRTN,0
+        beq     L(dureturn26)
+        li      rRTN,1
+        bgt     L(dureturn26)
+        li      rRTN,-1
+	b    L(dureturn26)
+	.align 4
+L(duLcr0):
+        lwz     r31,48(1)
+        lwz     r30,44(1)
+	li	rRTN, 1
+	bgt	cr0, L(dureturn29)	
+	lwz     r29,40(r1)
+        lwz     r28,36(r1)	
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align 4
+L(duLcr1):
+        lwz     r31,48(1)
+        lwz     r30,44(1)
+	li	rRTN, 1
+	bgt	cr1, L(dureturn29)	
+        lwz     r29,40(r1)
+        lwz     r28,36(r1)	
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align 4
+L(duLcr6):
+        lwz     r31,48(1)
+        lwz     r30,44(1)
+	li	rRTN, 1
+	bgt	cr6, L(dureturn29)	
+        lwz     r29,40(r1)
+        lwz     r28,36(r1)	
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align 4
+L(duLcr5):
+        lwz     r31,48(1)
+        lwz     r30,44(1)
+	li	rRTN, 1
+	bgt	cr5, L(dureturn29)	
+        lwz     r29,40(r1)
+        lwz     r28,36(r1)	
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align	3
+L(duZeroReturn):
+	li	rRTN,0
+	.align	4
+L(dureturn):
+        lwz     r31,48(1)
+        lwz     r30,44(1)
+L(dureturn29):	
+        lwz     r29,40(r1)
+        lwz     r28,36(r1)	
+L(dureturn27):	
+        lwz     r27,32(r1)
+L(dureturn26):	
+        lwz     r26,28(r1)
+L(dureturn25):	
+        lwz     r25,24(r1)
+        lwz     r24,20(r1)
+        lwz     1,0(1)
+	blr
+
+libc_hidden_builtin_def (memcmp)
+weak_alias (memcmp, bcmp)
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S
--- dummy-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,420 @@
+/* Optimized memcpy implementation for PowerPC32 on PowerPC64.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
+   Returns 'dst'.
+
+   Memcpy handles short copies (< 32-bytes) using a binary move blocks 
+   (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled 
+   with the appropriate combination of byte and halfword load/stores. 
+   There is minimal effort to optimize the alignment of short moves.  
+
+   Longer moves (>= 32-bytes) justify the effort to get at least the
+   destination word (4-byte) aligned.  Further optimization is
+   possible when both source and destination are word aligned.
+   Each case has an optimized unrolled loop.   */
+
+EALIGN (BP_SYM (memcpy), 5, 0)
+	CALL_MCOUNT
+
+    stwu  1,-32(1)
+    stw   30,20(1)
+    mr    30,3
+    cmplwi cr1,5,31
+    neg   0,3
+    andi. 11,3,3	/* check alignment of dst.  */
+    clrlwi 0,0,30	/* Number of bytes until the 1st word of dst.  */
+    clrlwi 10,4,30	/* check alignment of src.  */
+    cmplwi cr6,5,8
+    ble-  cr1,.L2	/* If move < 32 bytes use short move code.  */
+    cmplw cr6,10,11     
+    stw   31,24(1)  
+    mr    12,4
+    srwi  9,5,2		/* Number of full words remaining.  */
+    mtcrf 0x01,0
+    mr    31,5
+    beq   .L0
+  
+    subf  31,0,5
+  /* Move 0-3 bytes as needed to get the destination word aligned.  */
+1:  bf    31,2f
+    lbz   6,0(12)
+    addi  12,12,1
+    stb   6,0(3)
+    addi  3,3,1
+2:  bf    30,0f
+    lhz   6,0(12)
+    addi  12,12,2
+    sth   6,0(3)
+    addi  3,3,2
+0:
+    clrlwi 10,12,30	/* check alignment of src again.  */     
+    srwi  9,31,2	/* Number of full words remaining.  */
+    
+  /* Copy words from source to destination, assuming the destination is 
+     aligned on a word boundary.
+
+     At this point we know there are at least 25 bytes left (32-7) to copy.
+     The next step is to determine if the source is also word aligned. 
+     If not branch to the unaligned move code at .L6. which uses
+     a load, shift, store strategy.
+     
+     Otherwise source and destination are word aligned, and we can use
+     the optimized word copy loop.  */
+.L0:
+    clrlwi	11,31,30  /* calculate the number of tail bytes */
+    mtcrf 0x01,9
+    bne-  cr6,.L6   /* If source is not word aligned.  */
+
+  /* Move words where destination and source are word aligned.
+     Use an unrolled loop to copy 4 words (16-bytes) per iteration.
+     If the the copy is not an exact multiple of 16 bytes, 1-3 
+     words are copied as needed to set up the main loop.  After
+     the main loop exits there may be a tail of 1-3 bytes. These bytes are 
+     copied a halfword/byte at a time as needed to preserve alignment.  */
+
+    srwi  8,31,4    /* calculate the 16 byte loop count */
+    cmplwi	cr1,9,4
+    cmplwi	cr6,11,0
+    mr    11,12
+    
+    bf    30,1f
+    lwz   6,0(12)
+    lwz   7,4(12)
+    addi  11,12,8
+    mtctr 8
+    stw   6,0(3)
+    stw   7,4(3)
+    addi  10,3,8
+    bf    31,4f
+    lwz   0,8(12)
+    stw   0,8(3)    
+    blt   cr1,3f
+    addi  11,12,12
+    addi  10,3,12
+    b     4f
+    .align  4
+1:
+    mr    10,3
+    mtctr 8
+    bf    31,4f
+    lwz   6,0(12)
+    addi  11,12,4
+    stw   6,0(3)
+    addi  10,3,4
+    
+    .align  4
+4:
+    lwz   6,0(11)
+    lwz   7,4(11)
+    lwz   8,8(11)
+    lwz   0,12(11)
+    stw   6,0(10)
+    stw   7,4(10)
+    stw   8,8(10)
+    stw   0,12(10)
+    addi  11,11,16
+    addi  10,10,16
+    bdnz  4b
+3:  
+    clrrwi 0,31,2
+    mtcrf 0x01,31
+    beq   cr6,0f
+.L9:
+    add   3,3,0
+    add   12,12,0
+    
+/*  At this point we have a tail of 0-3 bytes and we know that the
+    destination is word aligned.  */
+2:  bf    30,1f
+    lhz   6,0(12)
+    addi  12,12,2
+    sth   6,0(3)
+    addi  3,3,2
+1:  bf    31,0f
+    lbz   6,0(12)
+    stb   6,0(3)
+0:
+  /* Return original dst pointer.  */
+    mr  3,30
+    lwz 30,20(1)
+    lwz 31,24(1)
+    addi 1,1,32
+    blr
+       
+/* Copy up to 31 bytes.  This is divided into two cases 0-8 bytes and 
+   9-31 bytes.  Each case is handled without loops, using binary 
+   (1,2,4,8) tests.  
+   
+   In the short (0-8 byte) case no attempt is made to force alignment
+   of either source or destination.  The hardware will handle the 
+   unaligned load/stores with small delays for crossing 32- 64-byte, and 
+   4096-byte boundaries. Since these short moves are unlikely to be
+   unaligned or cross these boundaries, the overhead to force 
+   alignment is not justified.
+   
+   The longer (9-31 byte) move is more likely to cross 32- or 64-byte
+   boundaries.  Since only loads are sensitive to the 32-/64-byte
+   boundaries it is more important to align the source than the 
+   destination.  If the source is not already word aligned, we first
+   move 1-3 bytes as needed.  While the destination and stores may 
+   still be unaligned, this is only an issue for page (4096 byte
+   boundary) crossing, which should be rare for these short moves.  
+   The hardware handles this case automatically with a small delay.  */ 
+   
+    .align  4
+.L2:
+    mtcrf 0x01,5
+    neg   8,4
+    clrrwi 11,4,2
+    andi. 0,8,3
+    ble   cr6,.LE8	/* Handle moves of 0-8 bytes.  */
+/* At least 9 bytes left.  Get the source word aligned.  */
+    cmplwi	cr1,5,16
+    mr    10,5
+    mr    12,4
+    cmplwi	cr6,0,2
+    beq   .L3	/* If the source is already word aligned skip this.  */
+/* Copy 1-3 bytes to get source address word aligned.  */
+    lwz   6,0(11)
+    subf  10,0,5
+    add   12,4,0
+    blt   cr6,5f
+    srwi  7,6,16
+    bgt	  cr6,3f
+    sth   6,0(3)
+    b     7f
+    .align  4
+3:
+    stb   7,0(3)
+    sth   6,1(3)
+    b     7f
+    .align  4
+5:
+    stb   6,0(3)
+7:
+    cmplwi	cr1,10,16
+    add   3,3,0
+    mtcrf 0x01,10
+    .align  4
+.L3:
+/* At least 6 bytes left and the source is word aligned.  */
+    blt   cr1,8f
+16: /* Move 16 bytes.  */
+    lwz   6,0(12)
+    lwz   7,4(12)
+    stw   6,0(3)
+    lwz   6,8(12)
+    stw   7,4(3)
+    lwz   7,12(12)
+    addi  12,12,16
+    stw   6,8(3)
+    stw   7,12(3)
+    addi  3,3,16
+8:  /* Move 8 bytes.  */
+    bf    28,4f
+    lwz   6,0(12)
+    lwz   7,4(12)
+    addi  12,12,8
+    stw   6,0(3)
+    stw   7,4(3)
+    addi  3,3,8
+4:  /* Move 4 bytes.  */
+    bf    29,2f
+    lwz   6,0(12)
+    addi  12,12,4
+    stw   6,0(3)
+    addi  3,3,4    
+2:  /* Move 2-3 bytes.  */
+    bf    30,1f
+    lhz   6,0(12)
+    sth   6,0(3) 
+    bf    31,0f
+    lbz   7,2(12)
+    stb   7,2(3)
+    mr    3,30
+    lwz   30,20(1)
+    addi  1,1,32
+    blr
+1:  /* Move 1 byte.  */
+    bf    31,0f
+    lbz   6,0(12)
+    stb   6,0(3)
+0:
+  /* Return original dst pointer.  */
+    mr   3,30
+    lwz  30,20(1)
+    addi 1,1,32
+    blr
+
+/* Special case to copy 0-8 bytes.  */
+    .align  4
+.LE8:
+    mr    12,4
+    bne   cr6,4f
+    lwz   6,0(4)
+    lwz   7,4(4)
+    stw   6,0(3)
+    stw   7,4(3)
+  /* Return original dst pointer.  */
+    mr    3,30
+    lwz   30,20(1)
+    addi  1,1,32
+    blr
+    .align  4
+4:  bf    29,2b
+    lwz   6,0(4)
+    stw   6,0(3)
+6:
+    bf    30,5f
+    lhz   7,4(4)
+    sth   7,4(3) 
+    bf    31,0f
+    lbz   8,6(4)
+    stb   8,6(3)
+    mr    3,30
+    lwz   30,20(1)
+    addi  1,1,32
+    blr
+    .align  4
+5:  
+    bf    31,0f
+    lbz   6,4(4)
+    stb   6,4(3)
+    .align  4
+0:
+  /* Return original dst pointer.  */
+    mr   3,30
+    lwz  30,20(1)
+    addi 1,1,32
+    blr
+
+    .align  4
+.L6:
+
+  /* Copy words where the destination is aligned but the source is
+     not.  Use aligned word loads from the source, shifted to realign
+     the data, to allow aligned destination stores.  
+     Use an unrolled loop to copy 4 words (16-bytes) per iteration.
+     A single word is retained for storing at loop exit to avoid walking
+     off the end of a page within the loop.
+     If the copy is not an exact multiple of 16 bytes, 1-3 
+     words are copied as needed to set up the main loop.  After
+     the main loop exits there may be a tail of 1-3 bytes. These bytes are 
+     copied a halfword/byte at a time as needed to preserve alignment.  */
+    
+
+    cmplwi  cr6,11,0  /* are there tail bytes left ? */
+    subf    5,10,12   /* back up src pointer to prev word alignment */
+    slwi    10,10,3   /* calculate number of bits to shift 1st word left */
+    addi    11,9,-1   /* we move one word after the loop */
+    srwi    8,11,2    /* calculate the 16 byte loop count */
+    lwz     6,0(5)    /* load 1st src word into R6 */
+    mr      4,3
+    lwz     7,4(5)    /* load 2nd src word into R7 */
+    mtcrf   0x01,11
+    subfic  9,10,32   /* number of bits to shift 2nd word right */
+    mtctr   8
+    bf      30,1f
+
+    /* there are at least two words to copy, so copy them */
+    slw   0,6,10  /* shift 1st src word to left align it in R0 */
+    srw   8,7,9   /* shift 2nd src word to right align it in R8 */
+    or    0,0,8   /* or them to get word to store */
+    lwz   6,8(5)  /* load the 3rd src word */
+    stw   0,0(4)  /* store the 1st dst word */
+    slw   0,7,10  /* now left align 2nd src word into R0 */
+    srw   8,6,9   /* shift 3rd src word to right align it in R8 */
+    or    0,0,8   /* or them to get word to store */
+    lwz   7,12(5)
+    stw   0,4(4)  /* store the 2nd dst word */
+    addi  4,4,8
+    addi  5,5,16
+    bf    31,4f
+    /* there is a third word to copy, so copy it */
+    slw   0,6,10  /* shift 3rd src word to left align it in R0 */
+    srw   8,7,9   /* shift 4th src word to right align it in R8 */
+    or    0,0,8   /* or them to get word to store */
+    stw   0,0(4)  /* store 3rd dst word */
+    mr    6,7
+    lwz   7,0(5)
+    addi  5,5,4
+    addi  4,4,4
+    b     4f
+    .align 4
+1:
+    slw     0,6,10  /* shift 1st src word to left align it in R0 */
+    srw     8,7,9   /* shift 2nd src word to right align it in R8 */
+    addi  5,5,8
+    or    0,0,8   /* or them to get word to store */
+    bf    31,4f
+    mr    6,7
+    lwz   7,0(5)
+    addi  5,5,4
+    stw   0,0(4)  /* store the 1st dst word */
+    addi  4,4,4
+
+    .align  4
+4:
+    /* copy 16 bytes at a time */
+    slw   0,6,10 
+    srw   8,7,9 
+    or    0,0,8
+    lwz   6,0(5)
+    stw   0,0(4)
+    slw   0,7,10
+    srw   8,6,9
+    or    0,0,8
+    lwz   7,4(5)
+    stw   0,4(4)
+    slw   0,6,10 
+    srw   8,7,9 
+    or    0,0,8
+    lwz   6,8(5)
+    stw   0,8(4)
+    slw   0,7,10
+    srw   8,6,9 
+    or    0,0,8
+    lwz   7,12(5)
+    stw   0,12(4)
+    addi  5,5,16
+    addi  4,4,16
+    bdnz+ 4b
+8:
+    /* calculate and store the final word */
+    slw   0,6,10 
+    srw   8,7,9 
+    or    0,0,8
+    stw   0,0(4)
+3:
+    clrrwi 0,31,2
+    mtcrf 0x01,31
+    bne   cr6,.L9	/* If the tail is 0 bytes we are done!  */
+
+  /* Return original dst pointer.  */
+    mr   3,30
+    lwz  30,20(1)
+    lwz  31,24(1)
+    addi 1,1,32
+    blr
+libc_hidden_builtin_def (memcpy)
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power4/memset.S libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/memset.S
--- dummy-cpu/sysdeps/powerpc/powerpc32/power4/memset.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/memset.S	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,227 @@
+/* Optimized memset implementation for PowerPC64.
+   Copyright (C) 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* __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 (1024 bits). There is a special case for setting cache lines
+   to 0, to take advantage of the dcbz instruction.  */
+
+EALIGN (BP_SYM (memset), 5, 0)
+	CALL_MCOUNT
+
+#define rTMP	r0
+#define rRTN	r3	/* Initial value of 1st argument.  */
+#define rMEMP0	r3	/* Original value of 1st arg.  */
+#define rCHR	r4	/* Char to set in each byte.  */
+#define rLEN	r5	/* Length of region to set.  */
+#define rMEMP	r6	/* Address at which we are storing.  */
+#define rALIGN	r7	/* Number of bytes we are setting now (when aligning). */
+#define rMEMP2	r8
+
+#define rNEG64	r8	/* Constant -64 for clearing with dcbz.  */
+#define rCLS	r8	/* Cache line size (known to be 128).  */
+#define rCLM	r9	/* Cache line size mask to check for cache alignment.  */
+L(_memset):
+/* Take care of case for size <= 4.  */
+	cmplwi	cr1, rLEN, 4
+	andi.	rALIGN, rMEMP0, 3
+	mr	rMEMP, rMEMP0
+	ble-	cr1, L(small)
+
+/* Align to word boundary.  */
+	cmplwi	cr5, rLEN, 31
+	rlwimi	rCHR, rCHR, 8, 16, 23 /* Replicate byte to halfword.  */
+	beq+	L(aligned)
+	mtcrf	0x01, rMEMP0
+	subfic	rALIGN, rALIGN, 4
+	add	rMEMP, rMEMP, rALIGN
+	sub	rLEN, rLEN, rALIGN
+	bf+	31, L(g0)
+	stb	rCHR, 0(rMEMP0)
+	bt	30, L(aligned)
+L(g0):
+	sth	rCHR, -2(rMEMP)
+
+/* Handle the case of size < 31.  */
+L(aligned):
+	mtcrf	0x01, rLEN
+	rlwimi	rCHR, rCHR, 16, 0, 15 /* Replicate halfword to word.  */
+	ble	cr5, L(medium)
+/* Align to 32-byte boundary.  */
+	andi.	rALIGN, rMEMP, 0x1C
+	subfic	rALIGN, rALIGN, 0x20
+	beq	L(caligned)
+	mtcrf	0x01, rALIGN
+	add	rMEMP, rMEMP, rALIGN
+	sub	rLEN, rLEN, rALIGN
+	cmplwi	cr1, rALIGN, 0x10
+	mr	rMEMP2, rMEMP
+	bf	28, L(a1)
+        stw     rCHR, -4(rMEMP2)
+	stwu	rCHR, -8(rMEMP2)
+L(a1):	blt	cr1, L(a2)
+        stw     rCHR, -4(rMEMP2)
+	stw	rCHR, -8(rMEMP2)
+	stw	rCHR, -12(rMEMP2)
+	stwu	rCHR, -16(rMEMP2)
+L(a2):  bf      29, L(caligned)
+        stw     rCHR, -4(rMEMP2)
+
+/* Now aligned to a 32 byte boundary.  */
+L(caligned):
+	cmplwi	cr1, rCHR, 0
+	clrrwi.	rALIGN, rLEN, 5
+	mtcrf	0x01, rLEN
+	beq	cr1, L(zloopstart) /* Special case for clearing memory using dcbz.  */
+L(nondcbz):
+	srwi	rTMP, rALIGN, 5
+	mtctr	rTMP
+	beq	L(medium)	/* We may not actually get to do a full line.  */
+	clrlwi.	rLEN, rLEN, 27
+	add	rMEMP, rMEMP, rALIGN
+	li	rNEG64, -0x40
+	bdz	L(cloopdone)
+
+        .align 4
+L(c3): 	dcbtst	rNEG64, rMEMP
+        stw     rCHR, -4(rMEMP)
+	stw	rCHR, -8(rMEMP)
+        stw     rCHR, -12(rMEMP)
+	stw	rCHR, -16(rMEMP)
+        stw     rCHR, -20(rMEMP)
+	stw	rCHR, -24(rMEMP)
+        stw     rCHR, -28(rMEMP)
+	stwu	rCHR, -32(rMEMP)
+	bdnz	L(c3)
+L(cloopdone):
+        stw     rCHR, -4(rMEMP)
+	stw	rCHR, -8(rMEMP)
+        stw     rCHR, -12(rMEMP)
+	stw	rCHR, -16(rMEMP)
+	cmplwi	cr1, rLEN, 16
+        stw     rCHR, -20(rMEMP)
+	stw	rCHR, -24(rMEMP)
+        stw     rCHR, -28(rMEMP)
+	stwu	rCHR, -32(rMEMP)
+	beqlr
+	add	rMEMP, rMEMP, rALIGN
+	b	L(medium_tail2)
+
+	.align 5
+/* Clear lines of memory in 128-byte chunks.  */
+L(zloopstart):
+/* If the remaining length is less the 32 bytes, don't bother getting
+	 the cache line size.  */
+	beq	L(medium)
+	li      rCLS,128  /* cache line size is 128 */
+	dcbt	0,rMEMP
+L(getCacheAligned):
+	cmplwi	cr1,rLEN,32
+	andi.	rTMP,rMEMP,127
+	blt	cr1,L(handletail32)
+	beq	L(cacheAligned)
+	addi	rMEMP,rMEMP,32
+	addi	rLEN,rLEN,-32
+	stw	rCHR,-32(rMEMP)
+        stw     rCHR,-28(rMEMP)
+	stw	rCHR,-24(rMEMP)
+	stw     rCHR,-20(rMEMP)
+	stw	rCHR,-16(rMEMP)
+        stw     rCHR,-12(rMEMP)
+	stw	rCHR,-8(rMEMP)
+        stw     rCHR,-4(rMEMP)
+	b	L(getCacheAligned)
+
+/* Now we are aligned to the cache line and can use dcbz.  */
+        .align 4
+L(cacheAligned):
+	cmplw	cr1,rLEN,rCLS
+	blt	cr1,L(handletail32)
+	dcbz	0,rMEMP
+	subf	rLEN,rCLS,rLEN
+	add	rMEMP,rMEMP,rCLS
+	b	L(cacheAligned)
+
+/* We are here because the cache line size was set and the remainder 
+  (rLEN) is less than the actual cache line size.
+   So set up the preconditions for L(nondcbz) and go there.  */
+L(handletail32):
+	clrrwi.	rALIGN, rLEN, 5
+	b		L(nondcbz)
+
+	.align 5
+L(small):
+/* Memset of 4 bytes or less.  */
+	cmplwi	cr5, rLEN, 1
+	cmplwi	cr1, rLEN, 3
+	bltlr	cr5
+	stb	rCHR, 0(rMEMP)
+	beqlr	cr5
+	stb	rCHR, 1(rMEMP)
+	bltlr	cr1
+	stb	rCHR, 2(rMEMP)
+	beqlr	cr1
+	stb	rCHR, 3(rMEMP)
+	blr
+
+/* Memset of 0-31 bytes.  */
+	.align 5
+L(medium):
+	cmplwi	cr1, rLEN, 16
+L(medium_tail2):
+	add	rMEMP, rMEMP, rLEN
+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     rCHR, -4(rMEMP)
+	stw	rCHR, -8(rMEMP)
+	blr
+
+L(medium_31t):
+	stbu	rCHR, -1(rMEMP)
+	bf-	30, L(medium_30f)
+L(medium_30t):
+	sthu	rCHR, -2(rMEMP)
+	bf-	29, L(medium_29f)
+L(medium_29t):
+	stwu	rCHR, -4(rMEMP)
+	blt-	cr1, L(medium_27f)
+L(medium_27t):
+        stw     rCHR, -4(rMEMP)
+	stw	rCHR, -8(rMEMP)
+        stw     rCHR, -12(rMEMP)
+	stwu	rCHR, -16(rMEMP)
+L(medium_27f):
+	bflr-	28
+L(medium_28t):
+        stw     rCHR, -4(rMEMP)
+	stw	rCHR, -8(rMEMP)
+	blr
+libc_hidden_builtin_def (memset)
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S
--- dummy-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S	Tue Dec 06 10:46:02 2005
@@ -0,0 +1,176 @@
+/* Optimized strcmp implementation for PowerPC32.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works.  */
+
+/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
+
+EALIGN (BP_SYM(strncmp), 4, 0)
+
+#define rTMP	r0
+#define rRTN	r3
+#define rSTR1	r3	/* first string arg */
+#define rSTR2	r4	/* second string arg */
+#define rN	r5	/* max string length */
+/* Note:  The Bounded pointer support in this code is broken.  This code
+   was inherited from PPC32 and and that support was never completed.  
+   Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
+#define rWORD1	r6	/* current word in s1 */
+#define rWORD2	r7	/* current word in s2 */
+#define rWORD3  r10
+#define rWORD4  r11
+#define rFEFE	r8	/* constant 0xfefefeff (-0x01010101) */
+#define r7F7F	r9	/* constant 0x7f7f7f7f */
+#define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f) */
+#define rBITDIF	r11	/* bits that differ in s1 & s2 words */
+
+	dcbt	0,rSTR1
+	or	rTMP, rSTR2, rSTR1
+	lis	r7F7F, 0x7f7f
+	dcbt	0,rSTR2
+	clrlwi.	rTMP, rTMP, 30
+	cmplwi	cr1, rN, 0
+	lis	rFEFE, -0x101
+	bne	L(unaligned)
+/* We are word alligned so set up for two loops.  first a word
+   loop, then fall into the byte loop if any residual.  */
+	srwi.	rTMP, rN, 2
+	clrlwi	rN, rN, 30
+	addi	rFEFE, rFEFE, -0x101
+	addi	r7F7F, r7F7F, 0x7f7f
+	cmplwi	cr1, rN, 0	
+	beq	L(unaligned)
+
+	mtctr	rTMP	/* Power4 wants mtctr 1st in dispatch group.  */
+	lwz	rWORD1, 0(rSTR1)
+	lwz	rWORD2, 0(rSTR2)
+	b	L(g1)
+
+L(g0):	
+	lwzu	rWORD1, 4(rSTR1)
+	bne-	cr1, L(different)
+	lwzu	rWORD2, 4(rSTR2)
+L(g1):	add	rTMP, rFEFE, rWORD1
+	nor	rNEG, r7F7F, rWORD1
+	bdz	L(tail)
+	and.	rTMP, rTMP, rNEG
+	cmpw	cr1, rWORD1, rWORD2
+	beq+	L(g0)
+	
+/* 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...  */
+	
+L(endstring):
+	and	rTMP, r7F7F, rWORD1
+	beq	cr1, L(equal)
+	add	rTMP, rTMP, r7F7F
+	xor.	rBITDIF, rWORD1, rWORD2
+
+	andc	rNEG, rNEG, rTMP
+	blt-	L(highbit)
+	cntlzw	rBITDIF, rBITDIF
+	cntlzw	rNEG, rNEG
+	addi	rNEG, rNEG, 7
+	cmpw	cr1, rNEG, rBITDIF
+	sub	rRTN, rWORD1, rWORD2
+	blt-	cr1, L(equal)
+	srawi	rRTN, rRTN, 31
+	ori	rRTN, rRTN, 1
+	blr
+L(equal):
+	li	rRTN, 0
+	blr
+
+L(different):
+	lwzu	rWORD1, -4(rSTR1)
+	xor.	rBITDIF, rWORD1, rWORD2
+	sub	rRTN, rWORD1, rWORD2
+	blt-	L(highbit)
+	srawi	rRTN, rRTN, 31
+	ori	rRTN, rRTN, 1
+	blr
+L(highbit):
+	srwi	rWORD2, rWORD2, 24
+	srwi	rWORD1, rWORD1, 24
+	sub	rRTN, rWORD1, rWORD2
+	blr
+
+
+/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+	.align 4
+L(tail):
+	and.	rTMP, rTMP, rNEG
+	cmpw	cr1, rWORD1, rWORD2
+	bne-	L(endstring)
+	addi	rSTR1, rSTR1, 4
+	bne-	cr1, L(different)
+	addi	rSTR2, rSTR2, 4
+	cmplwi	cr1, rN, 0
+L(unaligned):
+	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
+	ble	cr1, L(ux)
+L(uz):
+	lbz	rWORD1, 0(rSTR1)
+	lbz	rWORD2, 0(rSTR2)
+	.align 4
+L(u1):
+	cmpwi	cr1, rWORD1, 0
+	bdz	L(u4)
+	cmpw	rWORD1, rWORD2
+	beq-	cr1, L(u4)
+	lbzu    rWORD3, 1(rSTR1)
+	lbzu	rWORD4, 1(rSTR2)
+	bne-	L(u4)
+	cmpwi	cr1, rWORD3, 0
+	bdz	L(u3)
+	cmpw	rWORD3, rWORD4
+	beq-    cr1, L(u3)
+	lbzu	rWORD1, 1(rSTR1)
+	lbzu	rWORD2, 1(rSTR2)
+	bne-    L(u3)
+	cmpwi	cr1, rWORD1, 0
+	bdz	L(u4)
+	cmpw	rWORD1, rWORD2
+	beq-	cr1, L(u4)
+	lbzu	rWORD3, 1(rSTR1)
+	lbzu	rWORD4, 1(rSTR2)
+	bne-	L(u4)
+	cmpwi	cr1, rWORD3, 0
+	bdz	L(u3)
+	cmpw	rWORD3, rWORD4
+	beq-    cr1, L(u3)
+	lbzu	rWORD1, 1(rSTR1)
+	lbzu	rWORD2, 1(rSTR2)
+	beq+    L(u1)
+
+L(u3):  sub     rRTN, rWORD3, rWORD4
+        blr
+L(u4):	sub	rRTN, rWORD1, rWORD2
+	blr
+L(ux):
+	li	rRTN, 0
+	blr
+END (BP_SYM (strncmp))
+libc_hidden_builtin_def (strncmp)
+
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power5/Implies libc24/power-cpu/sysdeps/powerpc/powerpc32/power5/Implies
--- dummy-cpu/sysdeps/powerpc/powerpc32/power5/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power5/Implies	Tue Dec 06 15:12:39 2005
@@ -0,0 +1,1 @@
+powerpc/powerpc32/power4
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies libc24/power-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies
--- dummy-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,1 @@
+powerpc/powerpc32/powerpc64/fpu
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/Makefile libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/Makefile
--- dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/Makefile	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/Makefile	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,7 @@
+# Powerpc32 ABI on powerpc64 hardware specific build options.
+
+ifeq ($(subdir),csu)
+sysdep_routines += hp-timing
+elide-routines.os += hp-timing
+endif
+
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S
--- dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,40 @@
+/* Round double to long int.  PowerPC32 on PowerPC64 version.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+/* long long int[r3, r4] __llrint (double x[fp1])  */
+ENTRY (__llrint)	
+	CALL_MCOUNT
+	fctid	fp13,fp1
+	stfd	fp13,-8(r1)
+	nop	/* Insure the following load is in a different dispatch group */
+	nop	/* to avoid pipe stall on POWER4&5.  */
+	nop
+	lwz	r3,-8(r1)
+	lwz	r4,-4(r1)	
+	blr
+	END (__llrint)
+
+weak_alias (__llrint, llrint)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llrint, __llrintl)
+weak_alias (__llrint, llrintl)
+#endif
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S
--- dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,36 @@
+/* Round float to long int.  PowerPC32 on PowerPC64 version.
+   Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+
+/* long long int[r3, r4] __llrintf (float x[fp1])  */
+ENTRY (__llrintf)	
+	CALL_MCOUNT
+	fctid	fp13,fp1
+	stfd	fp13,-8(r1)
+	nop	/* Insure the following load is in a different dispatch group */
+	nop	/* to avoid pipe stall on POWER4&5.  */
+	nop
+	lwz	r3,-8(r1)
+	lwz	r4,-4(r1)	
+	blr
+	END (__llrintf)
+
+weak_alias (__llrintf, llrintf)
+
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.c libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.c
--- dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.c	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.c	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,27 @@
+/* Support for high precision, low overhead timing functions. 
+   powerpc32 version.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <hp-timing.h>
+
+/* We have to define a variable for the overhead and thread locking. 
+   To avoid false sharing and potential "live lock" we need to insure that
+   the hp_timing lock is in a cache line by itself.  */
+hp_timing_t _dl_hp_timing_overhead __attribute__((aligned(128)));
diff -urN dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.h libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.h
--- dummy-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.h	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc32/powerpc64/hp-timing.h	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,183 @@
+/* High precision, low overhead timing functions.  powerpc32 version.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _HP_TIMING_H
+#define _HP_TIMING_H	1
+
+#include <string.h>
+#include <sys/param.h>
+#include <stdio-common/_itoa.h>
+#include <atomic.h>
+
+/* The macros defined here use the powerpc 64-bit time base register.
+   The time base is nominally clocked at 1/8th the CPU clock, but this
+   can vary.
+
+   The list of macros we need includes the following:
+
+   - HP_TIMING_AVAIL: test for availability.
+
+   - HP_TIMING_INLINE: this macro is non-zero if the functionality is not
+     implemented using function calls but instead uses some inlined code
+     which might simply consist of a few assembler instructions.  We have to
+     know this since we might want to use the macros here in places where we
+     cannot make function calls.
+
+   - hp_timing_t: This is the type for variables used to store the time
+     values.
+
+   - HP_TIMING_ZERO: clear `hp_timing_t' object.
+
+   - HP_TIMING_NOW: place timestamp for current time in variable given as
+     parameter.
+
+   - HP_TIMING_DIFF_INIT: do whatever is necessary to be able to use the
+     HP_TIMING_DIFF macro.
+
+   - HP_TIMING_DIFF: compute difference between two times and store it
+     in a third.  Source and destination might overlap.
+
+   - HP_TIMING_ACCUM: add time difference to another variable.  This might
+     be a bit more complicated to implement for some platforms as the
+     operation should be thread-safe and 64bit arithmetic on 32bit platforms
+     is not.
+
+   - HP_TIMING_ACCUM_NT: this is the variant for situations where we know
+     there are no threads involved.
+
+   - HP_TIMING_PRINT: write decimal representation of the timing value into
+     the given string.  This operation need not be inline even though
+     HP_TIMING_INLINE is specified.
+
+*/
+
+/* We always assume having the timestamp register.  */
+#define HP_TIMING_AVAIL		(1)
+
+/* We indeed have inlined functions.  */
+#define HP_TIMING_INLINE	(1)
+
+/* We use 64bit values for the times.  */
+typedef unsigned long long int hp_timing_t;
+
+typedef union  hp_timing_ut
+  {
+     hp_timing_t 	ll_tb;
+     unsigned long	l_tb[2];
+  } hp_timing_ut;
+	
+
+/* Set timestamp value to zero.  */
+#define HP_TIMING_ZERO(Var)	(Var) = (0)
+
+/* Use the `mftbu'/`mftb' instructions to obtain the 64-bit timebase 
+   32-bits at a time.  We need to insure that the upper timebase is 
+   consistent with the lower timebase.  So we read the upper timebase
+   before and after we read the lower timebase then compare them.
+   If the two upper timebase values are equal we are done. Otherwise the 
+   lower timebase may have wrapper, so we repeat the sequence.
+
+   Note that the value might not be 100% accurate since there might be
+   some more instructions running in this moment.  */
+#define HP_TIMING_NOW(Var)						      \
+  do {									      \
+    unsigned long __temp;						      \
+    hp_timing_ut tmp_val;						      \
+    __asm __volatile (							      \
+		    "1:	mftbu	%0\n"					      \
+		    "	mftb	%1\n"					      \
+		    "	mftbu	%2\n"					      \
+		    "	cmpw	%0,%2\n"				      \
+		    "	bne-	1b\n"					      \
+		    : "=r" (tmp_val.l_tb[0]), "=r" (tmp_val.l_tb[1]),         \
+		      "=r" (__temp)					      \
+		    :							      \
+		    : "cr0", "memory");					      \
+     Var =  tmp_val.ll_tb;	      \
+  } while (0)
+
+/* Use two 'mftb/mftbu' sequences in a row to find out how long it takes.
+   On current POWER4, POWER5, and 970 processors mftb/mftbu ibstructions
+   take ~10 cycles each.  */
+#define HP_TIMING_DIFF_INIT() \
+  do {									      \
+    if (GLRO(dl_hp_timing_overhead) == 0)				      \
+      {									      \
+	int __cnt = 5;							      \
+	GLRO(dl_hp_timing_overhead) = ~0ull;				      \
+	do								      \
+	  {								      \
+	    hp_timing_t __t1, __t2;					      \
+	    HP_TIMING_NOW (__t1);					      \
+	    HP_TIMING_NOW (__t2);					      \
+	    if (__t2 - __t1 < GLRO(dl_hp_timing_overhead))		      \
+	      GLRO(dl_hp_timing_overhead) = __t2 - __t1;		      \
+	  }								      \
+	while (--__cnt > 0);						      \
+      }									      \
+  } while (0)
+
+/* It's simple arithmetic in 64-bit.  */
+#define HP_TIMING_DIFF(Diff, Start, End)	(Diff) = ((End) - (Start))
+
+/* We need to insure that this add is atomic in threaded environments.  
+   But we want this needs to be a "light-weight" as posible.  So we create a
+   simple lwarx lock on the 1st word of dl_hp_timing_overhead. The lwarx gets
+   the reservation and (attempts to hold it while we compute long long sum.  
+   We follow this with a conditional stwcx to verify that no other thread
+   took the reservation while we computed the sum.  We don't care
+   about the value of the lock word, and don't change the value.  */
+#define HP_TIMING_ACCUM(Sum, Diff) \
+  do {									      \
+    hp_timing_t __diff = (Diff) - GLRO(dl_hp_timing_overhead);		      \
+    void *lock	= & GLRO(dl_hp_timing_overhead);			      \
+    unsigned int __tmp;							      \
+    __asm __volatile (							      \
+		    "1:	lwarx	%0,0,%1\n"				      \
+		    "  " __ARCH_ACQ_INSTR "\n"				      \
+		    : "=&r" (__tmp)					      \
+		    : "b" (lock)					      \
+		    );							      \
+    (Sum) += (__diff);							      \
+    __asm __volatile (							      \
+		    "  " __ARCH_REL_INSTR "\n"				      \
+		    "	stwcx.	%0,0,%1\n"				      \
+		    "	bne-	1b\n"					      \
+		    : 							      \
+		    : "r" (__tmp), "b" (lock)				      \
+		    : "cr0", "memory");					      \
+  } while (0)
+
+/* No threads, no extra work.  */
+#define HP_TIMING_ACCUM_NT(Sum, Diff)	(Sum) += (Diff)
+
+/* Print the time value.  */
+#define HP_TIMING_PRINT(Buf, Len, Val) \
+  do {									      \
+    char __buf[20];							      \
+    char *__cp = _itoa (Val, __buf + sizeof (__buf), 10, 0);		      \
+    size_t __len = (Len);						      \
+    char *__dest = (Buf);						      \
+    while (__len-- > 0 && __cp < __buf + sizeof (__buf))		      \
+      *__dest++ = *__cp++;						      \
+    memcpy (__dest, " ticks", MIN (__len, sizeof (" ticks")));  \
+  } while (0)
+
+#endif	/* hp-timing.h */
diff -urN dummy-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S libc24/power-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S
--- dummy-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,966 @@
+/* Optimized strcmp implementation for PowerPC64.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* int [r3] memcmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
+
+EALIGN (BP_SYM(memcmp), 4, 0)
+	CALL_MCOUNT 3
+
+#define rTMP	r0
+#define rRTN	r3
+#define rSTR1	r3	/* first string arg */
+#define rSTR2	r4	/* second string arg */
+#define rN	r5	/* max string length */
+/* Note:  The Bounded pointer support in this code is broken.  This code
+   was inherited from PPC32 and and that support was never completed.  
+   Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
+#define rWORD1	r6	/* current word in s1 */
+#define rWORD2	r7	/* current word in s2 */
+#define rWORD3	r8	/* next word in s1 */
+#define rWORD4	r9	/* next word in s2 */
+#define rWORD5	r10	/* next word in s1 */
+#define rWORD6	r11	/* next word in s2 */
+#define rBITDIF	r12	/* bits that differ in s1 & s2 words */
+#define rWORD7	r30	/* next word in s1 */
+#define rWORD8	r31	/* next word in s2 */
+
+	xor	rTMP, rSTR2, rSTR1
+	cmpldi	cr6, rN, 0
+	cmpldi	cr1, rN, 12
+	clrldi.	rTMP, rTMP, 61
+	clrldi	rBITDIF, rSTR1, 61
+	cmpldi	cr5, rBITDIF, 0
+	beq-	cr6, L(zeroLength)
+	dcbt	0,rSTR1
+	dcbt	0,rSTR2
+/* If less than 8 bytes or not aligned, use the unalligned
+   byte loop.  */
+	blt	cr1, L(bytealigned)
+	std	rWORD8,-8(r1)
+	std	rWORD7,-16(r1)
+	bne	L(unaligned)
+/* At this point we know both strings have the same alignment and the
+   compare length is at least 8 bytes.  rBITDIF containes the low order
+   3 bits of rSTR1 and cr5 contains the result of the logical compare
+   of rBITDIF to 0.  If rBITDIF == 0 then we are already double word 
+   aligned and can perform the DWaligned loop.
+  
+   Otherwise we know the two strings have the same alignment (but not
+   yet DW).  So we can force the string addresses to the next lower DW
+   boundary and special case this first DW word using shift left to
+   ellimiate bits preceeding the first byte.  Since we want to join the
+   normal (DWaligned) compare loop, starting at the second double word,
+   we need to adjust the length (rN) and special case the loop
+   versioning for the first DW. This insures that the loop count is
+   correct and the first DW (shifted) is in the expected resister pair.  */
+	.align 4
+L(samealignment):
+	clrrdi	rSTR1, rSTR1, 3
+	clrrdi	rSTR2, rSTR2, 3
+	beq	cr5, L(DWaligned)
+	add	rN, rN, rBITDIF
+	sldi	r11, rBITDIF, 3
+	srdi	rTMP, rN, 5	/* Divide by 32 */
+	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+	ld	rWORD1, 0(rSTR1)
+	ld	rWORD2, 0(rSTR2)
+	cmpldi	cr1, rBITDIF, 16
+	cmpldi	cr7, rN, 32
+	clrldi	rN, rN, 61
+	beq	L(dPs4)
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	bgt	cr1, L(dPs3)
+	beq	cr1, L(dPs2)
+
+/* Remainder is 8 */
+	.align 3
+L(dsP1):
+	sld	rWORD5, rWORD1, r11
+	sld	rWORD6, rWORD2, r11
+	cmpld	cr5, rWORD5, rWORD6
+	blt	cr7, L(dP1x)
+/* Do something useful in this cycle since we have to branch anyway.  */
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	b	L(dP1e)
+/* Remainder is 16 */
+	.align 4
+L(dPs2):
+	sld	rWORD5, rWORD1, r11
+	sld	rWORD6, rWORD2, r11
+	cmpld	cr6, rWORD5, rWORD6
+	blt	cr7, L(dP2x)
+/* Do something useful in this cycle since we have to branch anyway.  */
+	ld	rWORD7, 8(rSTR1)
+	ld	rWORD8, 8(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	b	L(dP2e)
+/* Remainder is 24 */
+	.align 4
+L(dPs3):
+	sld	rWORD3, rWORD1, r11
+	sld	rWORD4, rWORD2, r11
+	cmpld	cr1, rWORD3, rWORD4
+	b	L(dP3e)
+/* Count is a multiple of 32, remainder is 0 */
+	.align 4
+L(dPs4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	sld	rWORD1, rWORD1, r11
+	sld	rWORD2, rWORD2, r11
+	cmpld	cr0, rWORD1, rWORD2
+	b	L(dP4e)
+
+/* At this point we know both strings are double word aligned and the
+   compare length is at least 8 bytes.  */
+	.align 4
+L(DWaligned):
+	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+	srdi	rTMP, rN, 5	/* Divide by 32 */
+	cmpldi	cr1, rBITDIF, 16
+	cmpldi	cr7, rN, 32
+	clrldi	rN, rN, 61
+	beq	L(dP4)
+	bgt	cr1, L(dP3)
+	beq	cr1, L(dP2)
+		
+/* Remainder is 8 */
+	.align 4
+L(dP1):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+/* Normally we'd use rWORD7/rWORD8 here, but since we might exit early
+   (8-15 byte compare), we want to use only volitile registers.  This
+   means we can avoid restoring non-volitile registers since we did not
+   change any on the early exit path.  The key here is the non-early
+   exit path only cares about the condition code (cr5), not about which 
+   register pair was used.  */
+	ld	rWORD5, 0(rSTR1)
+	ld	rWORD6, 0(rSTR2)
+	cmpld	cr5, rWORD5, rWORD6
+	blt	cr7, L(dP1x)
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+L(dP1e):
+	ld	rWORD3, 16(rSTR1)
+	ld	rWORD4, 16(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	ld	rWORD5, 24(rSTR1)
+	ld	rWORD6, 24(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr5, L(dLcr5)
+	bne	cr0, L(dLcr0)
+	
+	ldu	rWORD7, 32(rSTR1)
+	ldu	rWORD8, 32(rSTR2)
+	bne	cr1, L(dLcr1)
+	cmpld	cr5, rWORD7, rWORD8
+	bdnz	L(dLoop)
+	bne	cr6, L(dLcr6)
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	.align 3
+L(dP1x):
+	sldi.	r12, rN, 3
+	bne	cr5, L(dLcr5)
+	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+	bne	L(d00)
+	li	rRTN, 0
+	blr
+		
+/* Remainder is 16 */
+	.align 4
+L(dP2):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	ld	rWORD5, 0(rSTR1)
+	ld	rWORD6, 0(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	blt	cr7, L(dP2x)
+	ld	rWORD7, 8(rSTR1)
+	ld	rWORD8, 8(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+L(dP2e):
+	ld	rWORD1, 16(rSTR1)
+	ld	rWORD2, 16(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	ld	rWORD3, 24(rSTR1)
+	ld	rWORD4, 24(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	bne	cr6, L(dLcr6)
+	bne	cr5, L(dLcr5)
+	b	L(dLoop2)
+/* Again we are on a early exit path (16-23 byte compare), we want to
+   only use volitile registers and avoid restoring non-volitile
+   registers.  */
+	.align 4
+L(dP2x):
+	ld	rWORD3, 8(rSTR1)
+	ld	rWORD4, 8(rSTR2)
+	cmpld	cr5, rWORD3, rWORD4
+	sldi.	r12, rN, 3
+	bne	cr6, L(dLcr6)
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	bne	cr5, L(dLcr5)
+	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+	bne	L(d00)
+	li	rRTN, 0
+	blr
+		
+/* Remainder is 24 */
+	.align 4
+L(dP3):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	ld	rWORD3, 0(rSTR1)
+	ld	rWORD4, 0(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+L(dP3e):
+	ld	rWORD5, 8(rSTR1)
+	ld	rWORD6, 8(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	blt	cr7, L(dP3x)
+	ld	rWORD7, 16(rSTR1)
+	ld	rWORD8, 16(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	ld	rWORD1, 24(rSTR1)
+	ld	rWORD2, 24(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	addi	rSTR1, rSTR1, 16
+	addi	rSTR2, rSTR2, 16
+	bne	cr1, L(dLcr1)
+	bne	cr6, L(dLcr6)
+	b	L(dLoop1)
+/* Again we are on a early exit path (24-31 byte compare), we want to
+   only use volitile registers and avoid restoring non-volitile
+   registers.  */
+	.align 4
+L(dP3x):
+	ld	rWORD1, 16(rSTR1)
+	ld	rWORD2, 16(rSTR2)
+	cmpld	cr5, rWORD1, rWORD2
+	sldi.	r12, rN, 3
+	bne	cr1, L(dLcr1)
+	addi	rSTR1, rSTR1, 16
+	addi	rSTR2, rSTR2, 16
+	bne	cr6, L(dLcr6)
+	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+	bne	cr5, L(dLcr5)
+	bne	L(d00)
+	li	rRTN, 0
+	blr
+	
+/* Count is a multiple of 32, remainder is 0 */
+	.align 4
+L(dP4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	ld	rWORD1, 0(rSTR1)
+	ld	rWORD2, 0(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+L(dP4e):
+	ld	rWORD3, 8(rSTR1)
+	ld	rWORD4, 8(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	ld	rWORD5, 16(rSTR1)
+	ld	rWORD6, 16(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	ldu	rWORD7, 24(rSTR1)
+	ldu	rWORD8, 24(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	bne	cr0, L(dLcr0)
+	bne	cr1, L(dLcr1)
+	bdz-	L(d24)		/* Adjust CTR as we start with +4 */
+/* This is the primary loop */
+	.align 4
+L(dLoop):
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	bne	cr6, L(dLcr6)
+L(dLoop1):
+	ld	rWORD3, 16(rSTR1)
+	ld	rWORD4, 16(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr5, L(dLcr5)
+L(dLoop2):
+	ld	rWORD5, 24(rSTR1)
+	ld	rWORD6, 24(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	bne	cr0, L(dLcr0)
+L(dLoop3):
+	ldu	rWORD7, 32(rSTR1)
+	ldu	rWORD8, 32(rSTR2)
+	bne-	cr1, L(dLcr1)
+	cmpld	cr0, rWORD1, rWORD2
+	bdnz+	L(dLoop)	
+	
+L(dL4):
+	cmpld	cr1, rWORD3, rWORD4
+	bne	cr6, L(dLcr6)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr5, L(dLcr5)
+	cmpld	cr5, rWORD7, rWORD8
+L(d44):
+	bne	cr0, L(dLcr0)
+L(d34):
+	bne	cr1, L(dLcr1)
+L(d24):
+	bne	cr6, L(dLcr6)
+L(d14):
+	sldi.	r12, rN, 3
+	bne	cr5, L(dLcr5) 
+L(d04):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	subfic	rN, r12, 64	/* Shift count is 64 - (rN * 8).  */
+	beq	L(zeroLength)
+/* At this point we have a remainder of 1 to 7 bytes to compare.  Since
+   we are aligned it is safe to load the whole double word, and use
+   shift right double to elliminate bits beyond the compare length.
+   This allows the use of double word subtract to compute the final
+   result.  */ 
+L(d00):
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2) 
+	srd	rWORD1, rWORD1, rN
+	srd	rWORD2, rWORD2, rN
+	sub	rRTN, rWORD1, rWORD2
+	blr
+	.align 4
+L(dLcr0):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgtlr	cr0
+	li	rRTN, -1
+	blr
+	.align 4
+L(dLcr1):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgtlr	cr1
+	li	rRTN, -1
+	blr
+	.align 4
+L(dLcr6):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgtlr	cr6
+	li	rRTN, -1
+	blr
+	.align 4
+L(dLcr5):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+L(dLcr5x):
+	li	rRTN, 1
+	bgtlr	cr5
+	li	rRTN, -1
+	blr
+	
+	.align 4
+L(bytealigned):
+	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
+	beq-	cr6, L(zeroLength)
+
+/* We need to prime this loop.  This loop is swing modulo scheduled
+   to avoid pipe delays.  The dependent instruction latencies (load to 
+   compare to conditional branch) is 2 to 3 cycles.  In this loop each
+   dispatch group ends in a branch and takes 1 cycle.  Effectively
+   the first iteration of the loop only serves to load operands and 
+   branches based on compares are delayed until the next loop. 
+
+   So we must precondition some registers and condition codes so that
+   we don't exit the loop early on the first iteration.  */
+   
+	lbz	rWORD1, 0(rSTR1)
+	lbz	rWORD2, 0(rSTR2)
+	bdz-	L(b11)
+	cmpld	cr0, rWORD1, rWORD2
+	lbz	rWORD3, 1(rSTR1)
+	lbz	rWORD4, 1(rSTR2)
+	bdz-	L(b12)
+	cmpld	cr1, rWORD3, rWORD4
+	lbzu	rWORD5, 2(rSTR1)
+	lbzu	rWORD6, 2(rSTR2)
+	bdz-	L(b13)
+	.align 4
+L(bLoop):
+	lbzu	rWORD1, 1(rSTR1)
+	lbzu	rWORD2, 1(rSTR2)
+	bne-	cr0, L(bLcr0)
+
+	cmpld	cr6, rWORD5, rWORD6
+	bdz-	L(b3i)
+	
+	lbzu	rWORD3, 1(rSTR1)
+	lbzu	rWORD4, 1(rSTR2)
+	bne-	cr1, L(bLcr1)
+
+	cmpld	cr0, rWORD1, rWORD2
+	bdz-	L(b2i)
+
+	lbzu	rWORD5, 1(rSTR1)
+	lbzu	rWORD6, 1(rSTR2)
+	bne-	cr6, L(bLcr6)
+
+	cmpld	cr1, rWORD3, rWORD4
+	bdnz+	L(bLoop)
+	
+/* We speculatively loading bytes before we have tested the previous
+   bytes.  But we must avoid overrunning the length (in the ctr) to
+   prevent these speculative loads from causing a segfault.  In this 
+   case the loop will exit early (before the all pending bytes are
+   tested.  In this case we must complete the pending operations
+   before returning.  */
+L(b1i):
+	bne-	cr0, L(bLcr0)
+	bne-	cr1, L(bLcr1)
+	b	L(bx56)
+	.align 4
+L(b2i):
+	bne-	cr6, L(bLcr6)
+	bne-	cr0, L(bLcr0)
+	b	L(bx34)
+	.align 4
+L(b3i):
+	bne-	cr1, L(bLcr1)
+	bne-	cr6, L(bLcr6)
+	b	L(bx12)
+	.align 4
+L(bLcr0):
+	li	rRTN, 1
+	bgtlr	cr0
+	li	rRTN, -1
+	blr
+L(bLcr1):
+	li	rRTN, 1
+	bgtlr	cr1
+	li	rRTN, -1
+	blr
+L(bLcr6):
+	li	rRTN, 1
+	bgtlr	cr6
+	li	rRTN, -1
+	blr
+
+L(b13):
+	bne-	cr0, L(bx12)
+	bne-	cr1, L(bx34)
+L(bx56):
+	sub	rRTN, rWORD5, rWORD6
+	blr
+	nop
+L(b12):
+	bne-	cr0, L(bx12)
+L(bx34):	
+	sub	rRTN, rWORD3, rWORD4
+	blr
+L(b11):
+L(bx12):
+	sub	rRTN, rWORD1, rWORD2
+	blr
+	.align 4 
+L(zeroLengthReturn):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+L(zeroLength):
+	li	rRTN, 0
+	blr
+
+	.align 4
+/* At this point we know the strings have different alignment and the
+   compare length is at least 8 bytes.  rBITDIF containes the low order
+   3 bits of rSTR1 and cr5 contains the result of the logical compare
+   of rBITDIF to 0.  If rBITDIF == 0 then rStr1 is double word 
+   aligned and can perform the DWunaligned loop.
+  
+   Otherwise we know that rSTR1 is not aready DW aligned yet.
+   So we can force the string addresses to the next lower DW
+   boundary and special case this first DW word using shift left to
+   ellimiate bits preceeding the first byte.  Since we want to join the
+   normal (DWaligned) compare loop, starting at the second double word,
+   we need to adjust the length (rN) and special case the loop
+   versioning for the first DW. This insures that the loop count is
+   correct and the first DW (shifted) is in the expected resister pair.  */
+#define rSHL	r29	/* Unaligned shift left count.  */
+#define rSHR	r28	/* Unaligned shift right count.  */
+#define rB		r27	/* Left rotation temp for rWORD2.  */
+#define rD		r26	/* Left rotation temp for rWORD4.  */
+#define rF		r25	/* Left rotation temp for rWORD6.  */
+#define rH		r24	/* Left rotation temp for rWORD8.  */
+#define rA		r0	/* Right rotation temp for rWORD2.  */
+#define rC		r12	/* Right rotation temp for rWORD4.  */
+#define rE		r0	/* Right rotation temp for rWORD6.  */
+#define rG		r12	/* Right rotation temp for rWORD8.  */
+L(unaligned):
+	std	r29,-24(r1)	
+	clrldi	rSHL, rSTR2, 61
+	beq-	cr6, L(duzeroLength)
+	std	r28,-32(r1)
+	beq	cr5, L(DWunaligned)
+	std	r27,-40(r1)
+/* Adjust the logical start of rSTR2 ro compensate for the extra bits
+   in the 1st rSTR1 DW.  */
+	sub	r27, rSTR2, rBITDIF
+/* But do not attempt to address the DW before that DW that contains
+   the actual start of rSTR2.  */
+	clrrdi	rSTR2, rSTR2, 3
+	std	r26,-48(r1)
+/* Compute the leaft/right shift counts for the unalign rSTR2,
+   compensating for the logical (DW aligned) start of rSTR1.  */ 
+	clrldi	rSHL, r27, 61
+	clrrdi	rSTR1, rSTR1, 3	
+	std	r25,-56(r1)
+	sldi	rSHL, rSHL, 3
+	cmpld	cr5, r27, rSTR2
+	add	rN, rN, rBITDIF
+	sldi	r11, rBITDIF, 3
+	std	r24,-64(r1)
+	subfic	rSHR, rSHL, 64
+	srdi	rTMP, rN, 5	/* Divide by 32 */
+	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+/* We normally need to load 2 DWs to start the unaligned rSTR2, but in
+   this special case those bits may be discarded anyway.  Also we
+   must avoid loading a DW where none of the bits are part of rSTR2 as
+   this may cross a page boundary and cause a page fault.  */
+	li	rWORD8, 0
+	blt	cr5, L(dus0)
+	ld	rWORD8, 0(rSTR2)
+	la	rSTR2, 8(rSTR2)
+	sld	rWORD8, rWORD8, rSHL
+
+L(dus0):
+	ld	rWORD1, 0(rSTR1)
+	ld	rWORD2, 0(rSTR2)
+	cmpldi	cr1, rBITDIF, 16
+	cmpldi	cr7, rN, 32
+	srd	rG, rWORD2, rSHR
+	clrldi	rN, rN, 61
+	beq	L(duPs4)
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	or	rWORD8, rG, rWORD8
+	bgt	cr1, L(duPs3)
+	beq	cr1, L(duPs2)
+
+/* Remainder is 8 */
+	.align 4
+L(dusP1):
+	sld	rB, rWORD2, rSHL
+	sld	rWORD7, rWORD1, r11
+	sld	rWORD8, rWORD8, r11
+	bge	cr7, L(duP1e)
+/* At this point we exit early with the first double word compare
+   complete and remainder of 0 to 7 bytes.  See L(du14) for details on
+   how we handle the remaining bytes.  */
+	cmpld	cr5, rWORD7, rWORD8
+	sldi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmpld	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	ld	rWORD2, 8(rSTR2)
+	srd	rA, rWORD2, rSHR
+	b	L(dutrim)
+/* Remainder is 16 */
+	.align 4
+L(duPs2):
+	sld	rH, rWORD2, rSHL
+	sld	rWORD5, rWORD1, r11
+	sld	rWORD6, rWORD8, r11
+	b	L(duP2e)
+/* Remainder is 24 */
+	.align 4
+L(duPs3):
+	sld	rF, rWORD2, rSHL
+	sld	rWORD3, rWORD1, r11
+	sld	rWORD4, rWORD8, r11
+	b	L(duP3e)
+/* Count is a multiple of 32, remainder is 0 */
+	.align 4
+L(duPs4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	or	rWORD8, rG, rWORD8
+	sld	rD, rWORD2, rSHL
+	sld	rWORD1, rWORD1, r11
+	sld	rWORD2, rWORD8, r11
+	b	L(duP4e)
+
+/* At this point we know rSTR1 is double word aligned and the
+   compare length is at least 8 bytes.  */
+	.align 4
+L(DWunaligned):
+	std	r27,-40(r1)
+	clrrdi	rSTR2, rSTR2, 3
+	std	r26,-48(r1)
+	srdi	rTMP, rN, 5	/* Divide by 32 */
+	std	r25,-56(r1)
+	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+	std	r24,-64(r1)
+	sldi	rSHL, rSHL, 3
+	ld	rWORD6, 0(rSTR2)
+	ldu	rWORD8, 8(rSTR2)
+	cmpldi	cr1, rBITDIF, 16
+	cmpldi	cr7, rN, 32
+	clrldi	rN, rN, 61
+	subfic	rSHR, rSHL, 64
+	sld	rH, rWORD6, rSHL
+	beq	L(duP4)
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	bgt	cr1, L(duP3)
+	beq	cr1, L(duP2)
+		
+/* Remainder is 8 */
+	.align 4
+L(duP1):
+	srd	rG, rWORD8, rSHR
+	ld	rWORD7, 0(rSTR1)
+	sld	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	blt	cr7, L(duP1x)
+L(duP1e):
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	srd	rA, rWORD2, rSHR
+	sld	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+	ld	rWORD3, 16(rSTR1)
+	ld	rWORD4, 16(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	srd	rC, rWORD4, rSHR
+	sld	rF, rWORD4, rSHL
+	bne	cr5, L(duLcr5)
+	or	rWORD4, rC, rD
+	ld	rWORD5, 24(rSTR1)
+	ld	rWORD6, 24(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	srd	rE, rWORD6, rSHR
+	sld	rH, rWORD6, rSHL
+	bne	cr0, L(duLcr0)
+	or	rWORD6, rE, rF
+	cmpld	cr6, rWORD5, rWORD6
+	b	L(duLoop3)	
+	.align 4
+/* At this point we exit early with the first double word compare
+   complete and remainder of 0 to 7 bytes.  See L(du14) for details on
+   how we handle the remaining bytes.  */
+L(duP1x):
+	cmpld	cr5, rWORD7, rWORD8
+	sldi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmpld	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	ld	rWORD2, 8(rSTR2)
+	srd	rA, rWORD2, rSHR
+	b	L(dutrim)
+/* Remainder is 16 */
+	.align 4
+L(duP2):
+	srd	rE, rWORD8, rSHR
+	ld	rWORD5, 0(rSTR1)
+	or	rWORD6, rE, rH
+	sld	rH, rWORD8, rSHL
+L(duP2e):
+	ld	rWORD7, 8(rSTR1)
+	ld	rWORD8, 8(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	srd	rG, rWORD8, rSHR
+	sld	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	blt	cr7, L(duP2x)
+	ld	rWORD1, 16(rSTR1)
+	ld	rWORD2, 16(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	bne	cr6, L(duLcr6)
+	srd	rA, rWORD2, rSHR
+	sld	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+	ld	rWORD3, 24(rSTR1)
+	ld	rWORD4, 24(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	bne	cr5, L(duLcr5)
+	srd	rC, rWORD4, rSHR
+	sld	rF, rWORD4, rSHL
+	or	rWORD4, rC, rD
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	cmpld	cr1, rWORD3, rWORD4
+	b	L(duLoop2)
+	.align 4
+L(duP2x):
+	cmpld	cr5, rWORD7, rWORD8
+	addi	rSTR1, rSTR1, 8
+	addi	rSTR2, rSTR2, 8
+	bne	cr6, L(duLcr6)
+	sldi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmpld	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	ld	rWORD2, 8(rSTR2)
+	srd	rA, rWORD2, rSHR
+	b	L(dutrim)
+		
+/* Remainder is 24 */
+	.align 4
+L(duP3):
+	srd	rC, rWORD8, rSHR
+	ld	rWORD3, 0(rSTR1)
+	sld	rF, rWORD8, rSHL
+	or	rWORD4, rC, rH
+L(duP3e):
+	ld	rWORD5, 8(rSTR1)
+	ld	rWORD6, 8(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	srd	rE, rWORD6, rSHR
+	sld	rH, rWORD6, rSHL
+	or	rWORD6, rE, rF
+	ld	rWORD7, 16(rSTR1)
+	ld	rWORD8, 16(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr1, L(duLcr1)
+	srd	rG, rWORD8, rSHR
+	sld	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	blt	cr7, L(duP3x)
+	ld	rWORD1, 24(rSTR1)
+	ld	rWORD2, 24(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	bne	cr6, L(duLcr6)
+	srd	rA, rWORD2, rSHR
+	sld	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+	addi	rSTR1, rSTR1, 16
+	addi	rSTR2, rSTR2, 16
+	cmpld	cr0, rWORD1, rWORD2
+	b	L(duLoop1)
+	.align 4
+L(duP3x):
+	addi	rSTR1, rSTR1, 16
+	addi	rSTR2, rSTR2, 16
+	bne	cr1, L(duLcr1)
+	cmpld	cr5, rWORD7, rWORD8
+	bne	cr6, L(duLcr6)
+	sldi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+	cmpld	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	ld	rWORD2, 8(rSTR2)
+	srd	rA, rWORD2, rSHR
+	b	L(dutrim)
+	
+/* Count is a multiple of 32, remainder is 0 */
+	.align 4
+L(duP4):
+	mtctr   rTMP	/* Power4 wants mtctr 1st in dispatch group */
+	srd	rA, rWORD8, rSHR
+	ld	rWORD1, 0(rSTR1)
+	sld	rD, rWORD8, rSHL
+	or	rWORD2, rA, rH
+L(duP4e):
+	ld	rWORD3, 8(rSTR1)
+	ld	rWORD4, 8(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	srd	rC, rWORD4, rSHR
+	sld	rF, rWORD4, rSHL
+	or	rWORD4, rC, rD
+	ld	rWORD5, 16(rSTR1)
+	ld	rWORD6, 16(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	bne	cr0, L(duLcr0)
+	srd	rE, rWORD6, rSHR
+	sld	rH, rWORD6, rSHL
+	or	rWORD6, rE, rF
+	ldu	rWORD7, 24(rSTR1)
+	ldu	rWORD8, 24(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr1, L(duLcr1)
+	srd	rG, rWORD8, rSHR
+	sld	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	cmpld	cr5, rWORD7, rWORD8
+	bdz-	L(du24)		/* Adjust CTR as we start with +4 */
+/* This is the primary loop */
+	.align 4
+L(duLoop):
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2)
+	cmpld	cr1, rWORD3, rWORD4
+	bne	cr6, L(duLcr6)
+	srd	rA, rWORD2, rSHR
+	sld	rD, rWORD2, rSHL
+	or	rWORD2, rA, rB
+L(duLoop1):
+	ld	rWORD3, 16(rSTR1)
+	ld	rWORD4, 16(rSTR2)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr5, L(duLcr5)
+	srd	rC, rWORD4, rSHR
+	sld	rF, rWORD4, rSHL
+	or	rWORD4, rC, rD
+L(duLoop2):
+	ld	rWORD5, 24(rSTR1)
+	ld	rWORD6, 24(rSTR2)
+	cmpld	cr5, rWORD7, rWORD8
+	bne	cr0, L(duLcr0)
+	srd	rE, rWORD6, rSHR
+	sld	rH, rWORD6, rSHL
+	or	rWORD6, rE, rF
+L(duLoop3):
+	ldu	rWORD7, 32(rSTR1)
+	ldu	rWORD8, 32(rSTR2)
+	cmpld	cr0, rWORD1, rWORD2
+	bne-	cr1, L(duLcr1)
+	srd	rG, rWORD8, rSHR
+	sld	rB, rWORD8, rSHL
+	or	rWORD8, rG, rH
+	bdnz+	L(duLoop)	
+	
+L(duL4):
+	bne	cr1, L(duLcr1)
+	cmpld	cr1, rWORD3, rWORD4
+	bne	cr6, L(duLcr6)
+	cmpld	cr6, rWORD5, rWORD6
+	bne	cr5, L(duLcr5)
+	cmpld	cr5, rWORD7, rWORD8
+L(du44):
+	bne	cr0, L(duLcr0)
+L(du34):
+	bne	cr1, L(duLcr1)
+L(du24):
+	bne	cr6, L(duLcr6)
+L(du14):
+	sldi.	rN, rN, 3
+	bne	cr5, L(duLcr5)
+/* At this point we have a remainder of 1 to 7 bytes to compare.  We use
+   shift right double to elliminate bits beyond the compare length. 
+   This allows the use of double word subtract to compute the final
+   result.
+
+   However it may not be safe to load rWORD2 which may be beyond the 
+   string length. So we compare the bit length of the remainder to
+   the right shift count (rSHR). If the bit count is less than or equal
+   we do not need to load rWORD2 (all significant bits are already in
+   rB).  */
+	cmpld	cr7, rN, rSHR
+	beq	L(duZeroReturn)
+	li	rA, 0
+	ble	cr7, L(dutrim)
+	ld	rWORD2, 8(rSTR2)
+	srd	rA, rWORD2, rSHR
+	.align 4
+L(dutrim):
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD8,-8(r1)
+	subfic	rN, rN, 64	/* Shift count is 64 - (rN * 8).  */ 
+	or	rWORD2, rA, rB
+	ld	rWORD7,-16(r1)	
+	ld	r29,-24(r1)
+	srd	rWORD1, rWORD1, rN
+	srd	rWORD2, rWORD2, rN
+	ld	r28,-32(r1)	
+	ld	r27,-40(r1)
+	sub	rRTN, rWORD1, rWORD2
+	b    L(dureturn26)
+	.align 4
+L(duLcr0):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgt	cr0, L(dureturn29)	
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align 4
+L(duLcr1):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgt	cr1, L(dureturn29)	
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align 4
+L(duLcr6):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgt	cr6, L(dureturn29)	
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align 4
+L(duLcr5):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+	li	rRTN, 1
+	bgt	cr5, L(dureturn29)	
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+	li	rRTN, -1
+	b	L(dureturn27)
+	.align	3
+L(duZeroReturn):
+	li	rRTN,0
+	.align	4
+L(dureturn):
+	ld	rWORD8,-8(r1)
+	ld	rWORD7,-16(r1)
+L(dureturn29):	
+	ld	r29,-24(r1)
+	ld	r28,-32(r1)
+L(dureturn27):	
+	ld	r27,-40(r1)
+L(dureturn26):	
+	ld	r26,-48(r1)
+L(dureturn25):	
+	ld	r25,-56(r1)
+	ld	r24,-64(r1)
+/*	
+	ld	r23,-72(r1)
+	ld	r22,-80(r1)	
+	ld	r21,-88(r1)
+	ld	r20,-96(r1)
+*/
+	blr
+L(duzeroLength):
+	li	rRTN,0
+	blr
+
+END (BP_SYM (memcmp))
+libc_hidden_builtin_def (memcmp)
+weak_alias (memcmp, bcmp)
diff -urN dummy-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S libc24/power-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S
--- dummy-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S	Mon Nov 28 14:28:26 2005
@@ -0,0 +1,416 @@
+/* Optimized memcpy implementation for PowerPC64.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* __ptr_t [r3] memcpy (__ptr_t dst [r3], __ptr_t src [r4], size_t len [r5]);
+   Returns 'dst'.
+
+   Memcpy handles short copies (< 32-bytes) using a binary move blocks 
+   (no loops) of lwz/stw.  The tail (remaining 1-3) bytes is handled 
+   with the appropriate combination of byte and halfword load/stores. 
+   There is minimal effort to optimize the alignment of short moves.  
+   The 64-bit implementations of POWER3 and POWER4 do a reasonable job
+   of handling unligned load/stores that do not cross 32-byte boundries.
+
+   Longer moves (>= 32-bytes) justify the effort to get at least the
+   destination doubleword (8-byte) aligned.  Further optimization is
+   posible when both source and destination are doubleword aligned.
+   Each case has a optimized unrolled loop.   */
+
+EALIGN (BP_SYM (memcpy), 5, 0)
+	CALL_MCOUNT 3
+
+    cmpldi cr1,5,31
+    neg   0,3
+    std   3,-16(1)
+    std   31,-8(1)
+    andi. 11,3,7	/* check alignement of dst.  */
+    clrldi 0,0,61	/* Number of bytes until the 1st doubleword of dst.  */
+    clrldi 10,4,61	/* check alignement of src.  */
+    cmpldi cr6,5,8
+    ble-  cr1,.L2	/* If move < 32 bytes use short move code.  */
+    cmpld cr6,10,11     
+    mr    12,4
+    srdi  9,5,3		/* Number of full double words remaining.  */
+    mtcrf 0x01,0
+    mr    31,5
+    beq   .L0
+  
+    subf  31,0,5
+  /* Move 0-7 bytes as needed to get the destination doubleword alligned.  */
+1:  bf    31,2f
+    lbz   6,0(12)
+    addi  12,12,1
+    stb   6,0(3)
+    addi  3,3,1
+2:  bf    30,4f
+    lhz   6,0(12)
+    addi  12,12,2
+    sth   6,0(3)
+    addi  3,3,2
+4:  bf    29,0f
+    lwz   6,0(12)
+    addi  12,12,4
+    stw   6,0(3)
+    addi  3,3,4
+0:
+    clrldi 10,12,61	/* check alignement of src again.  */     
+    srdi  9,31,3	/* Number of full double words remaining.  */
+    
+  /* Copy doublewords from source to destination, assumpting the
+     destination is aligned on a doubleword boundary.
+
+     At this point we know there are at least 25 bytes left (32-7) to copy.
+     The next step is to determine if the source is also doubleword aligned. 
+     If not branch to the unaligned move code at .L6. which uses
+     a load, shift, store strategy.
+     
+     Otherwise source and destination are doubleword aligned, and we can
+     the optimized doubleword copy loop.  */
+.L0:
+    clrldi  11,31,61
+    mtcrf   0x01,9
+    cmpldi  cr1,11,0
+    bne-    cr6,.L6   /* If source is not DW aligned.  */
+
+  /* Move doublewords where destination and source are DW aligned.
+     Use a unrolled loop to copy 4 doubleword (32-bytes) per iteration.
+     If the the copy is not an exact multiple of 32 bytes, 1-3 
+     doublewords are copied as needed to set up the main loop.  After
+     the main loop exits there may be a tail of 1-7 bytes. These byte are 
+     copied a word/halfword/byte at a time as needed to preserve alignment.  */
+
+    srdi  8,31,5
+    cmpldi	cr1,9,4
+    cmpldi	cr6,11,0
+    mr    11,12
+    
+    bf    30,1f
+    ld    6,0(12)
+    ld    7,8(12)
+    addi  11,12,16
+    mtctr 8
+    std   6,0(3)
+    std   7,8(3)
+    addi  10,3,16
+    bf    31,4f
+    ld    0,16(12)
+    std   0,16(3)    
+    blt   cr1,3f
+    addi  11,12,24
+    addi  10,3,24
+    b     4f
+    .align  4
+1:
+    mr    10,3
+    mtctr 8
+    bf    31,4f
+    ld    6,0(12)
+    addi  11,12,8
+    std   6,0(3)
+    addi  10,3,8
+    
+    .align  4
+4:
+    ld    6,0(11)
+    ld    7,8(11)
+    ld    8,16(11)
+    ld    0,24(11)
+    addi  11,11,32
+2:
+    std   6,0(10)
+    std   7,8(10)
+    std   8,16(10)
+    std   0,24(10)
+    addi  10,10,32
+    bdnz  4b
+3:  
+
+    rldicr 0,31,0,60
+    mtcrf 0x01,31
+    beq   cr6,0f
+.L9:
+    add   3,3,0
+    add   12,12,0
+    
+/*  At this point we have a tail of 0-7 bytes and we know that the
+    destiniation is double word aligned.  */
+4:  bf    29,2f
+    lwz   6,0(12)
+    addi  12,12,4
+    stw   6,0(3)
+    addi  3,3,4
+2:  bf    30,1f
+    lhz   6,0(12)
+    addi  12,12,2
+    sth   6,0(3)
+    addi  3,3,2
+1:  bf    31,0f
+    lbz   6,0(12)
+    stb   6,0(3)
+0:
+  /* Return original dst pointer.  */
+    ld 31,-8(1)
+    ld 3,-16(1)
+    blr
+       
+/* Copy up to 31 bytes.  This divided into two cases 0-8 bytes and 9-31 
+   bytes.  Each case is handled without loops, using binary (1,2,4,8) 
+   tests.  
+   
+   In the short (0-8 byte) case no attempt is made to force alignment
+   of either source or destination.  The hardware will handle the 
+   unaligned load/stores with small delays for crossing 32- 64-byte, and 
+   4096-byte boundaries. Since these short moves are unlikely to be
+   unaligned or cross these boundaries, the overhead to force 
+   alignment is not justified.
+   
+   The longer (9-31 byte) move is more likely to cross 32- or 64-byte
+   boundaries.  Since only loads are sensitive to the 32-/64-byte
+   boundaries it is more important to align the source then the 
+   destination.  If the source is not already word aligned, we first
+   move 1-3 bytes as needed.  Since we are only word aligned we don't 
+   use double word load/stores to insure that all loads are aligned. 
+   While the destination and stores may still be unaligned, this
+   is only an issue for page (4096 byte boundary) crossing, which
+   should be rare for these short moves.  The hardware handles this
+   case automatically with a small delay.  */ 
+   
+    .align  4
+.L2:
+    mtcrf 0x01,5
+    neg   8,4
+    clrrdi	11,4,2
+    andi. 0,8,3
+    ble   cr6,.LE8	/* Handle moves of 0-8 bytes.  */
+/* At least 9 bytes left.  Get the source word aligned.  */
+    cmpldi	cr1,5,16
+    mr    10,5
+    mr    12,4
+    cmpldi	cr6,0,2
+    beq   .L3	/* If the source is already word aligned skip this.  */
+/* Copy 1-3 bytes to get source address word aligned.  */
+    lwz   6,0(11)
+    subf  10,0,5
+    add   12,4,0
+    blt   cr6,5f
+    srdi  7,6,16
+    bgt	  cr6,3f
+    sth   6,0(3)
+    b     7f
+    .align  4
+3:
+    stb   7,0(3)
+    sth   6,1(3)
+    b     7f
+    .align  4
+5:
+    stb   6,0(3)
+7:
+    cmpldi	cr1,10,16
+    add   3,3,0
+    mtcrf 0x01,10
+    .align  4
+.L3:
+/* At least 6 bytes left and the source is word aligned.  */
+    blt   cr1,8f
+16: /* Move 16 bytes.  */
+    lwz   6,0(12)
+    lwz   7,4(12)
+    stw   6,0(3)
+    lwz   6,8(12)
+    stw   7,4(3)
+    lwz   7,12(12)
+    addi  12,12,16
+    stw   6,8(3)
+    stw   7,12(3)
+    addi  3,3,16
+8:  /* Move 8 bytes.  */
+    bf    28,4f
+    lwz   6,0(12)
+    lwz   7,4(12)
+    addi  12,12,8
+    stw   6,0(3)
+    stw   7,4(3)
+    addi  3,3,8
+4:  /* Move 4 bytes.  */
+    bf    29,2f
+    lwz   6,0(12)
+    addi  12,12,4
+    stw   6,0(3)
+    addi  3,3,4    
+2:  /* Move 2-3 bytes.  */
+    bf    30,1f
+    lhz   6,0(12)
+    sth   6,0(3) 
+    bf    31,0f
+    lbz   7,2(12)
+    stb   7,2(3)
+    ld 3,-16(1)
+    blr
+1:  /* Move 1 byte.  */
+    bf    31,0f
+    lbz   6,0(12)
+    stb   6,0(3)
+0:
+  /* Return original dst pointer.  */
+    ld    3,-16(1)
+    blr
+
+/* Special case to copy 0-8 bytes.  */
+    .align  4
+.LE8:
+    mr    12,4
+    bne   cr6,4f
+/* Would have liked to use use ld/std here but the 630 processors are
+   slow for load/store doubles that are not at least word aligned.  
+   Unaligned Load/Store word execute with only a 1 cycle penaltity.  */
+    lwz   6,0(4)
+    lwz   7,4(4)
+    stw   6,0(3)
+    stw   7,4(3)
+  /* Return original dst pointer.  */
+    ld    3,-16(1)
+    blr
+    .align  4
+4:  bf    29,2b
+    lwz   6,0(4)
+    stw   6,0(3)
+6:
+    bf    30,5f
+    lhz   7,4(4)
+    sth   7,4(3) 
+    bf    31,0f
+    lbz   8,6(4)
+    stb   8,6(3)
+    ld 3,-16(1)
+    blr
+    .align  4
+5:  
+    bf    31,0f
+    lbz   6,4(4)
+    stb   6,4(3)
+    .align  4
+0:
+  /* Return original dst pointer.  */
+    ld    3,-16(1)
+    blr
+
+    .align  4
+.L6:
+
+  /* Copy doublewords where the destination is aligned but the source is
+     not.  Use aligned doubleword loads from the source, shifted to realign
+     the data, to allow aligned destination stores.  */
+    addi    11,9,-1  /* loop DW count is one less than total */
+    subf    5,10,12
+    sldi    10,10,3
+    mr      4,3
+    srdi    8,11,2   /* calculate the 32 byte loop count */
+    ld      6,0(5)
+    mtcrf   0x01,11
+    cmpldi  cr6,9,4
+    mtctr   8
+    ld      7,8(5)
+    subfic  9,10,64
+    bf      30,1f
+
+    /* there are at least two DWs to copy */
+    sld     0,6,10
+    srd     8,7,9
+    or      0,0,8
+    ld      6,16(5)
+    std     0,0(4)
+    sld     0,7,10
+    srd     8,6,9
+    or      0,0,8
+    ld      7,24(5)
+    std     0,8(4)
+    addi    4,4,16
+    addi    5,5,32
+    blt     cr6,8f  /* if total DWs = 3, then bypass loop */
+    bf      31,4f
+    /* there is a third DW to copy */
+    sld     0,6,10
+    srd     8,7,9
+    or      0,0,8
+    std     0,0(4)
+    mr      6,7
+    ld      7,0(5)
+    addi    5,5,8
+    addi    4,4,8
+    beq     cr6,8f  /* if total DWs = 4, then bypass loop */
+    b       4f
+    .align 4
+1:
+    sld     0,6,10
+    srd     8,7,9
+    addi    5,5,16
+    or      0,0,8
+    bf      31,4f
+    mr      6,7
+    ld      7,0(5)
+    addi    5,5,8
+    std     0,0(4)
+    addi    4,4,8
+    .align 4
+/* copy 32 bytes at a time */
+4:  sld   0,6,10
+    srd   8,7,9
+    or    0,0,8
+    ld    6,0(5)
+    std   0,0(4)
+    sld   0,7,10
+    srd   8,6,9
+    or    0,0,8
+    ld    7,8(5)
+    std   0,8(4)
+    sld   0,6,10
+    srd   8,7,9
+    or    0,0,8
+    ld    6,16(5)
+    std   0,16(4)
+    sld   0,7,10
+    srd   8,6,9
+    or    0,0,8
+    ld    7,24(5)
+    std   0,24(4)
+    addi  5,5,32
+    addi  4,4,32
+    bdnz+ 4b
+    .align 4
+8:
+    /* calculate and store the final DW */
+    sld   0,6,10
+    srd   8,7,9
+    or    0,0,8  
+    std   0,0(4)
+3:
+    rldicr 0,31,0,60
+    mtcrf 0x01,31
+    bne   cr1,.L9	/* If the tail is 0 bytes we are done!  */
+  /* Return original dst pointer.  */
+    ld 31,-8(1)
+    ld 3,-16(1)
+    blr
+END_GEN_TB (BP_SYM (memcpy),TB_TOCLESS)
+libc_hidden_builtin_def (memcpy)
diff -urN dummy-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S libc24/power-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S
--- dummy-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S	Tue Dec 06 10:46:31 2005
@@ -0,0 +1,180 @@
+/* Optimized strcmp implementation for PowerPC64.
+   Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <sysdep.h>
+#include <bp-sym.h>
+#include <bp-asm.h>
+
+/* See strlen.s for comments on how the end-of-string testing works.  */
+
+/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
+
+EALIGN (BP_SYM(strncmp), 4, 0)
+	CALL_MCOUNT 3
+
+#define rTMP	r0
+#define rRTN	r3
+#define rSTR1	r3	/* first string arg */
+#define rSTR2	r4	/* second string arg */
+#define rN	r5	/* max string length */
+/* Note:  The Bounded pointer support in this code is broken.  This code
+   was inherited from PPC32 and and that support was never completed.  
+   Current PPC gcc does not support -fbounds-check or -fbounded-pointers.  */
+#define rWORD1	r6	/* current word in s1 */
+#define rWORD2	r7	/* current word in s2 */
+#define rWORD3  r10
+#define rWORD4  r11
+#define rFEFE	r8	/* constant 0xfefefefefefefeff (-0x0101010101010101) */
+#define r7F7F	r9	/* constant 0x7f7f7f7f7f7f7f7f */
+#define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
+#define rBITDIF	r11	/* bits that differ in s1 & s2 words */
+
+	dcbt	0,rSTR1
+	or	rTMP, rSTR2, rSTR1
+	lis	r7F7F, 0x7f7f
+	dcbt	0,rSTR2
+	clrldi.	rTMP, rTMP, 61
+	cmpldi	cr1, rN, 0
+	lis	rFEFE, -0x101
+	bne	L(unaligned)
+/* We are doubleword alligned so set up for two loops.  first a double word
+   loop, then fall into the byte loop if any residual.  */
+	srdi.	rTMP, rN, 3
+	clrldi	rN, rN, 61
+	addi	rFEFE, rFEFE, -0x101
+	addi	r7F7F, r7F7F, 0x7f7f
+	cmpldi	cr1, rN, 0	
+	beq	L(unaligned)
+
+	mtctr	rTMP	/* Power4 wants mtctr 1st in dispatch group.  */
+	ld	rWORD1, 0(rSTR1)
+	ld	rWORD2, 0(rSTR2)
+	sldi	rTMP, rFEFE, 32
+	insrdi	r7F7F, r7F7F, 32, 0
+	add	rFEFE, rFEFE, rTMP
+	b	L(g1)
+
+L(g0):	
+	ldu	rWORD1, 8(rSTR1)
+	bne-	cr1, L(different)
+	ldu	rWORD2, 8(rSTR2)
+L(g1):	add	rTMP, rFEFE, rWORD1
+	nor	rNEG, r7F7F, rWORD1
+	bdz	L(tail)
+	and.	rTMP, rTMP, rNEG
+	cmpd	cr1, rWORD1, rWORD2
+	beq+	L(g0)
+	
+/* 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...  */
+	
+L(endstring):
+	and	rTMP, r7F7F, rWORD1
+	beq	cr1, L(equal)
+	add	rTMP, rTMP, r7F7F
+	xor.	rBITDIF, rWORD1, rWORD2
+
+	andc	rNEG, rNEG, rTMP
+	blt-	L(highbit)
+	cntlzd	rBITDIF, rBITDIF
+	cntlzd	rNEG, rNEG
+	addi	rNEG, rNEG, 7
+	cmpd	cr1, rNEG, rBITDIF
+	sub	rRTN, rWORD1, rWORD2
+	blt-	cr1, L(equal)
+	sradi	rRTN, rRTN, 63
+	ori	rRTN, rRTN, 1
+	blr
+L(equal):
+	li	rRTN, 0
+	blr
+
+L(different):
+	ldu	rWORD1, -8(rSTR1)
+	xor.	rBITDIF, rWORD1, rWORD2
+	sub	rRTN, rWORD1, rWORD2
+	blt-	L(highbit)
+	sradi	rRTN, rRTN, 63
+	ori	rRTN, rRTN, 1
+	blr
+L(highbit):
+	srdi	rWORD2, rWORD2, 56
+	srdi	rWORD1, rWORD1, 56
+	sub	rRTN, rWORD1, rWORD2
+	blr
+
+
+/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
+	.align 4
+L(tail):
+	and.	rTMP, rTMP, rNEG
+	cmpd	cr1, rWORD1, rWORD2
+	bne-	L(endstring)
+	addi	rSTR1, rSTR1, 8
+	bne-	cr1, L(different)
+	addi	rSTR2, rSTR2, 8
+	cmpldi	cr1, rN, 0
+L(unaligned):
+	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
+	ble	cr1, L(ux)
+L(uz):
+	lbz	rWORD1, 0(rSTR1)
+	lbz	rWORD2, 0(rSTR2)
+	.align 4
+L(u1):
+	cmpdi	cr1, rWORD1, 0
+	bdz	L(u4)
+	cmpd	rWORD1, rWORD2
+	beq-	cr1, L(u4)
+	lbzu    rWORD3, 1(rSTR1)
+	lbzu	rWORD4, 1(rSTR2)
+	bne-	L(u4)
+	cmpdi	cr1, rWORD3, 0
+	bdz	L(u3)
+	cmpd	rWORD3, rWORD4
+	beq-    cr1, L(u3)
+	lbzu	rWORD1, 1(rSTR1)
+	lbzu	rWORD2, 1(rSTR2)
+	bne-    L(u3)
+	cmpdi	cr1, rWORD1, 0
+	bdz	L(u4)
+	cmpd	rWORD1, rWORD2
+	beq-	cr1, L(u4)
+	lbzu	rWORD3, 1(rSTR1)
+	lbzu	rWORD4, 1(rSTR2)
+	bne-	L(u4)
+	cmpdi	cr1, rWORD3, 0
+	bdz	L(u3)
+	cmpd	rWORD3, rWORD4
+	beq-    cr1, L(u3)
+	lbzu	rWORD1, 1(rSTR1)
+	lbzu	rWORD2, 1(rSTR2)
+	beq+    L(u1)
+
+L(u3):  sub     rRTN, rWORD3, rWORD4
+        blr
+L(u4):	sub	rRTN, rWORD1, rWORD2
+	blr
+L(ux):
+	li	rRTN, 0
+	blr
+END (BP_SYM (strncmp))
+libc_hidden_builtin_def (strncmp)
+
diff -urN dummy-cpu/sysdeps/powerpc/powerpc64/power5/Implies libc24/power-cpu/sysdeps/powerpc/powerpc64/power5/Implies
--- dummy-cpu/sysdeps/powerpc/powerpc64/power5/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/powerpc/powerpc64/power5/Implies	Mon Nov 28 11:30:59 2005
@@ -0,0 +1,1 @@
+powerpc/powerpc64/power4
diff -urN dummy-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.c libc24/power-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.c
--- dummy-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.c	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.c	Tue Nov 29 18:04:04 2005
@@ -0,0 +1,94 @@
+/* Data for linux/powerpc version of processor capability information.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+/* This information must be kept in sync with the _DL_HWCAP_COUNT and
+   _DL_PLATFORM_COUNT definitions in procinfo.h.
+
+   If anything should be added here check whether the size of each string
+   is still ok with the given array size.
+
+   All the #ifdefs in the definitions are quite irritating but
+   necessary if we want to avoid duplicating the information.  There
+   are three different modes:
+
+   - PROCINFO_DECL is defined.  This means we are only interested in
+     declarations.
+
+   - PROCINFO_DECL is not defined:
+
+     + if SHARED is defined the file is included in an array
+       initializer.  The .element = { ... } syntax is needed.
+
+     + if SHARED is not defined a normal array initialization is
+       needed.
+  */
+
+#ifndef PROCINFO_CLASS
+# define PROCINFO_CLASS
+#endif
+
+#if !defined PROCINFO_DECL && defined SHARED
+  ._dl_powerpc_cap_flags
+#else
+PROCINFO_CLASS const char _dl_powerpc_cap_flags[32][12]
+#endif
+#ifndef PROCINFO_DECL
+/*  Powerpc is big-endian but the common implementation is little-endian.
+    This also applies to bit numbering where PPC_FEATURE_32 should be 
+    bit 0, but in little-endian ends up as bit 31.  So to make things
+    work we have to pad the table with empty slots and reverse the order
+    of the name strings.  */
+= {
+    "", "", "", "",
+    "", "", "", "",
+    "", "", "", "",
+    "", "", "", "",
+    "cell", "power5_plus", "power5", "power4",
+    "NO-TB", "EFP_double", "EFP_float", "SPE",
+    "ucache", "4xxMAC", "MMU", "FPU", 
+    "Altivec", "601", "64-bit","32-bit"
+  }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+/* PowerPC does not support platform masks from the VDSO note.
+
+#if !defined PROCINFO_DECL && defined SHARED
+  ._dl_powerpc_platforms
+#else
+PROCINFO_CLASS const char _dl_powerpc_platforms[5][8]
+#endif
+#ifndef PROCINFO_DECL
+= {
+    "power4", "970", "power5", "power5+",
+    "cell"
+  }
+#endif
+#if !defined SHARED || defined PROCINFO_DECL
+;
+#else
+,
+#endif
+*/
+#undef PROCINFO_DECL
+#undef PROCINFO_CLASS
diff -urN dummy-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.h libc24/power-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.h
--- dummy-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.h	Wed Dec 31 18:00:00 1969
+++ libc24/power-cpu/sysdeps/unix/sysv/linux/powerpc/dl-procinfo.h	Tue Nov 29 17:47:22 2005
@@ -0,0 +1,99 @@
+/* Linux/powerpc version of processor capability information handling macros.
+   Copyright (C) 2005 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+
+#ifndef _DL_PROCINFO_H
+#define _DL_PROCINFO_H	1
+#include <ldsodefs.h>
+#include <sysdep.h>
+
+#define _DL_HWCAP_COUNT 32
+
+/* PowerPC does not use _DL_PLATFORMS_COUNT or _DL_FIRST_PLATFORM.  */
+
+/* Mask to filter out platforms.  */
+#define _DL_HWCAP_PLATFORM	(0xffff0000)
+				 
+
+#define HWCAP_IMPORTANT	(PPC_FEATURE_HAS_ALTIVEC \
+                       + PPC_FEATURE_POWER4 + PPC_FEATURE_POWER5 \
+		       + PPC_FEATURE_POWER5_PLUS + PPC_FEATURE_CELL)
+
+#undef _dl_procinfo
+static inline int
+__attribute__ ((unused))
+_dl_procinfo (int word)
+{
+  /* This table should match the information from arch/powerpc64/kernel/setup.c
+     in the kernel sources.  */
+  int i;
+  unsigned long int __mask = 0x00000001UL;
+
+  _dl_printf ("AT_HWCAP:   ");
+
+  for (i = 0; i < _DL_HWCAP_COUNT; ++i)
+  {
+    if (word & __mask)
+      _dl_printf (" %s", GLRO(dl_powerpc_cap_flags)[i]);
+    __mask <<= 1;
+  }
+
+  _dl_printf ("\n");
+
+  return 0;
+}
+
+
+static inline const char *
+__attribute__ ((unused))
+_dl_hwcap_string (int idx)
+{
+  return GLRO(dl_powerpc_cap_flags)[idx];
+};
+
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_hwcap (const char *str)
+{
+  int i;
+
+  for (i = 0; i < _DL_HWCAP_COUNT; i++)
+    {
+      if (strcmp (str, GLRO(dl_powerpc_cap_flags)[i]) == 0)
+	return i;
+    }
+  return -1;
+};
+/* PowerPC does not support platform masks from the VDSO note.
+
+static inline const char *
+__attribute__ ((unused))
+_dl_platform_string (int idx)
+{
+  return GLRO(dl_powerpc_platforms)[idx - _DL_FIRST_PLATFORM];
+};
+*/
+static inline int
+__attribute__ ((unused, always_inline))
+_dl_string_platform (const char *str)
+{
+  return -1;
+};
+#endif /* dl-procinfo.h */

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]