2002-09-17 23:50:03 +00:00
|
|
|
/* Optimized strlen implementation for PowerPC64.
|
2020-01-01 00:14:33 +00:00
|
|
|
Copyright (C) 1997-2020 Free Software Foundation, Inc.
|
2002-09-17 23:50:03 +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
|
2012-02-09 23:18:22 +00:00
|
|
|
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/>. */
|
2002-09-17 23:50:03 +00:00
|
|
|
|
|
|
|
#include <sysdep.h>
|
|
|
|
|
|
|
|
/* The algorithm here uses the following techniques:
|
|
|
|
|
|
|
|
1) Given a word 'x', we can test to see if it contains any 0 bytes
|
|
|
|
by subtracting 0x01010101, and seeing if any of the high bits of each
|
|
|
|
byte changed from 0 to 1. This works because the least significant
|
|
|
|
0 byte must have had no incoming carry (otherwise it's not the least
|
|
|
|
significant), so it is 0x00 - 0x01 == 0xff. For all other
|
|
|
|
byte values, either they have the high bit set initially, or when
|
|
|
|
1 is subtracted you get a value in the range 0x00-0x7f, none of which
|
|
|
|
have their high bit set. The expression here is
|
|
|
|
(x + 0xfefefeff) & ~(x | 0x7f7f7f7f), which gives 0x00000000 when
|
2013-08-17 09:10:11 +00:00
|
|
|
there were no 0x00 bytes in the word. You get 0x80 in bytes that
|
|
|
|
match, but possibly false 0x80 matches in the next more significant
|
|
|
|
byte to a true match due to carries. For little-endian this is
|
|
|
|
of no consequence since the least significant match is the one
|
|
|
|
we're interested in, but big-endian needs method 2 to find which
|
|
|
|
byte matches.
|
2002-09-17 23:50:03 +00:00
|
|
|
|
|
|
|
2) Given a word 'x', we can test to see _which_ byte was zero by
|
|
|
|
calculating ~(((x & 0x7f7f7f7f) + 0x7f7f7f7f) | x | 0x7f7f7f7f).
|
|
|
|
This produces 0x80 in each byte that was zero, and 0x00 in all
|
|
|
|
the other bytes. The '| 0x7f7f7f7f' clears the low 7 bits in each
|
|
|
|
byte, and the '| x' part ensures that bytes with the high bit set
|
|
|
|
produce 0x00. The addition will carry into the high bit of each byte
|
|
|
|
iff that byte had one of its low 7 bits set. We can then just see
|
|
|
|
which was the most significant bit set and divide by 8 to find how
|
|
|
|
many to add to the index.
|
|
|
|
This is from the book 'The PowerPC Compiler Writer's Guide',
|
|
|
|
by Steve Hoxey, Faraydon Karim, Bill Hay and Hank Warren.
|
|
|
|
|
|
|
|
We deal with strings not aligned to a word boundary by taking the
|
|
|
|
first word and ensuring that bytes not part of the string
|
|
|
|
are treated as nonzero. To allow for memory latency, we unroll the
|
|
|
|
loop a few times, being careful to ensure that we do not read ahead
|
|
|
|
across cache line boundaries.
|
|
|
|
|
|
|
|
Questions to answer:
|
|
|
|
1) How long are strings passed to strlen? If they're often really long,
|
|
|
|
we should probably use cache management instructions and/or unroll the
|
|
|
|
loop more. If they're often quite short, it might be better to use
|
|
|
|
fact (2) in the inner loop than have to recalculate it.
|
|
|
|
2) How popular are bytes with the high bit set? If they are very rare,
|
|
|
|
on some processors it might be useful to use the simpler expression
|
|
|
|
~((x - 0x01010101) | 0x7f7f7f7f) (that is, on processors with only one
|
2013-06-05 20:44:03 +00:00
|
|
|
ALU), but this fails when any character has its high bit set.
|
|
|
|
|
2003-04-04 22:03:25 +00:00
|
|
|
Answer:
|
2013-06-05 20:44:03 +00:00
|
|
|
1) Added a Data Cache Block Touch early to prefetch the first 128
|
|
|
|
byte cache line. Adding dcbt instructions to the loop would not be
|
2013-08-17 09:10:11 +00:00
|
|
|
effective since most strings will be shorter than the cache line. */
|
2002-09-17 23:50:03 +00:00
|
|
|
|
|
|
|
/* Some notes on register usage: Under the SVR4 ABI, we can use registers
|
|
|
|
0 and 3 through 12 (so long as we don't call any procedures) without
|
|
|
|
saving them. We can also use registers 14 through 31 if we save them.
|
|
|
|
We can't use r1 (it's the stack pointer), r2 nor r13 because the user
|
|
|
|
program may expect them to hold their usual value if we get sent
|
|
|
|
a signal. Integer parameters are passed in r3 through r10.
|
|
|
|
We can use condition registers cr0, cr1, cr5, cr6, and cr7 without saving
|
|
|
|
them, the others we must save. */
|
|
|
|
|
|
|
|
/* int [r3] strlen (char *s [r3]) */
|
|
|
|
|
2017-04-11 17:18:35 +00:00
|
|
|
#ifndef STRLEN
|
|
|
|
# define STRLEN strlen
|
|
|
|
#endif
|
|
|
|
|
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 (STRLEN)
|
2004-10-06 22:09:35 +00:00
|
|
|
CALL_MCOUNT 1
|
2002-09-17 23:50:03 +00:00
|
|
|
|
2013-08-17 09:10:11 +00:00
|
|
|
#define rTMP4 r0
|
2002-09-17 23:50:03 +00:00
|
|
|
#define rRTN r3 /* incoming STR arg, outgoing result */
|
|
|
|
#define rSTR r4 /* current string position */
|
|
|
|
#define rPADN r5 /* number of padding bits we prepend to the
|
|
|
|
string to make it start at a word boundary */
|
2003-04-04 22:03:25 +00:00
|
|
|
#define rFEFE r6 /* constant 0xfefefefefefefeff (-0x0101010101010101) */
|
|
|
|
#define r7F7F r7 /* constant 0x7f7f7f7f7f7f7f7f */
|
|
|
|
#define rWORD1 r8 /* current string doubleword */
|
|
|
|
#define rWORD2 r9 /* next string doubleword */
|
|
|
|
#define rMASK r9 /* mask for first string doubleword */
|
2013-08-17 09:10:11 +00:00
|
|
|
#define rTMP1 r10
|
|
|
|
#define rTMP2 r11
|
|
|
|
#define rTMP3 r12
|
2002-09-17 23:50:03 +00:00
|
|
|
|
2003-04-04 22:03:25 +00:00
|
|
|
dcbt 0,rRTN
|
|
|
|
clrrdi rSTR, rRTN, 3
|
2002-09-17 23:50:03 +00:00
|
|
|
lis r7F7F, 0x7f7f
|
2003-04-04 22:03:25 +00:00
|
|
|
rlwinm rPADN, rRTN, 3, 26, 28
|
|
|
|
ld rWORD1, 0(rSTR)
|
2002-09-17 23:50:03 +00:00
|
|
|
addi r7F7F, r7F7F, 0x7f7f
|
2003-04-04 22:03:25 +00:00
|
|
|
li rMASK, -1
|
|
|
|
insrdi r7F7F, r7F7F, 32, 0
|
2013-08-17 09:10:11 +00:00
|
|
|
/* We use method (2) on the first two doublewords, because rFEFE isn't
|
|
|
|
required which reduces setup overhead. Also gives a faster return
|
|
|
|
for small strings on big-endian due to needing to recalculate with
|
|
|
|
method (2) anyway. */
|
|
|
|
#ifdef __LITTLE_ENDIAN__
|
|
|
|
sld rMASK, rMASK, rPADN
|
|
|
|
#else
|
2003-04-04 22:03:25 +00:00
|
|
|
srd rMASK, rMASK, rPADN
|
2013-08-17 09:10:11 +00:00
|
|
|
#endif
|
2002-09-17 23:50:03 +00:00
|
|
|
and rTMP1, r7F7F, rWORD1
|
|
|
|
or rTMP2, r7F7F, rWORD1
|
2003-04-04 22:03:25 +00:00
|
|
|
lis rFEFE, -0x101
|
2002-09-17 23:50:03 +00:00
|
|
|
add rTMP1, rTMP1, r7F7F
|
2003-04-04 22:03:25 +00:00
|
|
|
addi rFEFE, rFEFE, -0x101
|
2013-08-17 09:10:11 +00:00
|
|
|
nor rTMP3, rTMP2, rTMP1
|
|
|
|
and. rTMP3, rTMP3, rMASK
|
2002-09-17 23:50:03 +00:00
|
|
|
mtcrf 0x01, rRTN
|
|
|
|
bne L(done0)
|
2013-08-17 09:10:11 +00:00
|
|
|
sldi rTMP1, rFEFE, 32
|
|
|
|
add rFEFE, rFEFE, rTMP1
|
2002-09-17 23:50:03 +00:00
|
|
|
/* Are we now aligned to a doubleword boundary? */
|
2003-04-04 22:03:25 +00:00
|
|
|
bt 28, L(loop)
|
2002-09-17 23:50:03 +00:00
|
|
|
|
2003-04-04 22:03:25 +00:00
|
|
|
/* Handle second doubleword of pair. */
|
2013-08-17 09:10:11 +00:00
|
|
|
/* Perhaps use method (1) here for little-endian, saving one instruction? */
|
2003-04-04 22:03:25 +00:00
|
|
|
ldu rWORD1, 8(rSTR)
|
2002-09-17 23:50:03 +00:00
|
|
|
and rTMP1, r7F7F, rWORD1
|
|
|
|
or rTMP2, r7F7F, rWORD1
|
|
|
|
add rTMP1, rTMP1, r7F7F
|
2013-08-17 09:10:11 +00:00
|
|
|
nor. rTMP3, rTMP2, rTMP1
|
2002-09-17 23:50:03 +00:00
|
|
|
bne L(done0)
|
|
|
|
|
|
|
|
/* The loop. */
|
|
|
|
|
|
|
|
L(loop):
|
2003-04-04 22:03:25 +00:00
|
|
|
ld rWORD1, 8(rSTR)
|
|
|
|
ldu rWORD2, 16(rSTR)
|
2002-09-17 23:50:03 +00:00
|
|
|
add rTMP1, rFEFE, rWORD1
|
|
|
|
nor rTMP2, r7F7F, rWORD1
|
|
|
|
and. rTMP1, rTMP1, rTMP2
|
|
|
|
add rTMP3, rFEFE, rWORD2
|
|
|
|
nor rTMP4, r7F7F, rWORD2
|
|
|
|
bne L(done1)
|
2013-08-17 09:10:11 +00:00
|
|
|
and. rTMP3, rTMP3, rTMP4
|
2002-09-17 23:50:03 +00:00
|
|
|
beq L(loop)
|
|
|
|
|
2013-08-17 09:10:11 +00:00
|
|
|
#ifndef __LITTLE_ENDIAN__
|
2002-09-17 23:50:03 +00:00
|
|
|
and rTMP1, r7F7F, rWORD2
|
|
|
|
add rTMP1, rTMP1, r7F7F
|
2013-08-17 09:10:11 +00:00
|
|
|
andc rTMP3, rTMP4, rTMP1
|
2002-09-17 23:50:03 +00:00
|
|
|
b L(done0)
|
|
|
|
|
|
|
|
L(done1):
|
|
|
|
and rTMP1, r7F7F, rWORD1
|
2003-04-04 22:03:25 +00:00
|
|
|
subi rSTR, rSTR, 8
|
2002-09-17 23:50:03 +00:00
|
|
|
add rTMP1, rTMP1, r7F7F
|
2013-08-17 09:10:11 +00:00
|
|
|
andc rTMP3, rTMP2, rTMP1
|
2002-09-17 23:50:03 +00:00
|
|
|
|
2003-04-04 22:03:25 +00:00
|
|
|
/* When we get to here, rSTR points to the first doubleword in the string that
|
2013-08-17 09:10:11 +00:00
|
|
|
contains a zero byte, and rTMP3 has 0x80 for bytes that are zero, and 0x00
|
|
|
|
otherwise. */
|
2002-09-17 23:50:03 +00:00
|
|
|
L(done0):
|
2013-08-17 09:10:11 +00:00
|
|
|
cntlzd rTMP3, rTMP3
|
2002-09-17 23:50:03 +00:00
|
|
|
subf rTMP1, rRTN, rSTR
|
2003-04-04 22:03:25 +00:00
|
|
|
srdi rTMP3, rTMP3, 3
|
2002-09-17 23:50:03 +00:00
|
|
|
add rRTN, rTMP1, rTMP3
|
|
|
|
blr
|
2013-08-17 09:10:11 +00:00
|
|
|
#else
|
|
|
|
|
|
|
|
L(done0):
|
|
|
|
addi rTMP1, rTMP3, -1 /* Form a mask from trailing zeros. */
|
|
|
|
andc rTMP1, rTMP1, rTMP3
|
|
|
|
cntlzd rTMP1, rTMP1 /* Count bits not in the mask. */
|
|
|
|
subf rTMP3, rRTN, rSTR
|
|
|
|
subfic rTMP1, rTMP1, 64-7
|
|
|
|
srdi rTMP1, rTMP1, 3
|
|
|
|
add rRTN, rTMP1, rTMP3
|
|
|
|
blr
|
|
|
|
|
|
|
|
L(done1):
|
|
|
|
addi rTMP3, rTMP1, -1
|
|
|
|
andc rTMP3, rTMP3, rTMP1
|
|
|
|
cntlzd rTMP3, rTMP3
|
|
|
|
subf rTMP1, rRTN, rSTR
|
|
|
|
subfic rTMP3, rTMP3, 64-7-64
|
|
|
|
sradi rTMP3, rTMP3, 3
|
|
|
|
add rRTN, rTMP1, rTMP3
|
|
|
|
blr
|
|
|
|
#endif
|
|
|
|
|
2017-04-11 17:18:35 +00:00
|
|
|
END (STRLEN)
|
Update.
* sysdeps/i386/fpu/ftestexcept.c: Also check SSE status word.
* include/signal.h: Use libc_hidden_proto for sigaddset and sigdelset.
* signal/sigaddset.c: Add libc_hidden_def.
* signal/sigdelset.c: Likewise.
2003-04-29 Jakub Jelinek <jakub@redhat.com>
* sysdeps/i386/i486/string-inlines.c (__memcpy_g, __strchr_g): Move
to the end of the file.
* configure.in: Change __oline__ to $LINENO.
(HAVE_BUILTIN_REDIRECTION): New check.
* config.h.in (HAVE_BUILTIN_REDIRECTION): Add.
* include/libc-symbols.h (libc_hidden_builtin_proto,
libc_hidden_builtin_def, libc_hidden_builtin_weak,
libc_hidden_builtin_ver): Define.
* include/string.h (memchr, memcpy, memmove, memset, strcat, strchr,
strcmp, strcpy, strcspn, strlen, strncmp, strncpy, strpbrk, strrchr,
strspn, strstr): Add libc_hidden_builtin_proto.
* intl/plural.y: Include string.h.
* sysdeps/alpha/alphaev6/memchr.S (memchr): Add
libc_hidden_builtin_def.
* sysdeps/alpha/alphaev6/memcpy.S (memcpy): Likewise.
* sysdeps/alpha/alphaev6/memset.S (memset): Likewise.
* sysdeps/alpha/alphaev67/strcat.S (strcat): Likewise.
* sysdeps/alpha/alphaev67/strchr.S (strchr): Likewise.
* sysdeps/alpha/alphaev67/strlen.S (strlen): Likewise.
* sysdeps/alpha/alphaev67/strrchr.S (strrchr): Likewise.
* sysdeps/alpha/memchr.S (memchr): Likewise.
* sysdeps/alpha/memset.S (memset): Likewise.
* sysdeps/alpha/strcat.S (strcat): Likewise.
* sysdeps/alpha/strchr.S (strchr): Likewise.
* sysdeps/alpha/strcmp.S (strcmp): Likewise.
* sysdeps/alpha/strcpy.S (strcpy): Likewise.
* sysdeps/alpha/strlen.S (strlen): Likewise.
* sysdeps/alpha/strncmp.S (strncmp): Likewise.
* sysdeps/alpha/strncpy.S (strncpy): Likewise.
* sysdeps/alpha/strrchr.S (strrchr): Likewise.
* sysdeps/arm/memset.S (memset): Likewise.
* sysdeps/arm/strlen.S (strlen): Likewise.
* sysdeps/generic/memchr.c (memchr): Likewise.
* sysdeps/generic/memcpy.c (memcpy): Likewise.
* sysdeps/generic/memmove.c (memmove): Likewise.
* sysdeps/generic/memset.c (memset): Likewise.
* sysdeps/generic/strcat.c (strcat): Likewise.
* sysdeps/generic/strchr.c (strchr): Likewise.
* sysdeps/generic/strcmp.c (strcmp): Likewise.
* sysdeps/generic/strcpy.c (strcpy): Likewise.
* sysdeps/generic/strcspn.c (strcspn): Likewise.
* sysdeps/generic/strlen.c (strlen): Likewise.
* sysdeps/generic/strncmp.c (strncmp): Likewise.
* sysdeps/generic/strncpy.c (strncpy): Likewise.
* sysdeps/generic/strpbrk.c (strpbrk): Likewise.
* sysdeps/generic/strrchr.c (strrchr): Likewise.
* sysdeps/generic/strspn.c (strspn): Likewise.
* sysdeps/generic/strstr.c (strstr): Likewise.
* sysdeps/i386/i486/strcat.S (strcat): Likewise.
* sysdeps/i386/i486/strlen.S (strlen): Likewise.
* sysdeps/i386/i586/memcpy.S (memcpy): Likewise.
* sysdeps/i386/i586/memset.S (memset): Likewise.
* sysdeps/i386/i586/strchr.S (strchr): Likewise.
* sysdeps/i386/i586/strcpy.S (strcpy): Likewise.
* sysdeps/i386/i586/strlen.S (strlen): Likewise.
* sysdeps/i386/i686/memcpy.S (memcpy): Likewise.
* sysdeps/i386/i686/memmove.S (memmove): Likewise.
* sysdeps/i386/i686/memset.S (memset): Likewise.
* sysdeps/i386/i686/strcmp.S (strcmp): Likewise.
* sysdeps/i386/memchr.S (memchr): Likewise.
* sysdeps/i386/memset.c (memset): Likewise.
* sysdeps/i386/strchr.S (strchr): Likewise.
* sysdeps/i386/strcspn.S (strcspn): Likewise.
* sysdeps/i386/strlen.c (strlen): Likewise.
* sysdeps/i386/strpbrk.S (strpbrk): Likewise.
* sysdeps/i386/strrchr.S (strrchr): Likewise.
* sysdeps/i386/strspn.S (strspn): Likewise.
* sysdeps/ia64/memchr.S (memchr): Likewise.
* sysdeps/ia64/memcpy.S (memcpy): Likewise.
* sysdeps/ia64/memmove.S (memmove): Likewise.
* sysdeps/ia64/memset.S (memset): Likewise.
* sysdeps/ia64/strcat.S (strcat): Likewise.
* sysdeps/ia64/strchr.S (strchr): Likewise.
* sysdeps/ia64/strcmp.S (strcmp): Likewise.
* sysdeps/ia64/strcpy.S (strcpy): Likewise.
* sysdeps/ia64/strlen.S (strlen): Likewise.
* sysdeps/ia64/strncmp.S (strncmp): Likewise.
* sysdeps/ia64/strncpy.S (strncpy): Likewise.
* sysdeps/m68k/memchr.S (memchr): Likewise.
* sysdeps/m68k/strchr.S (strchr): Likewise.
* sysdeps/mips/mips64/memcpy.S (memcpy): Likewise.
* sysdeps/mips/mips64/memset.S (memset): Likewise.
* sysdeps/mips/memcpy.S (memcpy): Likewise.
* sysdeps/mips/memset.S (memset): Likewise.
* sysdeps/powerpc/powerpc32/memset.S (memset): Likewise.
* sysdeps/powerpc/powerpc32/strchr.S (strchr): Likewise.
* sysdeps/powerpc/powerpc32/strcmp.S (strcmp): Likewise.
* sysdeps/powerpc/powerpc32/strcpy.S (strcpy): Likewise.
* sysdeps/powerpc/powerpc32/strlen.S (strlen): Likewise.
* sysdeps/powerpc/powerpc64/memcpy.S (memcpy): Likewise.
* sysdeps/powerpc/powerpc64/memset.S (memset): Likewise.
* sysdeps/powerpc/powerpc64/strchr.S (strchr): Likewise.
* sysdeps/powerpc/powerpc64/strcmp.S (strcmp): Likewise.
* sysdeps/powerpc/powerpc64/strcpy.S (strcpy): Likewise.
* sysdeps/powerpc/powerpc64/strlen.S (strlen): Likewise.
* sysdeps/powerpc/strcat.c (strcat): Likewise.
* sysdeps/sparc/sparc32/memchr.S (memchr): Likewise.
* sysdeps/sparc/sparc32/memcpy.S (memcpy): Likewise.
* sysdeps/sparc/sparc32/memset.S (memset): Likewise.
* sysdeps/sparc/sparc32/strcat.S (strcat): Likewise.
* sysdeps/sparc/sparc32/strchr.S (strchr, strrchr): Likewise.
* sysdeps/sparc/sparc32/strcmp.S (strcmp): Likewise.
* sysdeps/sparc/sparc32/strcpy.S (strcpy): Likewise.
* sysdeps/sparc/sparc32/strlen.S (strlen): Likewise.
* sysdeps/sparc/sparc64/sparcv9b/memcpy.S (memcpy, memmove): Likewise.
* sysdeps/sparc/sparc64/memchr.S (memchr): Likewise.
* sysdeps/sparc/sparc64/memcpy.S (memcpy, memmove): Likewise.
* sysdeps/sparc/sparc64/memset.S (memset): Likewise.
* sysdeps/sparc/sparc64/strcat.S (strcat): Likewise.
* sysdeps/sparc/sparc64/strchr.S (strchr, strrchr): Likewise.
* sysdeps/sparc/sparc64/strcmp.S (strcmp): Likewise.
* sysdeps/sparc/sparc64/strcpy.S (strcpy): Likewise.
* sysdeps/sparc/sparc64/strcspn.S (strcspn): Likewise.
* sysdeps/sparc/sparc64/strlen.S (strlen): Likewise.
* sysdeps/sparc/sparc64/strncmp.S (strncmp): Likewise.
* sysdeps/sparc/sparc64/strncpy.S (strncpy): Likewise.
* sysdeps/sparc/sparc64/strpbrk.S (strpbrk): Likewise.
* sysdeps/sparc/sparc64/strspn.S (strspn): Likewise.
* sysdeps/sh/memcpy.S (memcpy): Likewise.
* sysdeps/sh/memset.S (memset): Likewise.
* sysdeps/sh/strlen.S (strlen): Likewise.
* sysdeps/s390/s390-32/memchr.S (memchr): Likewise.
* sysdeps/s390/s390-32/memcpy.S (memcpy): Likewise.
* sysdeps/s390/s390-32/memset.S (memset): Likewise.
* sysdeps/s390/s390-32/strcmp.S (strcmp): Likewise.
* sysdeps/s390/s390-32/strcpy.S (strcpy): Likewise.
* sysdeps/s390/s390-32/strncpy.S (strncpy): Likewise.
* sysdeps/s390/s390-64/memchr.S (memchr): Likewise.
* sysdeps/s390/s390-64/memcpy.S (memcpy): Likewise.
* sysdeps/s390/s390-64/memset.S (memset): Likewise.
* sysdeps/s390/s390-64/strcmp.S (strcmp): Likewise.
* sysdeps/s390/s390-64/strcpy.S (strcpy): Likewise.
* sysdeps/s390/s390-64/strncpy.S (strncpy): Likewise.
* sysdeps/x86_64/memcpy.S (memcpy): Likewise.
* sysdeps/x86_64/memset.S (memset): Likewise.
* sysdeps/x86_64/strcat.S (strcat): Likewise.
* sysdeps/x86_64/strchr.S (strchr): Likewise.
* sysdeps/x86_64/strcmp.S (strcmp): Likewise.
* sysdeps/x86_64/strcpy.S (strcpy): Likewise.
* sysdeps/x86_64/strcspn.S (strcspn): Likewise.
* sysdeps/x86_64/strlen.S (strlen): Likewise.
* sysdeps/x86_64/strspn.S (strspn): Likewise.
* string/string-inlines.c: Move...
* sysdeps/generic/string-inlines.c: ...here.
(__memcpy_g, __strchr_g): Remove.
(__NO_INLINE__): Define before including <string.h>,
undefine after. Include bits/string.h and bits/string2.h.
* sysdeps/i386/i486/string-inlines.c: New file.
* sysdeps/i386/string-inlines.c: New file.
* sysdeps/i386/i486/Versions: Remove.
All GLIBC_2.1.1 symbols moved...
* sysdeps/i386/Versions (libc): ...here.
2003-04-29 Ulrich Drepper <drepper@redhat.com>
2003-04-29 22:49:58 +00:00
|
|
|
libc_hidden_builtin_def (strlen)
|