diff options
author | Jeff Johnston <jjohnstn@redhat.com> | 2008-05-26 22:56:14 +0000 |
---|---|---|
committer | Jeff Johnston <jjohnstn@redhat.com> | 2008-05-26 22:56:14 +0000 |
commit | cae28869c106eb342dd5a1c8242f933efab6f772 (patch) | |
tree | 96a8d157506d0652152d90ae40cfd8137795fe6c /newlib/libc/string | |
parent | 12cf19762d07e477c5c58419cb522e393bee2e0c (diff) | |
download | cygnal-cae28869c106eb342dd5a1c8242f933efab6f772.tar.gz cygnal-cae28869c106eb342dd5a1c8242f933efab6f772.tar.bz2 cygnal-cae28869c106eb342dd5a1c8242f933efab6f772.zip |
2008-05-26 Eric Blake <ebb9@byu.net>
Optimize the generic and x86 strlen.
* libc/string/strlen.c (strlen) [!__OPTIMIZE_SIZE__]: Pre-align
data so unaligned searches aren't penalized.
* libc/machine/i386/strlen.S (strlen) [!__OPTIMIZE_SIZE__]:
Word operations are faster than repnz byte searches.
Diffstat (limited to 'newlib/libc/string')
-rw-r--r-- | newlib/libc/string/strlen.c | 42 |
1 files changed, 21 insertions, 21 deletions
diff --git a/newlib/libc/string/strlen.c b/newlib/libc/string/strlen.c index 4249e14c7..a796d2738 100644 --- a/newlib/libc/string/strlen.c +++ b/newlib/libc/string/strlen.c @@ -1,7 +1,7 @@ -/* +/* FUNCTION <<strlen>>---character string length - + INDEX strlen @@ -57,32 +57,32 @@ size_t _DEFUN (strlen, (str), _CONST char *str) { -#if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__) _CONST char *start = str; - while (*str) - str++; - - return str - start; -#else - _CONST char *start = str; +#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) unsigned long *aligned_addr; - if (!UNALIGNED (str)) + /* Align the pointer, so we can search a word at a time. */ + while (UNALIGNED (str)) { - /* If the string is word-aligned, we can check for the presence of - a null in each word-sized block. */ - aligned_addr = (unsigned long*)str; - while (!DETECTNULL (*aligned_addr)) - aligned_addr++; - - /* Once a null is detected, we check each byte in that block for a - precise position of the null. */ - str = (char*)aligned_addr; + if (!*str) + return str - start; + str++; } - + + /* If the string is word-aligned, we can check for the presence of + a null in each word-sized block. */ + aligned_addr = (unsigned long *)str; + while (!DETECTNULL (*aligned_addr)) + aligned_addr++; + + /* Once a null is detected, we check each byte in that block for a + precise position of the null. */ + str = (char *) aligned_addr; + +#endif /* not PREFER_SIZE_OVER_SPEED */ + while (*str) str++; return str - start; -#endif /* not PREFER_SIZE_OVER_SPEED */ } |