Blame sysdeps/powerpc/powerpc64/power4/strncmp.S

Packit Service 82fcde
/* Optimized strcmp implementation for PowerPC64.
Packit Service 82fcde
   Copyright (C) 2003-2018 Free Software Foundation, Inc.
Packit Service 82fcde
   This file is part of the GNU C Library.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU Lesser General Public
Packit Service 82fcde
   License as published by the Free Software Foundation; either
Packit Service 82fcde
   version 2.1 of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   The GNU C Library is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 82fcde
   Lesser General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU Lesser General Public
Packit Service 82fcde
   License along with the GNU C Library; if not, see
Packit Service 82fcde
   <http://www.gnu.org/licenses/>.  */
Packit Service 82fcde
Packit Service 82fcde
#include <sysdep.h>
Packit Service 82fcde
Packit Service 82fcde
#ifndef STRNCMP
Packit Service 82fcde
# define STRNCMP strncmp
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* See strlen.s for comments on how the end-of-string testing works.  */
Packit Service 82fcde
Packit Service 82fcde
/* int [r3] strncmp (const char *s1 [r3], const char *s2 [r4], size_t size [r5])  */
Packit Service 82fcde
Packit Service 82fcde
ENTRY_TOCLESS (STRNCMP, 4)
Packit Service 82fcde
	CALL_MCOUNT 3
Packit Service 82fcde
Packit Service 82fcde
#define rTMP2	r0
Packit Service 82fcde
#define rRTN	r3
Packit Service 82fcde
#define rSTR1	r3	/* first string arg */
Packit Service 82fcde
#define rSTR2	r4	/* second string arg */
Packit Service 82fcde
#define rN	r5	/* max string length */
Packit Service 82fcde
#define rWORD1	r6	/* current word in s1 */
Packit Service 82fcde
#define rWORD2	r7	/* current word in s2 */
Packit Service 82fcde
#define rWORD3  r10
Packit Service 82fcde
#define rWORD4  r11
Packit Service 82fcde
#define rFEFE	r8	/* constant 0xfefefefefefefeff (-0x0101010101010101) */
Packit Service 82fcde
#define r7F7F	r9	/* constant 0x7f7f7f7f7f7f7f7f */
Packit Service 82fcde
#define rNEG	r10	/* ~(word in s1 | 0x7f7f7f7f7f7f7f7f) */
Packit Service 82fcde
#define rBITDIF	r11	/* bits that differ in s1 & s2 words */
Packit Service 82fcde
#define rTMP	r12
Packit Service 82fcde
Packit Service 82fcde
	dcbt	0,rSTR1
Packit Service 82fcde
	or	rTMP, rSTR2, rSTR1
Packit Service 82fcde
	lis	r7F7F, 0x7f7f
Packit Service 82fcde
	dcbt	0,rSTR2
Packit Service 82fcde
	clrldi.	rTMP, rTMP, 61
Packit Service 82fcde
	cmpldi	cr1, rN, 0
Packit Service 82fcde
	lis	rFEFE, -0x101
Packit Service 82fcde
	bne	L(unaligned)
Packit Service 82fcde
/* We are doubleword aligned so set up for two loops.  first a double word
Packit Service 82fcde
   loop, then fall into the byte loop if any residual.  */
Packit Service 82fcde
	srdi.	rTMP, rN, 3
Packit Service 82fcde
	clrldi	rN, rN, 61
Packit Service 82fcde
	addi	rFEFE, rFEFE, -0x101
Packit Service 82fcde
	addi	r7F7F, r7F7F, 0x7f7f
Packit Service 82fcde
	cmpldi	cr1, rN, 0
Packit Service 82fcde
	beq	L(unaligned)
Packit Service 82fcde
Packit Service 82fcde
	mtctr	rTMP	/* Power4 wants mtctr 1st in dispatch group.  */
Packit Service 82fcde
	ld	rWORD1, 0(rSTR1)
Packit Service 82fcde
	ld	rWORD2, 0(rSTR2)
Packit Service 82fcde
	sldi	rTMP, rFEFE, 32
Packit Service 82fcde
	insrdi	r7F7F, r7F7F, 32, 0
Packit Service 82fcde
	add	rFEFE, rFEFE, rTMP
Packit Service 82fcde
	b	L(g1)
Packit Service 82fcde
Packit Service 82fcde
L(g0):
Packit Service 82fcde
	ldu	rWORD1, 8(rSTR1)
Packit Service 82fcde
	bne-	cr1, L(different)
Packit Service 82fcde
	ldu	rWORD2, 8(rSTR2)
Packit Service 82fcde
L(g1):	add	rTMP, rFEFE, rWORD1
Packit Service 82fcde
	nor	rNEG, r7F7F, rWORD1
Packit Service 82fcde
	bdz	L(tail)
Packit Service 82fcde
	and.	rTMP, rTMP, rNEG
Packit Service 82fcde
	cmpd	cr1, rWORD1, rWORD2
Packit Service 82fcde
	beq+	L(g0)
Packit Service 82fcde
Packit Service 82fcde
/* OK. We've hit the end of the string. We need to be careful that
Packit Service 82fcde
   we don't compare two strings as different because of gunk beyond
Packit Service 82fcde
   the end of the strings...  */
Packit Service 82fcde
Packit Service 82fcde
#ifdef __LITTLE_ENDIAN__
Packit Service 82fcde
L(endstring):
Packit Service 82fcde
	addi    rTMP2, rTMP, -1
Packit Service 82fcde
	beq	cr1, L(equal)
Packit Service 82fcde
	andc    rTMP2, rTMP2, rTMP
Packit Service 82fcde
	rldimi	rTMP2, rTMP2, 1, 0
Packit Service 82fcde
	and	rWORD2, rWORD2, rTMP2	/* Mask off gunk.  */
Packit Service 82fcde
	and	rWORD1, rWORD1, rTMP2
Packit Service 82fcde
	cmpd	cr1, rWORD1, rWORD2
Packit Service 82fcde
	beq	cr1, L(equal)
Packit Service 82fcde
	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
Packit Service 82fcde
	neg	rNEG, rBITDIF
Packit Service 82fcde
	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
Packit Service 82fcde
	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
Packit Service 82fcde
	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
Packit Service 82fcde
	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
Packit Service 82fcde
	sld	rWORD2, rWORD2, rNEG
Packit Service 82fcde
	xor.	rBITDIF, rWORD1, rWORD2
Packit Service 82fcde
	sub	rRTN, rWORD1, rWORD2
Packit Service 82fcde
	blt-	L(highbit)
Packit Service 82fcde
	sradi	rRTN, rRTN, 63		/* must return an int.  */
Packit Service 82fcde
	ori	rRTN, rRTN, 1
Packit Service 82fcde
	blr
Packit Service 82fcde
L(equal):
Packit Service 82fcde
	li	rRTN, 0
Packit Service 82fcde
	blr
Packit Service 82fcde
Packit Service 82fcde
L(different):
Packit Service 82fcde
	ld	rWORD1, -8(rSTR1)
Packit Service 82fcde
	xor	rBITDIF, rWORD1, rWORD2	/* rBITDIF has bits that differ.  */
Packit Service 82fcde
	neg	rNEG, rBITDIF
Packit Service 82fcde
	and	rNEG, rNEG, rBITDIF	/* rNEG has LS bit that differs.  */
Packit Service 82fcde
	cntlzd	rNEG, rNEG		/* bitcount of the bit.  */
Packit Service 82fcde
	andi.	rNEG, rNEG, 56		/* bitcount to LS byte that differs. */
Packit Service 82fcde
	sld	rWORD1, rWORD1, rNEG	/* shift left to clear MS bytes.  */
Packit Service 82fcde
	sld	rWORD2, rWORD2, rNEG
Packit Service 82fcde
	xor.	rBITDIF, rWORD1, rWORD2
Packit Service 82fcde
	sub	rRTN, rWORD1, rWORD2
Packit Service 82fcde
	blt-	L(highbit)
Packit Service 82fcde
	sradi	rRTN, rRTN, 63
Packit Service 82fcde
	ori	rRTN, rRTN, 1
Packit Service 82fcde
	blr
Packit Service 82fcde
L(highbit):
Packit Service 82fcde
	sradi	rRTN, rWORD2, 63
Packit Service 82fcde
	ori	rRTN, rRTN, 1
Packit Service 82fcde
	blr
Packit Service 82fcde
Packit Service 82fcde
#else
Packit Service 82fcde
L(endstring):
Packit Service 82fcde
	and	rTMP, r7F7F, rWORD1
Packit Service 82fcde
	beq	cr1, L(equal)
Packit Service 82fcde
	add	rTMP, rTMP, r7F7F
Packit Service 82fcde
	xor.	rBITDIF, rWORD1, rWORD2
Packit Service 82fcde
	andc	rNEG, rNEG, rTMP
Packit Service 82fcde
	blt-	L(highbit)
Packit Service 82fcde
	cntlzd	rBITDIF, rBITDIF
Packit Service 82fcde
	cntlzd	rNEG, rNEG
Packit Service 82fcde
	addi	rNEG, rNEG, 7
Packit Service 82fcde
	cmpd	cr1, rNEG, rBITDIF
Packit Service 82fcde
	sub	rRTN, rWORD1, rWORD2
Packit Service 82fcde
	blt-	cr1, L(equal)
Packit Service 82fcde
	sradi	rRTN, rRTN, 63		/* must return an int.  */
Packit Service 82fcde
	ori	rRTN, rRTN, 1
Packit Service 82fcde
	blr
Packit Service 82fcde
L(equal):
Packit Service 82fcde
	li	rRTN, 0
Packit Service 82fcde
	blr
Packit Service 82fcde
Packit Service 82fcde
L(different):
Packit Service 82fcde
	ld	rWORD1, -8(rSTR1)
Packit Service 82fcde
	xor.	rBITDIF, rWORD1, rWORD2
Packit Service 82fcde
	sub	rRTN, rWORD1, rWORD2
Packit Service 82fcde
	blt-	L(highbit)
Packit Service 82fcde
	sradi	rRTN, rRTN, 63
Packit Service 82fcde
	ori	rRTN, rRTN, 1
Packit Service 82fcde
	blr
Packit Service 82fcde
L(highbit):
Packit Service 82fcde
	sradi	rRTN, rWORD2, 63
Packit Service 82fcde
	ori	rRTN, rRTN, 1
Packit Service 82fcde
	blr
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
/* Oh well.  In this case, we just do a byte-by-byte comparison.  */
Packit Service 82fcde
	.align 4
Packit Service 82fcde
L(tail):
Packit Service 82fcde
	and.	rTMP, rTMP, rNEG
Packit Service 82fcde
	cmpd	cr1, rWORD1, rWORD2
Packit Service 82fcde
	bne-	L(endstring)
Packit Service 82fcde
	addi	rSTR1, rSTR1, 8
Packit Service 82fcde
	bne-	cr1, L(different)
Packit Service 82fcde
	addi	rSTR2, rSTR2, 8
Packit Service 82fcde
	cmpldi	cr1, rN, 0
Packit Service 82fcde
L(unaligned):
Packit Service 82fcde
	mtctr   rN	/* Power4 wants mtctr 1st in dispatch group */
Packit Service 82fcde
	ble	cr1, L(ux)
Packit Service 82fcde
L(uz):
Packit Service 82fcde
	lbz	rWORD1, 0(rSTR1)
Packit Service 82fcde
	lbz	rWORD2, 0(rSTR2)
Packit Service 82fcde
	.align 4
Packit Service 82fcde
L(u1):
Packit Service 82fcde
	cmpdi	cr1, rWORD1, 0
Packit Service 82fcde
	bdz	L(u4)
Packit Service 82fcde
	cmpd	rWORD1, rWORD2
Packit Service 82fcde
	beq-	cr1, L(u4)
Packit Service 82fcde
	bne-	L(u4)
Packit Service 82fcde
	lbzu    rWORD3, 1(rSTR1)
Packit Service 82fcde
	lbzu	rWORD4, 1(rSTR2)
Packit Service 82fcde
	cmpdi	cr1, rWORD3, 0
Packit Service 82fcde
	bdz	L(u3)
Packit Service 82fcde
	cmpd	rWORD3, rWORD4
Packit Service 82fcde
	beq-    cr1, L(u3)
Packit Service 82fcde
	bne-    L(u3)
Packit Service 82fcde
	lbzu	rWORD1, 1(rSTR1)
Packit Service 82fcde
	lbzu	rWORD2, 1(rSTR2)
Packit Service 82fcde
	cmpdi	cr1, rWORD1, 0
Packit Service 82fcde
	bdz	L(u4)
Packit Service 82fcde
	cmpd	rWORD1, rWORD2
Packit Service 82fcde
	beq-	cr1, L(u4)
Packit Service 82fcde
	bne-	L(u4)
Packit Service 82fcde
	lbzu	rWORD3, 1(rSTR1)
Packit Service 82fcde
	lbzu	rWORD4, 1(rSTR2)
Packit Service 82fcde
	cmpdi	cr1, rWORD3, 0
Packit Service 82fcde
	bdz	L(u3)
Packit Service 82fcde
	cmpd	rWORD3, rWORD4
Packit Service 82fcde
	beq-    cr1, L(u3)
Packit Service 82fcde
	bne-    L(u3)
Packit Service 82fcde
	lbzu	rWORD1, 1(rSTR1)
Packit Service 82fcde
	lbzu	rWORD2, 1(rSTR2)
Packit Service 82fcde
	b       L(u1)
Packit Service 82fcde
Packit Service 82fcde
L(u3):  sub     rRTN, rWORD3, rWORD4
Packit Service 82fcde
	blr
Packit Service 82fcde
L(u4):	sub	rRTN, rWORD1, rWORD2
Packit Service 82fcde
	blr
Packit Service 82fcde
L(ux):
Packit Service 82fcde
	li	rRTN, 0
Packit Service 82fcde
	blr
Packit Service 82fcde
END (STRNCMP)
Packit Service 82fcde
libc_hidden_builtin_def (strncmp)