2013-03-07 17:07:51 +00:00
|
|
|
/* strchr -- find the first instance of C in a nul-terminated string.
|
2023-01-06 21:08:04 +00:00
|
|
|
Copyright (C) 2013-2023 Free Software Foundation, Inc.
|
2013-03-07 17:07:51 +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/>. */
|
2013-03-07 17:07:51 +00:00
|
|
|
|
|
|
|
#include <sysdep.h>
|
|
|
|
|
|
|
|
.syntax unified
|
|
|
|
.text
|
|
|
|
|
|
|
|
ENTRY (strchr)
|
|
|
|
@ r0 = start of string
|
|
|
|
@ r1 = character to match
|
|
|
|
@ returns NULL for no match, or a pointer to the match
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
ldrb r2, [r0] @ load the first byte asap
|
2013-03-07 17:07:51 +00:00
|
|
|
uxtb r1, r1
|
|
|
|
|
|
|
|
@ To cater to long strings, we want to search through a few
|
|
|
|
@ characters until we reach an aligned pointer. To cater to
|
|
|
|
@ small strings, we don't want to start doing word operations
|
|
|
|
@ immediately. The compromise is a maximum of 16 bytes less
|
|
|
|
@ whatever is required to end with an aligned pointer.
|
|
|
|
@ r3 = number of characters to search in alignment loop
|
|
|
|
and r3, r0, #7
|
|
|
|
rsb r3, r3, #15 @ 16 - 1 peeled loop iteration
|
|
|
|
cmp r2, r1 @ Found C?
|
|
|
|
it ne
|
|
|
|
cmpne r2, #0 @ Found EOS?
|
|
|
|
beq 99f
|
|
|
|
|
|
|
|
@ Loop until we find ...
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
1: ldrb r2, [r0, #1]!
|
2013-03-07 17:07:51 +00:00
|
|
|
subs r3, r3, #1 @ ... the aligment point
|
|
|
|
it ne
|
|
|
|
cmpne r2, r1 @ ... or the character
|
|
|
|
it ne
|
|
|
|
cmpne r2, #0 @ ... or EOS
|
|
|
|
bne 1b
|
|
|
|
|
|
|
|
@ Disambiguate the exit possibilites above
|
|
|
|
cmp r2, r1 @ Found the character
|
|
|
|
it ne
|
|
|
|
cmpne r2, #0 @ Found EOS
|
|
|
|
beq 99f
|
|
|
|
add r0, r0, #1
|
|
|
|
|
|
|
|
@ So now we're aligned. Now we actually need a stack frame.
|
|
|
|
push { r4, r5, r6, r7 }
|
|
|
|
cfi_adjust_cfa_offset (16)
|
|
|
|
cfi_rel_offset (r4, 0)
|
|
|
|
cfi_rel_offset (r5, 4)
|
|
|
|
cfi_rel_offset (r6, 8)
|
|
|
|
cfi_rel_offset (r7, 12)
|
|
|
|
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
ldrd r2, r3, [r0], #8
|
2013-03-07 17:07:51 +00:00
|
|
|
orr r1, r1, r1, lsl #8 @ Replicate C to all bytes
|
|
|
|
#ifdef ARCH_HAS_T2
|
|
|
|
movw ip, #0x0101
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
pld [r0, #64]
|
2013-03-07 17:07:51 +00:00
|
|
|
movt ip, #0x0101
|
|
|
|
#else
|
|
|
|
ldr ip, =0x01010101
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
pld [r0, #64]
|
2013-03-07 17:07:51 +00:00
|
|
|
#endif
|
|
|
|
orr r1, r1, r1, lsl #16
|
|
|
|
|
|
|
|
@ Loop searching for EOS or C, 8 bytes at a time.
|
|
|
|
2:
|
|
|
|
@ Subtracting (unsigned saturating) from 1 means result of 1 for
|
|
|
|
@ any byte that was originally zero and 0 otherwise. Therefore
|
|
|
|
@ we consider the lsb of each byte the "found" bit.
|
|
|
|
uqsub8 r4, ip, r2 @ Find EOS
|
|
|
|
eor r6, r2, r1 @ Convert C bytes to 0
|
|
|
|
uqsub8 r5, ip, r3
|
|
|
|
eor r7, r3, r1
|
|
|
|
uqsub8 r6, ip, r6 @ Find C
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
pld [r0, #128] @ Prefetch 2 lines ahead
|
2013-03-07 17:07:51 +00:00
|
|
|
uqsub8 r7, ip, r7
|
|
|
|
orr r4, r4, r6 @ Combine found for EOS and C
|
|
|
|
orr r5, r5, r7
|
|
|
|
orrs r6, r4, r5 @ Combine the two words
|
|
|
|
it eq
|
Remove sfi_* annotations from ARM assembly files.
This semi-mechanical patch removes all uses and definitions of the
sfi_breg, sfi_pld, and sfi_sp macros from various ARM-specific
assembly files. These were only used by NaCl.
* sysdeps/arm/sysdep.h
(ARM_SFI_MACROS, sfi_breg, sfi_pld, sfi_sp): Delete definitions.
* sysdeps/arm/__longjmp.S, sysdeps/arm/add_n.S
* sysdeps/arm/addmul_1.S, sysdeps/arm/arm-mcount.S
* sysdeps/arm/armv6/rawmemchr.S, sysdeps/arm/armv6/strchr.S
* sysdeps/arm/armv6/strcpy.S, sysdeps/arm/armv6/strlen.S
* sysdeps/arm/armv6/strrchr.S, sysdeps/arm/armv6t2/memchr.S
* sysdeps/arm/armv6t2/strlen.S
* sysdeps/arm/armv7/multiarch/memcpy_impl.S
* sysdeps/arm/armv7/strcmp.S, sysdeps/arm/dl-tlsdesc.S
* sysdeps/arm/memcpy.S, sysdeps/arm/memmove.S
* sysdeps/arm/memset.S, sysdeps/arm/setjmp.S
* sysdeps/arm/strlen.S, sysdeps/arm/submul_1.S:
Remove all uses of sfi_breg, sfi_pld, and sfi_sp.
2017-05-12 00:36:15 +00:00
|
|
|
ldrdeq r2, r3, [r0], #8
|
2013-03-07 17:07:51 +00:00
|
|
|
beq 2b
|
|
|
|
|
|
|
|
@ Found something. Disambiguate between first and second words.
|
|
|
|
@ Adjust r0 to point to the word containing the match.
|
|
|
|
@ Adjust r2 to the contents of the word containing the match.
|
|
|
|
@ Adjust r4 to the found bits for the word containing the match.
|
|
|
|
cmp r4, #0
|
|
|
|
sub r0, r0, #4
|
|
|
|
itte eq
|
|
|
|
moveq r4, r5
|
|
|
|
moveq r2, r3
|
|
|
|
subne r0, r0, #4
|
|
|
|
|
|
|
|
@ Find the bit-offset of the match within the word.
|
|
|
|
#if defined(__ARMEL__)
|
|
|
|
@ For LE, swap the found word so clz searches from the little end.
|
|
|
|
rev r4, r4
|
|
|
|
#else
|
|
|
|
@ For BE, byte swap the word to make it easier to extract the byte.
|
|
|
|
rev r2, r2
|
|
|
|
#endif
|
|
|
|
@ We're counting 0x01 (not 0x80), so the bit offset is 7 too high.
|
|
|
|
clz r3, r4
|
|
|
|
sub r3, r3, #7
|
|
|
|
lsr r2, r2, r3 @ Shift down found byte
|
|
|
|
uxtb r1, r1 @ Undo replication of C
|
|
|
|
uxtb r2, r2 @ Extract found byte
|
|
|
|
add r0, r0, r3, lsr #3 @ Adjust the pointer to the found byte
|
|
|
|
|
|
|
|
pop { r4, r5, r6, r7 }
|
|
|
|
cfi_adjust_cfa_offset (-16)
|
|
|
|
cfi_restore (r4)
|
|
|
|
cfi_restore (r5)
|
|
|
|
cfi_restore (r6)
|
|
|
|
cfi_restore (r7)
|
|
|
|
|
|
|
|
@ Disambiguate between EOS and C.
|
|
|
|
99:
|
|
|
|
cmp r2, r1
|
|
|
|
it ne
|
|
|
|
movne r0, #0 @ Found EOS, return NULL
|
|
|
|
bx lr
|
|
|
|
|
|
|
|
END (strchr)
|
|
|
|
|
|
|
|
weak_alias (strchr, index)
|
|
|
|
libc_hidden_builtin_def (strchr)
|