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] powerpc-cpu add-on for --with-cpu


This update fixes a latent bug in the powerpc64/memcmp.S implementation.
In this case the return value was not constrained to an int as required
by the posix spec. In this case we replaces the simple subtract with a
compare/branch sequence that return s -1, 0, +1 as appropriate.  When
scheduled with loads from the epiloque there is minimum cycle penalty.

Also removed mathinline.h form this patch as the fsqrt exploitation is
now in the libc trunc, thanks to Jukub.




2006-02-14  Steven Munroe  <sjmunroe@us.ibm.com>

	* Makefile: New file.
	* README: New file.
	* configure: New file.
	* sysdeps/powerpc/powerpc32/970/Implies: 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/fpu/s_llrint.S: New file.
	* sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S: New file.
	* sysdeps/powerpc/powerpc64/970/Implies: 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.


diff -urN dummy-libc/powerpc-cpu/Makefile libc24/powerpc-cpu/Makefile
--- dummy-libc/powerpc-cpu/Makefile	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/Makefile	Tue Feb 14 08:38:22 2006
@@ -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-libc/powerpc-cpu/README libc24/powerpc-cpu/README
--- dummy-libc/powerpc-cpu/README	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/README	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,60 @@
+The powerpc-cpu directory is an add-on for the GNU C Library (glibc).
+It provides additional platform/cpu specific optimizations when the
+--with-cpu= configure option is specified.  Specifying --with-cpu=<cpu_type>
+on the configure implicitly inserts the -mcpu=<cpu_type> option for gcc
+commands in the glibc make. It also inserts <cpu_type> specific directories
+into the source search path for glibc.
+
+The scripts in the top level of this directory provide the infrastructure
+necessary for a glibc add-on.  The real source code is found in the 
+sysdeps/powerpc/powerpc32 and sysdeps/powerpc/powerpc64 subdirectories.
+These directories support the 32- and 64-bit ELF ABIs of the powerpc platform.
+The next directory level is "<cpu_type>" where the names match supported
+gcc -mcpu= options.  When --with-cpu=<cpu_type> is specified, the <cpu_type>
+must match one of the directories at this level.
+
+The mechanism is generalized and can be extended to any "cpu-type" that is
+accepted by gcc's -mcpu= option.  To support another "cpu_type" simply add a
+directory of the form:
+
+./powerpc-cpu/sysdeps/powerpc/powerpc32/<cpu_type>
+
+and for 64-bit implementations also:
+
+./powerpc-cpu/sysdeps/powerpc/powerpc64/<cpu_type>
+
+See the GCC online documentation <http://gcc.gnu.org/onlinedocs> 
+3.17.24 "IBM RS/6000 and PowerPC Options" for the complete list of -mcpu=
+options.
+
+So far the cpu_type's power4 and power5 are enabled with specific assembler
+implementations and have corresponding directories for both powerpc32 and
+powerpc64.  For 64-bit <cpu_types>, implementations of the 32-bit ABI can
+share code exploiting 64-bit instructions from the generic cpu_type powerpc64
+(directory sysdeps/powerpc/powerpc32/powerpc64).  Specifically an "Implies"
+file, can be included in any sysdeps/powerpc/powerpc32/<cpu_type> directory
+where <cpu_type> is a 64-bit processor.  This is useful when the
+implementation wants to exploit 64-bit instructions in 32-bit mode.
+
+To build with this add-on you need to configure glibc specifying both
+--enable-add-ons=powerpc-cpu,.. and --with-cpu=<cpu_type> options.  If you
+specify multiple add-ons, powerpc-cpu should be first to insure that any
+optimizations can override the corresponding source files from mainline glibc. 
+For example: "--enable-add-ons=powerpc-cpu,nptl".
+
+Special note: While this add-on is currently focused on powerpc, the
+mechanism is general enough to be used by any platform which also supports
+gcc's -mcpu= option.  Simply add the appropriate ./sysdeps/<target>/<cpu_type>
+directories. 
+
+Currently supported cpu_types are:
+
+power4
+power5
+970
+
+Special note: Currently the "970" implementation is implied to the power4
+implementation.  The internal micro-architecture of the 970 chip is based on
+the power4 design and any instruction scheduling for integer and floating point
+units is the same for power4 and 970.  Any 970 unique code would be specific
+to Altivec/VMX exploitation which we don't have any examples of yet.
diff -urN dummy-libc/powerpc-cpu/configure libc24/powerpc-cpu/configure
--- dummy-libc/powerpc-cpu/configure	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/configure	Tue Feb 14 08:38:22 2006
@@ -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-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/970/Implies libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/970/Implies
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/970/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/970/Implies	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,1 @@
+powerpc/powerpc32/power4
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/fpu/Implies	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,1 @@
+powerpc/powerpc32/powerpc64/fpu
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcmp.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,985 @@
+/* Optimized strcmp implementation for PowerPC64.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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)
+	cfi_adjust_cfa_offset(64)
+        stw     r31,48(1)	
+	cfi_offset(31,(48-64))
+        stw     r30,44(1)	
+	cfi_offset(30,(44-64))
+	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):
+	cfi_adjust_cfa_offset(-64)
+	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
+
+	cfi_adjust_cfa_offset(64)
+	.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)	
+	cfi_offset(r29,(40-64))	
+	clrlwi	rSHL, rSTR2, 30
+        stw     r28,36(r1)	
+	cfi_offset(r28,(36-64))
+	beq	cr5, L(Wunaligned)
+        stw     r27,32(r1)	
+	cfi_offset(r27,(32-64))
+/* 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)	
+	cfi_offset(r26,(28-64))
+/* 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)	
+	cfi_offset(r25,(24-64))
+	slwi	rSHL, rSHL, 3
+	cmplw	cr5, r27, rSTR2
+	add	rN, rN, rBITDIF
+	slwi	r11, rBITDIF, 3
+        stw     r24,20(r1)	
+	cfi_offset(r24,(20-64))
+	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)	
+	cfi_offset(r27,(32-64))
+	clrrwi	rSTR2, rSTR2, 2
+        stw     r26,28(r1)	
+	cfi_offset(r26,(28-64))
+	srwi	rTMP, rN, 4	 /* Divide by 16 */
+        stw     r25,24(r1)	
+	cfi_offset(r25,(24-64))
+	andi.	rBITDIF, rN, 12  /* Get the W remainder */
+        stw     r24,20(r1)	
+	cfi_offset(r24,(24-64))
+	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
+END (BP_SYM (memcmp))
+
+libc_hidden_builtin_def (memcmp)
+weak_alias (memcmp, bcmp)
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memcpy.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,425 @@
+/* Optimized memcpy implementation for PowerPC32 on PowerPC64.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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)
+    cfi_adjust_cfa_offset(32)
+    stw   30,20(1)
+    cfi_offset(30,(20-32))
+    mr    30,3
+    cmplwi cr1,5,31     
+    stw   31,24(1)
+    cfi_offset(31,(24-32))
+    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  
+    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
+END (BP_SYM (memcpy))
+
+libc_hidden_builtin_def (memcpy)
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memset.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memset.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memset.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/memset.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,228 @@
+/* Optimized memset implementation for PowerPC64.
+   Copyright (C) 1997,99, 2000,02,03, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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
+END (BP_SYM (memset))
+libc_hidden_builtin_def (memset)
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power4/strncmp.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,176 @@
+/* Optimized strcmp implementation for PowerPC32.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/Implies libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/Implies
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/Implies	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,1 @@
+powerpc/powerpc32/power4
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/power5/fpu/Implies	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,1 @@
+powerpc/powerpc32/powerpc64/fpu
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrint.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,43 @@
+/* Round double to long int.  PowerPC32 on PowerPC64 version.
+   Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+
+/* long long int[r3, r4] __llrint (double x[fp1])  */
+ENTRY (__llrint)	
+	CALL_MCOUNT
+	stwu	r1,-16(r1)
+	cfi_adjust_cfa_offset (16)
+	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,12(r1)
+	addi	r1,r1,16	
+	blr
+	END (__llrint)
+
+weak_alias (__llrint, llrint)
+
+#ifdef NO_LONG_DOUBLE
+strong_alias (__llrint, __llrintl)
+weak_alias (__llrint, llrintl)
+#endif
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc32/powerpc64/fpu/s_llrintf.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,39 @@
+/* Round float to long int.  PowerPC32 on PowerPC64 version.
+   Copyright (C) 2004, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+
+/* long long int[r3, r4] __llrintf (float x[fp1])  */
+ENTRY (__llrintf)	
+	CALL_MCOUNT
+	stwu	r1,-16(r1)
+	cfi_adjust_cfa_offset (16)
+	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,12(r1)
+	addi	r1,r1,16	
+	blr
+	END (__llrintf)
+
+weak_alias (__llrintf, llrintf)
+
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/970/Implies libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/970/Implies
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/970/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/970/Implies	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,1 @@
+powerpc/powerpc64/power4
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcmp.S	Tue Feb 14 15:12:56 2006
@@ -0,0 +1,981 @@
+/* Optimized strcmp implementation for PowerPC64.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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)	
+	cfi_offset(rWORD8,-8)
+	std	rWORD7,-16(r1)	
+	cfi_offset(rWORD7,-16)
+	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.  */ 
+L(d00):
+	ld	rWORD1, 8(rSTR1)
+	ld	rWORD2, 8(rSTR2) 
+	srd	rWORD1, rWORD1, rN
+	srd	rWORD2, rWORD2, rN
+	cmpld	cr5, rWORD1, rWORD2
+ 	bne	cr5, L(dLcr5x)
+	li	rRTN, 0
+	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)	
+	cfi_offset(r29,-24)
+	clrldi	rSHL, rSTR2, 61
+	beq-	cr6, L(duzeroLength)
+	std	r28,-32(r1)	
+	cfi_offset(r28,-32)
+	beq	cr5, L(DWunaligned)
+	std	r27,-40(r1)	
+	cfi_offset(r27,-40)
+/* 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)	
+	cfi_offset(r26,-48)
+/* 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)	
+	cfi_offset(r25,-56)
+	sldi	rSHL, rSHL, 3
+	cmpld	cr5, r27, rSTR2
+	add	rN, rN, rBITDIF
+	sldi	r11, rBITDIF, 3
+	std	r24,-64(r1)	
+	cfi_offset(r24,-64)
+	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)	
+	cfi_offset(r27,-40)
+	clrrdi	rSTR2, rSTR2, 3
+	std	r26,-48(r1)	
+	cfi_offset(r26,-48)
+	srdi	rTMP, rN, 5	/* Divide by 32 */
+	std	r25,-56(r1)	
+	cfi_offset(r25,-56)
+	andi.	rBITDIF, rN, 24	/* Get the DW remainder */
+	std	r24,-64(r1)	
+	cfi_offset(r24,-64)
+	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)
+	li	rRTN, 0
+	cmpld	cr0, rWORD1, rWORD2	
+	ld	r26,-48(r1)
+	ld	r25,-56(r1)
+ 	beq	cr0, L(dureturn24)
+	li	rRTN, 1
+	ld	r24,-64(r1)
+	bgtlr	cr0
+	li	rRTN, -1
+	blr
+	.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)
+L(dureturn24):
+	ld	r24,-64(r1)
+	blr
+L(duzeroLength):
+	li	rRTN,0
+	blr
+
+END (BP_SYM (memcmp))
+libc_hidden_builtin_def (memcmp)
+weak_alias (memcmp, bcmp)
diff -urN dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/memcpy.S	Tue Feb 14 14:40:06 2006
@@ -0,0 +1,417 @@
+/* Optimized memcpy implementation for PowerPC64.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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)
+    cfi_offset(31,-8)
+    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-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power4/strncmp.S	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,180 @@
+/* Optimized strcmp implementation for PowerPC64.
+   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA
+   02110-1301 USA.  */
+
+#include <sysdep.h>
+#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-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power5/Implies libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power5/Implies
--- dummy-libc/powerpc-cpu/sysdeps/powerpc/powerpc64/power5/Implies	Wed Dec 31 18:00:00 1969
+++ libc24/powerpc-cpu/sysdeps/powerpc/powerpc64/power5/Implies	Tue Feb 14 08:38:22 2006
@@ -0,0 +1,1 @@
+powerpc/powerpc64/power4

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