public inbox for newlib@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 1/1] newlib: libc: Optimize the string functions
@ 2022-08-12 20:52 doremylover456
  0 siblings, 0 replies; only message in thread
From: doremylover456 @ 2022-08-12 20:52 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.

Most of the changes were simple refactorings, with some code changed to better match that of other files in the same directory.

Pointers to unsigned variables in memory sometimes cause some older compilers to generate better code than if they were signed, hence those changes as well.
---
 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             | 32 +++++++--------
 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, 254 insertions(+), 269 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..4f186777d 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,24 +72,24 @@ 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;
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..17334c37a 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-12 20:52 [PATCH 1/1] newlib: libc: 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).