2014-06-06 12:56:07 +00:00
|
|
|
/* Optimized strcmp implementation for Power7 using 'cmpb' instruction
|
2021-01-02 19:32:25 +00:00
|
|
|
Copyright (C) 2014-2021 Free Software Foundation, Inc.
|
2014-06-06 12:56:07 +00:00
|
|
|
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, see
|
Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:
sed -ri '
s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
$(find $(git ls-files) -prune -type f \
! -name '*.po' \
! -name 'ChangeLog*' \
! -path COPYING ! -path COPYING.LIB \
! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
! -path manual/texinfo.tex ! -path scripts/config.guess \
! -path scripts/config.sub ! -path scripts/install-sh \
! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
! -path INSTALL ! -path locale/programs/charmap-kw.h \
! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
! '(' -name configure \
-execdir test -f configure.ac -o -f configure.in ';' ')' \
! '(' -name preconfigure \
-execdir test -f preconfigure.ac ';' ')' \
-print)
and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:
chmod a+x sysdeps/unix/sysv/linux/riscv/configure
# Omit irrelevant whitespace and comment-only changes,
# perhaps from a slightly-different Autoconf version.
git checkout -f \
sysdeps/csky/configure \
sysdeps/hppa/configure \
sysdeps/riscv/configure \
sysdeps/unix/sysv/linux/csky/configure
# Omit changes that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
git checkout -f \
sysdeps/powerpc/powerpc64/ppc-mcount.S \
sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
# Omit change that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
|
|
|
<https://www.gnu.org/licenses/>. */
|
2014-06-06 12:56:07 +00:00
|
|
|
|
|
|
|
/* The optimization is achieved here through cmpb instruction.
|
|
|
|
8byte aligned strings are processed with double word comparision
|
|
|
|
and unaligned strings are handled effectively with loop unrolling
|
|
|
|
technique */
|
|
|
|
|
|
|
|
#include <sysdep.h>
|
|
|
|
|
2017-04-11 17:18:34 +00:00
|
|
|
#ifndef STRCMP
|
|
|
|
# define STRCMP strcmp
|
|
|
|
#endif
|
|
|
|
|
2014-06-06 12:56:07 +00:00
|
|
|
/* int [r3] strcmp (const char *s1 [r3], const char *s2 [r4]) */
|
|
|
|
|
2015-01-09 16:56:35 +00:00
|
|
|
.machine power7
|
PowerPC64 ENTRY_TOCLESS
A number of functions in the sysdeps/powerpc/powerpc64/ tree don't use
or change r2, yet declare a global entry that sets up r2. This patch
fixes that problem, and consolidates the ENTRY and EALIGN macros.
* sysdeps/powerpc/powerpc64/sysdep.h: Formatting.
(NOPS, ENTRY_3): New macros.
(ENTRY): Rewrite.
(ENTRY_TOCLESS): Define.
(EALIGN, EALIGN_W_0, EALIGN_W_1, EALIGN_W_2, EALIGN_W_4, EALIGN_W_5,
EALIGN_W_6, EALIGN_W_7, EALIGN_W_8): Delete.
* sysdeps/powerpc/powerpc64/a2/memcpy.S: Replace EALIGN with ENTRY.
* sysdeps/powerpc/powerpc64/dl-trampoline.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_ceil.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_ceilf.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_floor.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_floorf.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_nearbyint.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_nearbyintf.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_rint.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_rintf.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_round.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_roundf.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_trunc.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_truncf.S: Likewise.
* sysdeps/powerpc/powerpc64/memset.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/fpu/s_finite.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/fpu/s_isinf.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/fpu/s_isnan.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strstr.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/e_expf.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_cosf.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_sinf.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strcasestr.S: Likewise.
* sysdeps/powerpc/powerpc64/addmul_1.S: Use ENTRY_TOCLESS.
* sysdeps/powerpc/powerpc64/cell/memcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_copysign.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_copysignl.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_fabsl.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_isnan.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_llrint.S: Likewise.
* sysdeps/powerpc/powerpc64/fpu/s_llrintf.S: Likewise.
* sysdeps/powerpc/powerpc64/lshift.S: Likewise.
* sysdeps/powerpc/powerpc64/memcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/mul_1.S: Likewise.
* sysdeps/powerpc/powerpc64/power4/memcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power4/memcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power4/memset.S: Likewise.
* sysdeps/powerpc/powerpc64/power4/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_ceil.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_ceilf.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_floor.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_floorf.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_llround.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_round.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_roundf.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_trunc.S: Likewise.
* sysdeps/powerpc/powerpc64/power5+/fpu/s_truncf.S: Likewise.
* sysdeps/powerpc/powerpc64/power5/fpu/s_isnan.S: Likewise.
* sysdeps/powerpc/powerpc64/power6/fpu/s_copysign.S: Likewise.
* sysdeps/powerpc/powerpc64/power6/fpu/s_isnan.S: Likewise.
* sysdeps/powerpc/powerpc64/power6/memcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power6/memset.S: Likewise.
* sysdeps/powerpc/powerpc64/power6x/fpu/s_isnan.S: Likewise.
* sysdeps/powerpc/powerpc64/power6x/fpu/s_llrint.S: Likewise.
* sysdeps/powerpc/powerpc64/power6x/fpu/s_llround.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/add_n.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/memchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/memcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/memcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/memmove.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/mempcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/memrchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/memset.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/rawmemchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strcasecmp.S (strcasecmp_l):
Likewise.
* sysdeps/powerpc/powerpc64/power7/strchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strchrnul.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strlen.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strncpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strnlen.S: Likewise.
* sysdeps/powerpc/powerpc64/power7/strrchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_finite.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_isinf.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_isnan.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_llrint.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/fpu/s_llround.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/memcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/memset.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strcpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strlen.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strncpy.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strnlen.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strrchr.S: Likewise.
* sysdeps/powerpc/powerpc64/power8/strspn.S: Likewise.
* sysdeps/powerpc/powerpc64/power9/strcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/power9/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/strchr.S: Likewise.
* sysdeps/powerpc/powerpc64/strcmp.S: Likewise.
* sysdeps/powerpc/powerpc64/strlen.S: Likewise.
* sysdeps/powerpc/powerpc64/strncmp.S: Likewise.
* sysdeps/powerpc/powerpc64/ppc-mcount.S: Store LR earlier. Don't
add nop when SHARED.
* sysdeps/powerpc/powerpc64/start.S: Fix comment.
* sysdeps/powerpc/powerpc64/multiarch/strrchr-power8.S (ENTRY): Don't
define.
(ENTRY_TOCLESS): Define.
* sysdeps/powerpc/powerpc32/sysdep.h (ENTRY_TOCLESS): Define.
* sysdeps/powerpc/fpu/s_fma.S: Use ENTRY_TOCLESS.
* sysdeps/powerpc/fpu/s_fmaf.S: Likewise.
2017-06-14 01:15:50 +00:00
|
|
|
ENTRY_TOCLESS (STRCMP, 4)
|
2014-06-06 12:56:07 +00:00
|
|
|
CALL_MCOUNT 2
|
|
|
|
|
|
|
|
or r9, r3, r4
|
|
|
|
rldicl. r10, r9, 0, 61 /* are s1 and s2 8 byte aligned..? */
|
|
|
|
bne cr0, L(process_unaligned_bytes)
|
2015-01-09 16:56:35 +00:00
|
|
|
li r5, 0
|
2014-06-06 12:56:07 +00:00
|
|
|
|
2015-01-09 16:56:35 +00:00
|
|
|
.align 4
|
2014-06-06 12:56:07 +00:00
|
|
|
/* process input parameters on double word aligned boundary */
|
|
|
|
L(unrollDword):
|
2015-01-09 16:56:35 +00:00
|
|
|
ld r8,0(r3)
|
|
|
|
ld r10,0(r4)
|
|
|
|
cmpb r7,r8,r5
|
|
|
|
cmpdi cr7,r7,0
|
|
|
|
mr r9,r7
|
|
|
|
bne cr7,L(null_found)
|
|
|
|
cmpld cr7,r8,r10
|
|
|
|
bne cr7,L(different)
|
|
|
|
|
|
|
|
ld r8,8(r3)
|
|
|
|
ld r10,8(r4)
|
|
|
|
cmpb r7,r8,r5
|
|
|
|
cmpdi cr7,r7,0
|
|
|
|
mr r9,r7
|
|
|
|
bne cr7,L(null_found)
|
|
|
|
cmpld cr7,r8,r10
|
|
|
|
bne cr7,L(different)
|
|
|
|
|
|
|
|
ld r8,16(r3)
|
|
|
|
ld r10,16(r4)
|
|
|
|
cmpb r7,r8,r5
|
|
|
|
cmpdi cr7,r7,0
|
|
|
|
mr r9,r7
|
|
|
|
bne cr7,L(null_found)
|
|
|
|
cmpld cr7,r8,r10
|
|
|
|
bne cr7,L(different)
|
|
|
|
|
|
|
|
ld r8,24(r3)
|
|
|
|
ld r10,24(r4)
|
|
|
|
cmpb r7,r8,r5
|
|
|
|
cmpdi cr7,r7,0
|
|
|
|
mr r9,r7
|
|
|
|
bne cr7,L(null_found)
|
|
|
|
cmpld cr7,r8,r10
|
|
|
|
bne cr7,L(different)
|
|
|
|
|
|
|
|
addi r3, r3, 32
|
|
|
|
addi r4, r4, 32
|
|
|
|
beq cr7, L(unrollDword)
|
|
|
|
|
|
|
|
.align 4
|
|
|
|
L(null_found):
|
|
|
|
#ifdef __LITTLE_ENDIAN__
|
|
|
|
neg r7,r9
|
|
|
|
and r9,r9,r7
|
|
|
|
li r7,-1
|
|
|
|
cntlzd r9,r9
|
|
|
|
subfic r9,r9,71
|
|
|
|
sld r9,r7,r9
|
|
|
|
#else
|
|
|
|
cntlzd r9,r9
|
|
|
|
li r7,-1
|
|
|
|
addi r9,r9,8
|
|
|
|
srd r9,r7,r9
|
|
|
|
#endif
|
|
|
|
or r8,r8,r9
|
|
|
|
or r10,r10,r9
|
|
|
|
|
|
|
|
L(different):
|
|
|
|
cmpb r9,r8,r10
|
|
|
|
#ifdef __LITTLE_ENDIAN__
|
|
|
|
addi r7,r9,1
|
|
|
|
andc r9,r7,r9
|
|
|
|
cntlzd r9,r9
|
|
|
|
subfic r9,r9,63
|
|
|
|
#else
|
|
|
|
not r9,r9
|
|
|
|
cntlzd r9,r9
|
|
|
|
subfic r9,r9,56
|
|
|
|
#endif
|
|
|
|
srd r3,r8,r9
|
|
|
|
srd r10,r10,r9
|
|
|
|
rldicl r10,r10,0,56
|
|
|
|
rldicl r3,r3,0,56
|
|
|
|
subf r3,r10,r3
|
|
|
|
blr
|
|
|
|
|
|
|
|
.align 4
|
2014-06-06 12:56:07 +00:00
|
|
|
L(process_unaligned_bytes):
|
|
|
|
lbz r9, 0(r3) /* load byte from s1 */
|
|
|
|
lbz r10, 0(r4) /* load byte from s2 */
|
|
|
|
cmpdi cr7, r9, 0 /* compare *s1 with NULL */
|
|
|
|
beq cr7, L(diffOfNULL) /* if *s1 is NULL , return *s1 - *s2 */
|
|
|
|
cmplw cr7, r9, r10 /* compare *s1 and *s2 */
|
|
|
|
bne cr7, L(ComputeDiff) /* branch to compute difference and return */
|
|
|
|
|
|
|
|
lbz r9, 1(r3) /* load next byte from s1 */
|
|
|
|
lbz r10, 1(r4) /* load next byte from s2 */
|
|
|
|
cmpdi cr7, r9, 0 /* compare *s1 with NULL */
|
|
|
|
beq cr7, L(diffOfNULL) /* if *s1 is NULL , return *s1 - *s2 */
|
|
|
|
cmplw cr7, r9, r10 /* compare *s1 and *s2 */
|
|
|
|
bne cr7, L(ComputeDiff) /* branch to compute difference and return */
|
|
|
|
|
|
|
|
lbz r9, 2(r3) /* unroll 3rd byte here */
|
|
|
|
lbz r10, 2(r4)
|
|
|
|
cmpdi cr7, r9, 0
|
|
|
|
beq cr7, L(diffOfNULL)
|
|
|
|
cmplw cr7, r9, r10
|
|
|
|
bne 7, L(ComputeDiff)
|
|
|
|
|
|
|
|
lbz r9, 3(r3) /* unroll 4th byte now */
|
|
|
|
lbz r10, 3(r4)
|
|
|
|
addi r3, r3, 4 /* increment s1 by unroll factor */
|
|
|
|
cmpdi cr7, r9, 0
|
|
|
|
cmplw cr6, 9, r10
|
|
|
|
beq cr7, L(diffOfNULL)
|
|
|
|
addi r4, r4, 4 /* increment s2 by unroll factor */
|
|
|
|
beq cr6, L(process_unaligned_bytes) /* unroll byte processing */
|
|
|
|
|
2015-01-09 16:56:35 +00:00
|
|
|
.align 4
|
2014-06-06 12:56:07 +00:00
|
|
|
L(ComputeDiff):
|
|
|
|
extsw r9, r9
|
|
|
|
subf r10, r10, r9 /* compute s1 - s2 */
|
|
|
|
extsw r3, r10
|
|
|
|
blr /* return */
|
|
|
|
|
2015-01-09 16:56:35 +00:00
|
|
|
.align 4
|
2014-06-06 12:56:07 +00:00
|
|
|
L(diffOfNULL):
|
|
|
|
li r9, 0
|
|
|
|
subf r10, r10, r9 /* compute s1 - s2 */
|
|
|
|
extsw r3, r10 /* sign extend result */
|
|
|
|
blr /* return */
|
|
|
|
|
2017-04-11 17:18:34 +00:00
|
|
|
END (STRCMP)
|
2014-06-06 12:56:07 +00:00
|
|
|
libc_hidden_builtin_def (strcmp)
|