summaryrefslogtreecommitdiffstats
path: root/newlib/libc/string
diff options
context:
space:
mode:
authorJeff Johnston <jjohnstn@redhat.com>2008-05-26 22:56:14 +0000
committerJeff Johnston <jjohnstn@redhat.com>2008-05-26 22:56:14 +0000
commitcae28869c106eb342dd5a1c8242f933efab6f772 (patch)
tree96a8d157506d0652152d90ae40cfd8137795fe6c /newlib/libc/string
parent12cf19762d07e477c5c58419cb522e393bee2e0c (diff)
downloadcygnal-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.c42
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 */
}