public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] String: Optimize the string functions
@ 2022-08-11 17:00 doremylover456
  0 siblings, 0 replies; only message in thread
From: doremylover456 @ 2022-08-11 17:00 UTC (permalink / raw)
  To: newlib; +Cc: Seija Kijin

From: Seija Kijin <doremylover456@gmail.com>

The code is well written, however, there is some room for improvement in terms of performance. This is an attempt to make the string functions more consistent and performant.
---
 newlib/libc/machine/microblaze/strcmp.c |  2 +-
 newlib/libc/machine/microblaze/strcpy.c |  2 +-
 newlib/libc/string/memccpy.c            | 49 ++++++++++++-----------
 newlib/libc/string/memchr.c             |  9 +++--
 newlib/libc/string/memcmp.c             | 34 ++++++++--------
 newlib/libc/string/memcpy.c             | 34 +++++++---------
 newlib/libc/string/memmem.c             | 18 ++++-----
 newlib/libc/string/memmove.c            | 34 ++++++++--------
 newlib/libc/string/mempcpy.c            | 30 +++++++-------
 newlib/libc/string/memrchr.c            | 17 ++++----
 newlib/libc/string/memset.c             | 19 +++++----
 newlib/libc/string/rawmemchr.c          | 19 ++++-----
 newlib/libc/string/stpcpy.c             | 12 +++---
 newlib/libc/string/stpncpy.c            | 13 ++++---
 newlib/libc/string/strcasestr.c         | 30 +++++++-------
 newlib/libc/string/strcat.c             |  6 +--
 newlib/libc/string/strchr.c             | 20 +++++-----
 newlib/libc/string/strcmp.c             | 18 ++++-----
 newlib/libc/string/strcpy.c             | 16 ++++----
 newlib/libc/string/strcspn.c            |  9 ++---
 newlib/libc/string/strlen.c             |  8 ++--
 newlib/libc/string/strncmp.c            | 28 ++++++-------
 newlib/libc/string/strncpy.c            | 10 ++---
 newlib/libc/string/strnlen.c            |  2 +-
 newlib/libc/string/strnstr.c            |  2 +-
 newlib/libc/string/strrchr.c            |  7 ++--
 newlib/libc/string/strspn.c             |  5 +--
 newlib/libc/string/strstr.c             | 52 ++++++++++++-------------
 newlib/libc/string/strxfrm.c            | 12 +++---
 newlib/libc/string/swab.c               |  8 ++--
 30 files changed, 255 insertions(+), 270 deletions(-)

diff --git a/newlib/libc/machine/microblaze/strcmp.c b/newlib/libc/machine/microblaze/strcmp.c
index 434195e2c..050437149 100644
--- a/newlib/libc/machine/microblaze/strcmp.c
+++ b/newlib/libc/machine/microblaze/strcmp.c
@@ -63,7 +63,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
 #if LONG_MAX == 2147483647L
diff --git a/newlib/libc/machine/microblaze/strcpy.c b/newlib/libc/machine/microblaze/strcpy.c
index 62072fa28..b4e45e6a2 100644
--- a/newlib/libc/machine/microblaze/strcpy.c
+++ b/newlib/libc/machine/microblaze/strcpy.c
@@ -63,7 +63,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 #if LONG_MAX == 2147483647L
 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
diff --git a/newlib/libc/string/memccpy.c b/newlib/libc/string/memccpy.c
index 1f5f55c50..6e352f57e 100644
--- a/newlib/libc/string/memccpy.c
+++ b/newlib/libc/string/memccpy.c
@@ -34,16 +34,17 @@ PORTABILITY
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* How many bytes are copied each iteration of the word copy loop.  */
-#define LITTLEBLOCKSIZE (sizeof (long))
+#define LITTLEBLOCKSIZE (sizeof (unsigned long))
 
 /* Threshhold for punting to the byte copier.  */
 #define TOO_SMALL(LEN)  ((LEN) < LITTLEBLOCKSIZE)
 
 /* Macros for detecting endchar */
 #if LONG_MAX == 2147483647L
+#define MAGIC
 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
 #else
 #if LONG_MAX == 9223372036854775807L
@@ -64,11 +65,11 @@ memccpy (void *__restrict dst0,
 
 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
   void *ptr = NULL;
-  char *dst = (char *) dst0;
-  char *src = (char *) src0;
-  char endchar = endchar0 & 0xff;
+  unsigned char *dst = (unsigned char *) dst0;
+  const unsigned char *src = (const unsigned char *) src0;
+  const unsigned char endchar = (unsigned char) endchar0;
 
-  while (len0--)
+  for (; len0; len0--)
     {
       if ((*dst++ = *src++) == endchar)
         {
@@ -80,21 +81,21 @@ memccpy (void *__restrict dst0,
   return ptr;
 #else
   void *ptr = NULL;
-  char *dst = dst0;
-  const char *src = src0;
-  long *aligned_dst;
-  const long *aligned_src;
-  char endchar = endchar0 & 0xff;
+  unsigned char *dst = (unsigned char *) dst0;
+  const unsigned char *src = (const unsigned char *) src0;
+  unsigned long *aligned_dst;
+  const unsigned long *aligned_src;
+  const unsigned char endchar = (unsigned char) endchar0;
 
   /* If the size is small, or either SRC or DST is unaligned,
      then punt into the byte copy loop.  This should be rare.  */
   if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
     {
       unsigned int i;
-      unsigned long mask = 0;
+      unsigned long mask;
 
-      aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_dst = (unsigned long*)dst;
+      aligned_src = (const unsigned long*)src;
 
       /* The fast code reads the ASCII one word at a time and only
          performs the bytewise search on word-sized segments if they
@@ -102,27 +103,29 @@ memccpy (void *__restrict dst0,
          the word-sized segment with a word-sized block of the search
          character and then detecting for the presence of NULL in the
          result.  */
-      for (i = 0; i < LITTLEBLOCKSIZE; i++)
-        mask = (mask << 8) + endchar;
+
+      mask = endchar << 8 | endchar;
+      mask = mask << 16 | mask;
+      for (i = 32; i < LITTLEBLOCKSIZE * 8; i <<= 1)
+        mask = (mask << i) | mask;
 
 
       /* Copy one long word at a time if possible.  */
-      while (len0 >= LITTLEBLOCKSIZE)
+      do
         {
-          unsigned long buffer = (unsigned long)(*aligned_src);
-          buffer ^=  mask;
+          unsigned long buffer = *aligned_src ^ mask;
           if (DETECTNULL (buffer))
             break; /* endchar is found, go byte by byte from here */
           *aligned_dst++ = *aligned_src++;
           len0 -= LITTLEBLOCKSIZE;
-        }
+        } while (len0 >= LITTLEBLOCKSIZE);
 
        /* Pick up any residual with a byte copier.  */
-      dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      dst = (unsigned char*)aligned_dst;
+      src = (const unsigned char*)aligned_src;
     }
 
-  while (len0--)
+  for (; len0; len0--)
     {
       if ((*dst++ = *src++) == endchar)
         {
diff --git a/newlib/libc/string/memchr.c b/newlib/libc/string/memchr.c
index 21bc4d879..614af2bfc 100644
--- a/newlib/libc/string/memchr.c
+++ b/newlib/libc/string/memchr.c
@@ -37,7 +37,7 @@ QUICKREF
 #define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
 
 /* How many bytes are loaded each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
+#define LBLOCKSIZE (sizeof (unsigned long))
 
 /* Threshhold for punting to the bytewise iterator.  */
 #define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
@@ -67,7 +67,7 @@ memchr (const void *src_void,
 	size_t length)
 {
   const unsigned char *src = (const unsigned char *) src_void;
-  unsigned char d = c;
+  const unsigned char d = (unsigned char) c;
 
 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
   unsigned long *asrc;
@@ -76,11 +76,12 @@ memchr (const void *src_void,
 
   while (UNALIGNED (src))
     {
-      if (!length--)
+      if (!length)
         return NULL;
       if (*src == d)
         return (void *) src;
       src++;
+      length--;
     }
 
   if (!TOO_SMALL (length))
@@ -93,7 +94,7 @@ memchr (const void *src_void,
          the word-sized segment with a word-sized block of the search
          character and then detecting for the presence of NUL in the
          result.  */
-      asrc = (unsigned long *) src;
+      asrc = (const unsigned long *) src;
       mask = d << 8 | d;
       mask = mask << 16 | mask;
       for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
diff --git a/newlib/libc/string/memcmp.c b/newlib/libc/string/memcmp.c
index 342fb9fbc..044a0fba0 100644
--- a/newlib/libc/string/memcmp.c
+++ b/newlib/libc/string/memcmp.c
@@ -34,10 +34,10 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* How many bytes are copied each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
+#define LBLOCKSIZE (sizeof (unsigned long))
 
 /* Threshhold for punting to the byte copier.  */
 #define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
@@ -48,22 +48,20 @@ memcmp (const void *m1,
 	size_t n)
 {
 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
-  unsigned char *s1 = (unsigned char *) m1;
-  unsigned char *s2 = (unsigned char *) m2;
+  const unsigned char *s1 = (const unsigned char *) m1;
+  const unsigned char *s2 = (const unsigned char *) m2;
 
-  while (n--)
+  for (; n; n--)
     {
       if (*s1 != *s2)
-	{
 	  return *s1 - *s2;
-	}
       s1++;
       s2++;
     }
   return 0;
 #else  
-  unsigned char *s1 = (unsigned char *) m1;
-  unsigned char *s2 = (unsigned char *) m2;
+  const unsigned char *s1 = (const unsigned char *) m1;
+  const unsigned char *s2 = (const unsigned char *) m2;
   unsigned long *a1;
   unsigned long *a2;
 
@@ -74,27 +72,27 @@ memcmp (const void *m1,
     {
       /* Otherwise, load and compare the blocks of memory one 
          word at a time.  */
-      a1 = (unsigned long*) s1;
-      a2 = (unsigned long*) s2;
-      while (n >= LBLOCKSIZE)
+      a1 = (const unsigned long*) s1;
+      a2 = (const unsigned long*) s2;
+      while (*a1 == *a2)
         {
-          if (*a1 != *a2) 
-   	    break;
           a1++;
           a2++;
           n -= LBLOCKSIZE;
+          if (TOO_SMALL(n))
+            break;
         }
 
       /* check m mod LBLOCKSIZE remaining characters */
 
-      s1 = (unsigned char*)a1;
-      s2 = (unsigned char*)a2;
+      s1 = (const unsigned char*)a1;
+      s2 = (const unsigned char*)a2;
     }
 
-  while (n--)
+  for (; n; n--)
     {
       if (*s1 != *s2)
-	return *s1 - *s2;
+	  return *s1 - *s2;
       s1++;
       s2++;
     }
diff --git a/newlib/libc/string/memcpy.c b/newlib/libc/string/memcpy.c
index 52f716b92..96cacd99e 100644
--- a/newlib/libc/string/memcpy.c
+++ b/newlib/libc/string/memcpy.c
@@ -33,7 +33,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* How many bytes are copied each iteration of the 4X unrolled loop.  */
 #define BIGBLOCKSIZE    (sizeof (long) << 2)
@@ -51,29 +51,25 @@ memcpy (void *__restrict dst0,
 	size_t len0)
 {
 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
-  char *dst = (char *) dst0;
-  char *src = (char *) src0;
+  unsigned char *dst = (unsigned char *) dst0;
+  const unsigned char *src = (const unsigned char *) src0;
 
-  void *save = dst0;
-
-  while (len0--)
-    {
+  for (; len0; len0--)
       *dst++ = *src++;
-    }
 
-  return save;
+  return dst0;
 #else
-  char *dst = dst0;
-  const char *src = src0;
-  long *aligned_dst;
-  const long *aligned_src;
+  unsigned char *dst = dst0;
+  const unsigned char *src = src0;
+  unsigned long *aligned_dst;
+  const unsigned long *aligned_src;
 
   /* If the size is small, or either SRC or DST is unaligned,
      then punt into the byte copy loop.  This should be rare.  */
   if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
     {
-      aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_dst = (unsigned long*)dst;
+      aligned_src = (const unsigned long*)src;
 
       /* Copy 4X long words at a time if possible.  */
       while (len0 >= BIGBLOCKSIZE)
@@ -93,12 +89,12 @@ memcpy (void *__restrict dst0,
         }
 
        /* Pick up any residual with a byte copier.  */
-      dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      dst = (unsigned char*)aligned_dst;
+      src = (const unsigned char*)aligned_src;
     }
 
-  while (len0--)
-    *dst++ = *src++;
+  for (; len0; len0--)
+      *dst++ = *src++;
 
   return dst0;
 #endif /* not PREFER_SIZE_OVER_SPEED */
diff --git a/newlib/libc/string/memmem.c b/newlib/libc/string/memmem.c
index 65267b9c5..c074a295c 100644
--- a/newlib/libc/string/memmem.c
+++ b/newlib/libc/string/memmem.c
@@ -68,14 +68,14 @@ QUICKREF
 void *
 memmem (const void *haystack, size_t hs_len, const void *needle, size_t ne_len)
 {
-  const char *hs = haystack;
-  const char *ne = needle;
+  const unsigned char *hs = haystack;
+  const unsigned char *ne = needle;
 
   if (ne_len == 0)
     return (void *)hs;
-  int i;
-  int c = ne[0];
-  const char *end = hs + hs_len - ne_len;
+  size_t i;
+  const unsigned char c = ne[0];
+  const unsigned char *end = hs + hs_len - ne_len;
 
   for ( ; hs <= end; hs++)
   {
@@ -143,7 +143,7 @@ memmem (const void *haystack, size_t hs_len, const void *needle, size_t ne_len)
   size_t tmp, shift1;
   size_t m1 = ne_len - 1;
   size_t offset = 0;
-  int i;
+  size_t i;
 
   /* Initialize bad character shift hash table.  */
   memset (shift, 0, sizeof (shift));
@@ -152,7 +152,7 @@ memmem (const void *haystack, size_t hs_len, const void *needle, size_t ne_len)
   shift1 = m1 - shift[hash2 (ne + m1)];
   shift[hash2 (ne + m1)] = m1;
 
-  for ( ; hs <= end; )
+  while (hs <= end)
     {
       /* Skip past character pairs not in the needle.  */
       do
@@ -170,13 +170,13 @@ memmem (const void *haystack, size_t hs_len, const void *needle, size_t ne_len)
 
       /* The last 2 characters match.  If the needle is long, check a
 	 fixed number of characters first to quickly filter out mismatches.  */
-      if (m1 <= 15 || memcmp (hs + offset, ne + offset, sizeof (long)) == 0)
+      if (m1 <= 15 || memcmp (hs + offset, ne + offset, sizeof (unsigned long)) == 0)
 	{
 	  if (memcmp (hs, ne, m1) == 0)
 	    return (void *) hs;
 
 	  /* Adjust filter offset when it doesn't find the mismatch.  */
-	  offset = (offset >= sizeof (long) ? offset : m1) - sizeof (long);
+	  offset = (offset >= sizeof (unsigned long) ? offset : m1) - sizeof (unsigned long);
 	}
 
       /* Skip based on matching the last 2 characters.  */
diff --git a/newlib/libc/string/memmove.c b/newlib/libc/string/memmove.c
index da5dfdbdd..24a93488d 100644
--- a/newlib/libc/string/memmove.c
+++ b/newlib/libc/string/memmove.c
@@ -36,7 +36,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* How many bytes are copied each iteration of the 4X unrolled loop.  */
 #define BIGBLOCKSIZE    (sizeof (long) << 2)
@@ -55,22 +55,22 @@ memmove (void *dst_void,
 	size_t length)
 {
 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
-  char *dst = dst_void;
-  const char *src = src_void;
+  unsigned char *dst = dst_void;
+  const unsigned char *src = src_void;
 
-  if (src < dst && dst < src + length)
+  if (dst - src >= length)	/* Unsigned compare means underflow is accounted for */
     {
       /* Have to copy backwards */
       src += length;
       dst += length;
-      while (length--)
+      for (; length; length--)
 	{
 	  *--dst = *--src;
 	}
     }
   else
     {
-      while (length--)
+      for (; length; length--)
 	{
 	  *dst++ = *src++;
 	}
@@ -78,17 +78,17 @@ memmove (void *dst_void,
 
   return dst_void;
 #else
-  char *dst = dst_void;
-  const char *src = src_void;
-  long *aligned_dst;
-  const long *aligned_src;
+  unsigned char *dst = dst_void;
+  const unsigned char *src = src_void;
+  unsigned long *aligned_dst;
+  const unsigned long *aligned_src;
 
-  if (src < dst && dst < src + length)
+  if (dst - src >= length)	/* Unsigned compare means underflow is accounted for */
     {
       /* Destructive overlap...have to copy backwards */
       src += length;
       dst += length;
-      while (length--)
+      for (; length; --length)
 	{
 	  *--dst = *--src;
 	}
@@ -100,8 +100,8 @@ memmove (void *dst_void,
          then punt into the byte copy loop.  This should be rare.  */
       if (!TOO_SMALL(length) && !UNALIGNED (src, dst))
         {
-          aligned_dst = (long*)dst;
-          aligned_src = (long*)src;
+          aligned_dst = (unsigned long*)dst;
+          aligned_src = (const unsigned long*)src;
 
           /* Copy 4X long words at a time if possible.  */
           while (length >= BIGBLOCKSIZE)
@@ -121,11 +121,11 @@ memmove (void *dst_void,
             }
 
           /* Pick up any residual with a byte copier.  */
-          dst = (char*)aligned_dst;
-          src = (char*)aligned_src;
+          dst = (unsigned char*)aligned_dst;
+          src = (const unsigned char*)aligned_src;
         }
 
-      while (length--)
+      for (; length; length--)
         {
           *dst++ = *src++;
         }
diff --git a/newlib/libc/string/mempcpy.c b/newlib/libc/string/mempcpy.c
index 129165603..b13af2dc5 100644
--- a/newlib/libc/string/mempcpy.c
+++ b/newlib/libc/string/mempcpy.c
@@ -31,7 +31,7 @@ PORTABILITY
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* How many bytes are copied each iteration of the 4X unrolled loop.  */
 #define BIGBLOCKSIZE    (sizeof (long) << 2)
@@ -48,27 +48,25 @@ mempcpy (void *dst0,
 	size_t len0)
 {
 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
-  char *dst = (char *) dst0;
-  char *src = (char *) src0;
+  unsigned char *dst = (unsigned char *) dst0;
+  const unsigned char *src = (const unsigned char *) src0;
 
-  while (len0--)
-    {
+  for (; len0; len0--)
       *dst++ = *src++;
-    }
 
   return dst;
 #else
-  char *dst = dst0;
-  const char *src = src0;
-  long *aligned_dst;
-  const long *aligned_src;
+  unsigned char *dst = dst0;
+  const unsigned char *src = src0;
+  unsigned long *aligned_dst;
+  const unsigned long *aligned_src;
 
   /* If the size is small, or either SRC or DST is unaligned,
      then punt into the byte copy loop.  This should be rare.  */
   if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
     {
-      aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_dst = (unsigned long*)dst;
+      aligned_src = (const unsigned long*)src;
 
       /* Copy 4X long words at a time if possible.  */
       while (len0 >= BIGBLOCKSIZE)
@@ -88,12 +86,12 @@ mempcpy (void *dst0,
         }
 
        /* Pick up any residual with a byte copier.  */
-      dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      dst = (unsigned char*)aligned_dst;
+      src = (const unsigned char*)aligned_src;
     }
 
-  while (len0--)
-    *dst++ = *src++;
+  for (; len0; len0--)
+      *dst++ = *src++;
 
   return dst;
 #endif /* not PREFER_SIZE_OVER_SPEED */
diff --git a/newlib/libc/string/memrchr.c b/newlib/libc/string/memrchr.c
index 652efb359..b5aa1e0d2 100644
--- a/newlib/libc/string/memrchr.c
+++ b/newlib/libc/string/memrchr.c
@@ -37,7 +37,7 @@ QUICKREF
 #define UNALIGNED(X) ((long)(X + 1) & (sizeof (long) - 1))
 
 /* How many bytes are loaded each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
+#define LBLOCKSIZE (sizeof (unsigned long))
 
 /* Threshhold for punting to the bytewise iterator.  */
 #define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
@@ -67,7 +67,7 @@ memrchr (const void *src_void,
 	size_t length)
 {
   const unsigned char *src = (const unsigned char *) src_void + length - 1;
-  unsigned char d = c;
+  const unsigned char d = (unsigned char) c;
 
 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
   unsigned long *asrc;
@@ -76,10 +76,11 @@ memrchr (const void *src_void,
 
   while (UNALIGNED (src))
     {
-      if (!length--)
+      if (!length)
         return NULL;
       if (*src == d)
         return (void *) src;
+      length--;
       src--;
     }
 
@@ -93,15 +94,15 @@ memrchr (const void *src_void,
          the word-sized segment with a word-sized block of the search
          character and then detecting for the presence of NUL in the
          result.  */
-      asrc = (unsigned long *) (src - LBLOCKSIZE + 1);
+      asrc = (const unsigned long *) (src - LBLOCKSIZE + 1);
       mask = d << 8 | d;
       mask = mask << 16 | mask;
       for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
         mask = (mask << i) | mask;
 
-      while (length >= LBLOCKSIZE)
+      while (!DETECTCHAR (*asrc, mask))
         {
-          if (DETECTCHAR (*asrc, mask))
+          if (TOO_SMALL (length))
             break;
           length -= LBLOCKSIZE;
           asrc--;
@@ -110,12 +111,12 @@ memrchr (const void *src_void,
       /* If there are fewer than LBLOCKSIZE characters left,
          then we resort to the bytewise loop.  */
 
-      src = (unsigned char *) asrc + LBLOCKSIZE - 1;
+      src = (const unsigned char *) asrc + LBLOCKSIZE - 1;
     }
 
 #endif /* not PREFER_SIZE_OVER_SPEED */
 
-  while (length--)
+  for (; length; length--)
     {
       if (*src == d)
         return (void *) src;
diff --git a/newlib/libc/string/memset.c b/newlib/libc/string/memset.c
index e8e667a24..0c8f8012a 100644
--- a/newlib/libc/string/memset.c
+++ b/newlib/libc/string/memset.c
@@ -39,21 +39,20 @@ memset (void *m,
 	int c,
 	size_t n)
 {
-  char *s = (char *) m;
+  unsigned char *s = (unsigned char *) m;
+  const unsigned char d = (unsigned char) c;
 
 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
   unsigned int i;
   unsigned long buffer;
   unsigned long *aligned_addr;
-  unsigned int d = c & 0xff;	/* To avoid sign extension, copy C to an
-				   unsigned variable.  */
 
   while (UNALIGNED (s))
     {
-      if (n--)
-        *s++ = (char) c;
-      else
+      if (!n)
         return m;
+      *s++ = d;
+      n--;
     }
 
   if (!TOO_SMALL (n))
@@ -64,7 +63,7 @@ memset (void *m,
       /* Store D into each char sized location in BUFFER so that
          we can set large blocks quickly.  */
       buffer = (d << 8) | d;
-      buffer |= (buffer << 16);
+      buffer = (buffer << 16) | buffer;
       for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
         buffer = (buffer << i) | buffer;
 
@@ -84,13 +83,13 @@ memset (void *m,
           n -= LBLOCKSIZE;
         }
       /* Pick up the remainder with a bytewise loop.  */
-      s = (char*)aligned_addr;
+      s = (unsigned char*)aligned_addr;
     }
 
 #endif /* not PREFER_SIZE_OVER_SPEED */
 
-  while (n--)
-    *s++ = (char) c;
+  for (; n; n--)
+    *s++ = d;
 
   return m;
 }
diff --git a/newlib/libc/string/rawmemchr.c b/newlib/libc/string/rawmemchr.c
index 56e2b5e2d..3ab95bb28 100644
--- a/newlib/libc/string/rawmemchr.c
+++ b/newlib/libc/string/rawmemchr.c
@@ -36,7 +36,7 @@ QUICKREF
 #define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
 
 /* How many bytes are loaded each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
+#define LBLOCKSIZE (sizeof (unsigned long))
 
 /* Threshhold for punting to the bytewise iterator.  */
 #define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
@@ -65,10 +65,10 @@ rawmemchr (const void *src_void,
 	int c)
 {
   const unsigned char *src = (const unsigned char *) src_void;
-  unsigned char d = c;
+  const unsigned char d = (unsigned char) c;
 
 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
-  unsigned long *asrc;
+  const unsigned long *asrc;
   unsigned long  mask;
   unsigned int i;
 
@@ -86,29 +86,26 @@ rawmemchr (const void *src_void,
      the word-sized segment with a word-sized block of the search
      character and then detecting for the presence of NUL in the
      result.  */
-  asrc = (unsigned long *) src;
+  asrc = (const unsigned long *) src;
   mask = d << 8 | d;
   mask = mask << 16 | mask;
   for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
     mask = (mask << i) | mask;
 
-  while (1)
+  while (!DETECTCHAR (*asrc, mask))
     {
-      if (DETECTCHAR (*asrc, mask))
-        break;
       asrc++;
     }
 
   /* We have the matching word, now we resort to a bytewise loop. */
 
-  src = (unsigned char *) asrc;
+  src = (const unsigned char *) asrc;
 
 #endif /* !PREFER_SIZE_OVER_SPEED && !__OPTIMIZE_SIZE__ */
 
-  while (1)
+  while (*src != d)
     {
-      if (*src == d)
-        return (void *) src;
       src++;
     }
+  return (void *) src;
 }
diff --git a/newlib/libc/string/stpcpy.c b/newlib/libc/string/stpcpy.c
index 4e2ae9fe0..bbd96ab98 100644
--- a/newlib/libc/string/stpcpy.c
+++ b/newlib/libc/string/stpcpy.c
@@ -35,7 +35,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 #if LONG_MAX == 2147483647L
 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
@@ -64,7 +64,7 @@ stpcpy (char *__restrict dst,
   if (!UNALIGNED (src, dst))
     {
       aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_src = (const long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
          sized copies.  */
@@ -74,11 +74,11 @@ stpcpy (char *__restrict dst,
         }
 
       dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      src = (const char*)aligned_src;
     }
 #endif /* not PREFER_SIZE_OVER_SPEED */
 
-  while ((*dst++ = *src++))
-    ;
-  return --dst;
+  while ((*dst = *src))
+    dst++, src++;
+  return dst;
 }
diff --git a/newlib/libc/string/stpncpy.c b/newlib/libc/string/stpncpy.c
index 87fe268cf..6ca186e95 100644
--- a/newlib/libc/string/stpncpy.c
+++ b/newlib/libc/string/stpncpy.c
@@ -41,7 +41,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 #if LONG_MAX == 2147483647L
 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
@@ -75,7 +75,7 @@ stpncpy (char *__restrict dst,
   if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
     {
       aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_src = (const long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
 	 sized copies.  */
@@ -86,21 +86,22 @@ stpncpy (char *__restrict dst,
 	}
 
       dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      src = (const char*)aligned_src;
     }
 #endif /* not PREFER_SIZE_OVER_SPEED */
 
   while (count > 0)
     {
       --count;
-      if ((*dst++ = *src++) == '\0')
+      if ((*dst = *src) == '\0')
 	{
-	  ret = dst - 1;
+	  ret = dst;
 	  break;
 	}
+	  dst++, src++;
     }
 
-  while (count-- > 0)
+  for (; count > 0; count--)
     *dst++ = '\0';
 
   return ret ? ret : dst;
diff --git a/newlib/libc/string/strcasestr.c b/newlib/libc/string/strcasestr.c
index 36e183986..db6b07cb9 100644
--- a/newlib/libc/string/strcasestr.c
+++ b/newlib/libc/string/strcasestr.c
@@ -99,15 +99,13 @@ strcasestr (const char *s,
 	char c, sc;
 	size_t len;
 
-	if ((c = *find++) != 0) {
-		c = tolower((unsigned char)c);
+	if ((c = *find++) != '\0') {
+		c = tolower(c & 0xff);
 		len = strlen(find);
 		do {
-			do {
-				if ((sc = *s++) == 0)
-					return (NULL);
-			} while ((char)tolower((unsigned char)sc) != c);
-		} while (strncasecmp(s, find, len) != 0);
+			if ((sc = *s++) == '\0')
+				return (NULL);
+		} while (((char)tolower(sc & 0xff) != c) && strncasecmp(s, find, len) != 0);
 		s--;
 	}
 	return ((char *)s);
@@ -115,8 +113,8 @@ strcasestr (const char *s,
 #else /* compilation for speed */
 
   /* Larger code size, but guaranteed linear performance.  */
-  const char *haystack = s;
-  const char *needle = find;
+  const unsigned char *haystack = (const unsigned char *)s;
+  const unsigned char *needle = (const unsigned char *)find;
   size_t needle_len; /* Length of NEEDLE.  */
   size_t haystack_len; /* Known minimum length of HAYSTACK.  */
   int ok = 1; /* True if NEEDLE is prefix of HAYSTACK.  */
@@ -125,22 +123,20 @@ strcasestr (const char *s,
      HAYSTACK is at least as long (no point processing all of a long
      NEEDLE if HAYSTACK is too short).  */
   while (*haystack && *needle)
-    ok &= (tolower ((unsigned char) *haystack++)
-	   == tolower ((unsigned char) *needle++));
+    ok &= (tolower (*haystack++)
+	   == tolower (*needle++));
   if (*needle)
     return NULL;
   if (ok)
     return (char *) s;
   needle_len = needle - find;
-  haystack = s + 1;
+  needle = (const unsigned char *)find;
+  haystack = (const unsigned char *)s + 1;
   haystack_len = needle_len - 1;
 
   /* Perform the search.  */
   if (needle_len < LONG_NEEDLE_THRESHOLD)
-    return two_way_short_needle ((const unsigned char *) haystack,
-				 haystack_len,
-				 (const unsigned char *) find, needle_len);
-  return two_way_long_needle ((const unsigned char *) haystack, haystack_len,
-			      (const unsigned char *) find, needle_len);
+    return two_way_short_needle (haystack, haystack_len, needle, needle_len);
+  return two_way_long_needle (haystack, haystack_len, needle, needle_len);
 #endif /* compilation for speed */
 }
diff --git a/newlib/libc/string/strcat.c b/newlib/libc/string/strcat.c
index 92313c492..ce5183c9b 100644
--- a/newlib/libc/string/strcat.c
+++ b/newlib/libc/string/strcat.c
@@ -63,8 +63,8 @@ strcat (char *__restrict s1,
   while (*s1)
     s1++;
 
-  while (*s1++ = *s2++)
-    ;
+  while (*s1 = *s2)
+    s1++, s2++;
   return s;
 #else
   char *s = s1;
@@ -73,7 +73,7 @@ strcat (char *__restrict s1,
   /* Skip over the data in s1 as quickly as possible.  */
   if (ALIGNED (s1))
     {
-      unsigned long *aligned_s1 = (unsigned long *)s1;
+      long *aligned_s1 = (long *)s1;
       while (!DETECTNULL (*aligned_s1))
 	aligned_s1++;
 
diff --git a/newlib/libc/string/strchr.c b/newlib/libc/string/strchr.c
index 96f30be04..3bf44c43c 100644
--- a/newlib/libc/string/strchr.c
+++ b/newlib/libc/string/strchr.c
@@ -55,12 +55,12 @@ char *
 strchr (const char *s1,
 	int i)
 {
-  const unsigned char *s = (const unsigned char *)s1;
-  unsigned char c = i;
+  const char *s = (const char *)s1;
+  const char c = (char)i;
 
 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
   unsigned long mask,j;
-  unsigned long *aligned_addr;
+  const long *aligned_addr;
 
   /* Special case for finding 0.  */
   if (!c)
@@ -72,11 +72,11 @@ strchr (const char *s1,
           s++;
         }
       /* Operate a word at a time.  */
-      aligned_addr = (unsigned long *) s;
+      aligned_addr = (const long *) s;
       while (!DETECTNULL (*aligned_addr))
         aligned_addr++;
       /* Found the end of string.  */
-      s = (const unsigned char *) aligned_addr;
+      s = (const char *) aligned_addr;
       while (*s)
         s++;
       return (char *) s;
@@ -92,11 +92,13 @@ strchr (const char *s1,
       s++;
     }
 
-  mask = c;
-  for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
+  mask = c & 0xff;
+  mask = mask << 8 | mask;
+  mask = mask << 16 | mask;
+  for (j = 32; j < LBLOCKSIZE * 8; j <<= 1)
     mask = (mask << j) | mask;
 
-  aligned_addr = (unsigned long *) s;
+  aligned_addr = (const long *) s;
   while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
     aligned_addr++;
 
@@ -104,7 +106,7 @@ strchr (const char *s1,
      contains either a null or the target char, or both.  We
      catch it using the bytewise search.  */
 
-  s = (unsigned char *) aligned_addr;
+  s = (const char *) aligned_addr;
 
 #endif /* not PREFER_SIZE_OVER_SPEED */
 
diff --git a/newlib/libc/string/strcmp.c b/newlib/libc/string/strcmp.c
index 894424a69..0a534cfdf 100644
--- a/newlib/libc/string/strcmp.c
+++ b/newlib/libc/string/strcmp.c
@@ -34,7 +34,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 /* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
 #if LONG_MAX == 2147483647L
@@ -62,17 +62,17 @@ strcmp (const char *s1,
       s2++;
     }
 
-  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+  return (*(const unsigned char *) s1) - (*(const unsigned char *) s2);
 #else
-  unsigned long *a1;
-  unsigned long *a2;
+  const long *a1;
+  const long *a2;
 
   /* If s1 or s2 are unaligned, then compare bytes. */
   if (!UNALIGNED (s1, s2))
     {  
       /* If s1 and s2 are word-aligned, compare them a word at a time. */
-      a1 = (unsigned long*)s1;
-      a2 = (unsigned long*)s2;
+      a1 = (const long*)s1;
+      a2 = (const long*)s2;
       while (*a1 == *a2)
         {
           /* To get here, *a1 == *a2, thus if we find a null in *a1,
@@ -85,8 +85,8 @@ strcmp (const char *s1,
         }
 
       /* A difference was detected in last few bytes of s1, so search bytewise */
-      s1 = (char*)a1;
-      s2 = (char*)a2;
+      s1 = (const char*)a1;
+      s2 = (const char*)a2;
     }
 
   while (*s1 != '\0' && *s1 == *s2)
@@ -94,6 +94,6 @@ strcmp (const char *s1,
       s1++;
       s2++;
     }
-  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+  return (*(const unsigned char *) s1) - (*(const unsigned char *) s2);
 #endif /* not PREFER_SIZE_OVER_SPEED */
 }
diff --git a/newlib/libc/string/strcpy.c b/newlib/libc/string/strcpy.c
index 94e16b512..9d3792ed3 100644
--- a/newlib/libc/string/strcpy.c
+++ b/newlib/libc/string/strcpy.c
@@ -34,7 +34,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 #if LONG_MAX == 2147483647L
 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
@@ -56,10 +56,10 @@ strcpy (char *dst0,
 	const char *src0)
 {
 #if defined(PREFER_SIZE_OVER_SPEED) || defined(__OPTIMIZE_SIZE__)
-  char *s = dst0;
+  char * const s = dst0;
 
-  while (*dst0++ = *src0++)
-    ;
+  while (*dst0 = *src0)
+    dst0++, src0++;
 
   return s;
 #else
@@ -72,7 +72,7 @@ strcpy (char *dst0,
   if (!UNALIGNED (src, dst))
     {
       aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_src = (const long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
          sized copies.  */
@@ -82,11 +82,11 @@ strcpy (char *dst0,
         }
 
       dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      src = (const char*)aligned_src;
     }
 
-  while ((*dst++ = *src++))
-    ;
+  while (*dst = *src)
+    dst++, src++;
   return dst0;
 #endif /* not PREFER_SIZE_OVER_SPEED */
 }
diff --git a/newlib/libc/string/strcspn.c b/newlib/libc/string/strcspn.c
index abaa93ad6..89ba3eb4d 100644
--- a/newlib/libc/string/strcspn.c
+++ b/newlib/libc/string/strcspn.c
@@ -29,20 +29,19 @@ size_t
 strcspn (const char *s1,
 	const char *s2)
 {
-  const char *s = s1;
+  const char *s;
   const char *c;
 
-  while (*s1)
+  for (s = s1; *s; s++)
     {
       for (c = s2; *c; c++)
 	{
-	  if (*s1 == *c)
+	  if (*s == *c)
 	    break;
 	}
       if (*c)
 	break;
-      s1++;
     }
 
-  return s1 - s;
+  return s - s1;
 }
diff --git a/newlib/libc/string/strlen.c b/newlib/libc/string/strlen.c
index acffa49e1..1b7c7969d 100644
--- a/newlib/libc/string/strlen.c
+++ b/newlib/libc/string/strlen.c
@@ -54,7 +54,7 @@ strlen (const char *str)
   const char *start = str;
 
 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
-  unsigned long *aligned_addr;
+  const long *aligned_addr;
 
   /* Align the pointer, so we can search a word at a time.  */
   while (UNALIGNED (str))
@@ -66,17 +66,17 @@ strlen (const char *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;
+  aligned_addr = (const 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;
+  str = (const char *) aligned_addr;
 
 #endif /* not PREFER_SIZE_OVER_SPEED */
 
-  while (*str)
+  while (*str != '\0')
     str++;
   return str - start;
 }
diff --git a/newlib/libc/string/strncmp.c b/newlib/libc/string/strncmp.c
index 16f8a7729..77291aebb 100644
--- a/newlib/libc/string/strncmp.c
+++ b/newlib/libc/string/strncmp.c
@@ -34,7 +34,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((long)X | (long)Y) & (sizeof (long) - 1))
 
 /* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
 #if LONG_MAX == 2147483647L
@@ -60,18 +60,18 @@ strncmp (const char *s1,
   if (n == 0)
     return 0;
 
-  while (n-- != 0 && *s1 == *s2)
+  while (*s1 == *s2)
     {
-      if (n == 0 || *s1 == '\0')
+      if (--n == 0 || *s1 == '\0')
 	break;
       s1++;
       s2++;
     }
 
-  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+  return (*(const unsigned char *) s1) - (*(const unsigned char *) s2);
 #else
-  unsigned long *a1;
-  unsigned long *a2;
+  const long *a1;
+  const long *a2;
 
   if (n == 0)
     return 0;
@@ -80,8 +80,8 @@ strncmp (const char *s1,
   if (!UNALIGNED (s1, s2))
     {
       /* If s1 and s2 are word-aligned, compare them a word at a time. */
-      a1 = (unsigned long*)s1;
-      a2 = (unsigned long*)s2;
+      a1 = (const long*)s1;
+      a2 = (const long*)s2;
       while (n >= sizeof (long) && *a1 == *a2)
         {
           n -= sizeof (long);
@@ -96,19 +96,19 @@ strncmp (const char *s1,
         }
 
       /* A difference was detected in last few bytes of s1, so search bytewise */
-      s1 = (char*)a1;
-      s2 = (char*)a2;
+      s1 = (const char*)a1;
+      s2 = (const char*)a2;
     }
 
-  while (n-- > 0 && *s1 == *s2)
+  while (*s1 == *s2)
     {
       /* If we've run out of bytes or hit a null, return zero
 	 since we already know *s1 == *s2.  */
-      if (n == 0 || *s1 == '\0')
-	return 0;
+      if (--n == 0 || *s1 == '\0')
+	  return 0;
       s1++;
       s2++;
     }
-  return (*(unsigned char *) s1) - (*(unsigned char *) s2);
+  return (*(const unsigned char *) s1) - (*(const unsigned char *) s2);
 #endif /* not PREFER_SIZE_OVER_SPEED */
 }
diff --git a/newlib/libc/string/strncpy.c b/newlib/libc/string/strncpy.c
index e7eb34d72..55921b6a1 100644
--- a/newlib/libc/string/strncpy.c
+++ b/newlib/libc/string/strncpy.c
@@ -39,7 +39,7 @@ QUICKREF
 
 /* Nonzero if either X or Y is not aligned on a "long" boundary.  */
 #define UNALIGNED(X, Y) \
-  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+  (((unsigned long)X | (unsigned long)Y) & (sizeof (unsigned long) - 1))
 
 #if LONG_MAX == 2147483647L
 #define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
@@ -75,7 +75,7 @@ strncpy (char *__restrict dst0,
       if ((*dscan++ = *sscan++) == '\0')
 	break;
     }
-  while (count-- > 0)
+  for (; count; count--)
     *dscan++ = '\0';
 
   return dst0;
@@ -89,7 +89,7 @@ strncpy (char *__restrict dst0,
   if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
     {
       aligned_dst = (long*)dst;
-      aligned_src = (long*)src;
+      aligned_src = (const long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
 	 sized copies.  */
@@ -100,7 +100,7 @@ strncpy (char *__restrict dst0,
 	}
 
       dst = (char*)aligned_dst;
-      src = (char*)aligned_src;
+      src = (const char*)aligned_src;
     }
 
   while (count > 0)
@@ -110,7 +110,7 @@ strncpy (char *__restrict dst0,
 	break;
     }
 
-  while (count-- > 0)
+  for (; count; count--)
     *dst++ = '\0';
 
   return dst0;
diff --git a/newlib/libc/string/strnlen.c b/newlib/libc/string/strnlen.c
index 3ee18d1c0..adc09f160 100644
--- a/newlib/libc/string/strnlen.c
+++ b/newlib/libc/string/strnlen.c
@@ -35,7 +35,7 @@ strnlen (const char *str,
 {
   const char *start = str;
 
-  while (n-- > 0 && *str)
+  for (; n && *str; n--)
     str++;
 
   return str - start;
diff --git a/newlib/libc/string/strnstr.c b/newlib/libc/string/strnstr.c
index cb5f71914..b2e529a4e 100644
--- a/newlib/libc/string/strnstr.c
+++ b/newlib/libc/string/strnstr.c
@@ -40,7 +40,7 @@ QUICKREF
 char *
 strnstr(const char *haystack, const char *needle, size_t haystack_len)
 {
-  size_t needle_len = strnlen(needle, haystack_len);
+  const size_t needle_len = strnlen(needle, haystack_len);
 
   if (needle_len < haystack_len || !needle[needle_len]) {
     char *x = memmem(haystack, haystack_len, needle, needle_len);
diff --git a/newlib/libc/string/strrchr.c b/newlib/libc/string/strrchr.c
index 35a7060d2..a7e5da8b9 100644
--- a/newlib/libc/string/strrchr.c
+++ b/newlib/libc/string/strrchr.c
@@ -34,11 +34,10 @@ strrchr (const char *s,
 	int i)
 {
   const char *last = NULL;
-  char c = i;
 
-  if (c)
+  if (i & 0xff)
     {
-      while ((s=strchr(s, c)))
+      while ((s=strchr(s, i)))
 	{
 	  last = s;
 	  s++;
@@ -46,7 +45,7 @@ strrchr (const char *s,
     }
   else
     {
-      last = strchr(s, c);
+      last = strchr(s, i);
     }
 
   return (char *) last;
diff --git a/newlib/libc/string/strspn.c b/newlib/libc/string/strspn.c
index baf239947..553977186 100644
--- a/newlib/libc/string/strspn.c
+++ b/newlib/libc/string/strspn.c
@@ -36,7 +36,7 @@ strspn (const char *s1,
   const char *s = s1;
   const char *c;
 
-  while (*s1)
+  for (s = s1; *s; s++)
     {
       for (c = s2; *c; c++)
 	{
@@ -45,8 +45,7 @@ strspn (const char *s1,
 	}
       if (*c == '\0')
 	break;
-      s1++;
     }
 
-  return s1 - s;
+  return s - s1;
 }
diff --git a/newlib/libc/string/strstr.c b/newlib/libc/string/strstr.c
index 84e4632f1..9afbc1fa1 100644
--- a/newlib/libc/string/strstr.c
+++ b/newlib/libc/string/strstr.c
@@ -67,7 +67,7 @@ char *
 strstr (const char *hs, const char *ne)
 {
   size_t i;
-  int c = ne[0];
+  char c = ne[0];
 
   if (c == 0)
     return (char*)hs;
@@ -143,24 +143,22 @@ strstr4 (const unsigned char *hs, const unsigned char *ne)
 char *
 strstr (const char *haystack, const char *needle)
 {
-  const unsigned char *hs = (const unsigned char *) haystack;
-  const unsigned char *ne = (const unsigned char *) needle;
-  int i;
+  size_t i;
 
   /* Handle short needle special cases first.  */
-  if (ne[0] == '\0')
-    return (char *) hs;
-  if (ne[1] == '\0')
-    return (char*)strchr ((const char *) hs, ne[0]);
-  if (ne[2] == '\0')
-    return strstr2 (hs, ne);
-  if (ne[3] == '\0')
-    return strstr3 (hs, ne);
-  if (ne[4] == '\0')
-    return strstr4 (hs, ne);
-
-  size_t ne_len = strlen ((const char *) ne);
-  size_t hs_len = strnlen ((const char *) hs, ne_len | 512);
+  if (needle[0] == '\0')
+    return haystack;
+  if (needle[1] == '\0')
+    return (char*)strchr (haystack, needle[0]);
+  if (needle[2] == '\0')
+    return strstr2 (haystack, needle);
+  if (needle[3] == '\0')
+    return strstr3 (haystack, needle);
+  if (needle[4] == '\0')
+    return strstr4 (haystack, needle);
+
+  size_t ne_len = strlen (haystack);
+  size_t hs_len = strnlen (needle, ne_len | 512);
 
   /* Ensure haystack length is >= needle length.  */
   if (hs_len < ne_len)
@@ -170,35 +168,35 @@ strstr (const char *haystack, const char *needle)
   if (__builtin_expect (ne_len < 255, 1))
     {
       uint8_t shift[1 << SHIFT_TABLE_BITS];
-      const unsigned char *end = hs + hs_len - ne_len;
+      const char *end = haystack + hs_len - ne_len;
 
       /* Initialize bad character shift hash table.  */
       memset (shift, ne_len + 1, sizeof (shift));
       for (i = 0; i < ne_len; i++)
-	shift[ne[i] % sizeof (shift)] = ne_len - i;
+	shift[needle[i] % sizeof (shift)] = ne_len - i;
 
       do
 	{
-	  hs--;
+	  haystack--;
 
 	  /* Search by skipping past bad characters.  */
-	  size_t tmp = shift[hs[ne_len] % sizeof (shift)];
-	  for (hs += tmp; hs <= end; hs += tmp)
+	  size_t tmp = shift[haystack[ne_len] % sizeof (shift)];
+	  for (haystack += tmp; haystack <= end; haystack += tmp)
 	    {
-	      tmp = shift[hs[ne_len] % sizeof (shift)];
-	      if (memcmp (hs, ne, ne_len) == 0)
-		return (char*) hs;
+	      tmp = shift[haystack[ne_len] % sizeof (shift)];
+	      if (memcmp (haystack, needle, ne_len) == 0)
+		return (char*) haystack;
 	    }
 	  if (end[ne_len] == 0)
 	    return NULL;
 	  end += strnlen ((const char *) (end + ne_len), 2048);
 	}
-      while (hs <= end);
+      while (haystack <= end);
 
       return NULL;
     }
 
   /* Use Two-Way algorithm for very long needles.  */
-  return two_way_long_needle (hs, hs_len, ne, ne_len);
+  return two_way_long_needle (haystack, hs_len, needle, ne_len);
 }
 #endif /* compilation for speed */
diff --git a/newlib/libc/string/strxfrm.c b/newlib/libc/string/strxfrm.c
index c5df0bcd5..537981586 100644
--- a/newlib/libc/string/strxfrm.c
+++ b/newlib/libc/string/strxfrm.c
@@ -50,14 +50,12 @@ strxfrm (char *__restrict s1,
 	const char *__restrict s2,
 	size_t n)
 {
-  size_t res;
-  res = 0;
-  while (n-- > 0)
+  size_t res = 0;
+  for (; n; n--)
     {
-      if ((*s1++ = *s2++) != '\0')
-        ++res;
-      else
-        return res;
+      if ((*s1++ = *s2++) == '\0')
+	  	return res;
+      ++res;
     }
   while (*s2)
     {
diff --git a/newlib/libc/string/swab.c b/newlib/libc/string/swab.c
index 28ab978bd..01910dc53 100644
--- a/newlib/libc/string/swab.c
+++ b/newlib/libc/string/swab.c
@@ -22,13 +22,13 @@ swab (const void *b1,
 	void *b2,
 	ssize_t length)
 {
-  const char *from = b1;
-  char *to = b2;
+  const unsigned char *from = b1;
+  unsigned char *to = b2;
   ssize_t ptr;
   for (ptr = 1; ptr < length; ptr += 2)
     {
-      char p = from[ptr];
-      char q = from[ptr-1];
+      unsigned char p = from[ptr];
+      unsigned char q = from[ptr-1];
       to[ptr-1] = p;
       to[ptr  ] = q;
     }
-- 
2.37.1


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2022-12-13 19:48 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-11 17:00 [PATCH] String: Optimize the string functions doremylover456

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).