Optimize the generic strchr.
* libc/string/strchr.c (strchr) [!__OPTIMIZE_SIZE__]: Pre-align data so unaligned searches aren't penalized. Special-case searching for 0.
This commit is contained in:
parent
0b99028af4
commit
ae47b14a12
@ -1,8 +1,14 @@
|
|||||||
2008-05-21 Eric Blake <ebb9@byu.net>
|
2008-05-21 Eric Blake <ebb9@byu.net>
|
||||||
|
|
||||||
|
Optimize the generic strchr.
|
||||||
|
* libc/string/strchr.c (strchr) [!__OPTIMIZE_SIZE__]: Pre-align
|
||||||
|
data so unaligned searches aren't penalized. Special-case
|
||||||
|
searching for 0.
|
||||||
|
|
||||||
Optimize strchr for x86.
|
Optimize strchr for x86.
|
||||||
* libc/machine/i386/strchr.S (strchr): Pre-align data so unaligned
|
* libc/machine/i386/strchr.S (strchr) [!__OPTIMIZE_SIZE__]:
|
||||||
searches aren't penalized. Special-case searching for 0.
|
Pre-align data so unaligned searches aren't penalized.
|
||||||
|
Special-case searching for 0.
|
||||||
|
|
||||||
2008-05-20 Nick Clifton <nickc@redhat.com>
|
2008-05-20 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
|
@ -63,30 +63,45 @@ _DEFUN (strchr, (s1, i),
|
|||||||
int i)
|
int i)
|
||||||
{
|
{
|
||||||
_CONST unsigned char *s = (_CONST unsigned char *)s1;
|
_CONST unsigned char *s = (_CONST unsigned char *)s1;
|
||||||
#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
|
unsigned char c = i;
|
||||||
unsigned char c = (unsigned int)i;
|
|
||||||
|
|
||||||
while (*s && *s != c)
|
#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
|
||||||
{
|
|
||||||
s++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*s != c)
|
|
||||||
{
|
|
||||||
s = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (char *) s;
|
|
||||||
#else
|
|
||||||
unsigned char c = (unsigned char)i;
|
|
||||||
unsigned long mask,j;
|
unsigned long mask,j;
|
||||||
unsigned long *aligned_addr;
|
unsigned long *aligned_addr;
|
||||||
|
|
||||||
if (!UNALIGNED (s))
|
/* Special case for finding 0. */
|
||||||
|
if (!c)
|
||||||
{
|
{
|
||||||
mask = 0;
|
while (UNALIGNED (s))
|
||||||
for (j = 0; j < LBLOCKSIZE; j++)
|
{
|
||||||
mask = (mask << 8) | c;
|
if (!*s)
|
||||||
|
return (char *) s;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
/* Operate a word at a time. */
|
||||||
|
aligned_addr = (unsigned long *) s;
|
||||||
|
while (!DETECTNULL (*aligned_addr))
|
||||||
|
aligned_addr++;
|
||||||
|
/* Found the end of string. */
|
||||||
|
s = (const unsigned char *) aligned_addr;
|
||||||
|
while (*s)
|
||||||
|
s++;
|
||||||
|
return (char *) s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* All other bytes. Align the pointer, then search a long at a time. */
|
||||||
|
while (UNALIGNED (s))
|
||||||
|
{
|
||||||
|
if (!*s)
|
||||||
|
return NULL;
|
||||||
|
if (*s == c)
|
||||||
|
return (char *) s;
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
|
||||||
|
mask = c;
|
||||||
|
for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
|
||||||
|
mask = (mask << j) | mask;
|
||||||
|
|
||||||
aligned_addr = (unsigned long *) s;
|
aligned_addr = (unsigned long *) s;
|
||||||
while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
|
while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
|
||||||
@ -97,12 +112,12 @@ _DEFUN (strchr, (s1, i),
|
|||||||
catch it using the bytewise search. */
|
catch it using the bytewise search. */
|
||||||
|
|
||||||
s = (unsigned char *) aligned_addr;
|
s = (unsigned char *) aligned_addr;
|
||||||
}
|
|
||||||
|
#endif /* not PREFER_SIZE_OVER_SPEED */
|
||||||
|
|
||||||
while (*s && *s != c)
|
while (*s && *s != c)
|
||||||
s++;
|
s++;
|
||||||
if (*s == c)
|
if (*s == c)
|
||||||
return (char *)s;
|
return (char *)s;
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif /* not PREFER_SIZE_OVER_SPEED */
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user