[1/6] newlib: string: refactor str/mem-family functions

Message ID 3668279f9eb28a9b644b90aab0b32152bc04a484.camel@espressif.com
State New
Headers
Series Refactor and optimize string/memory functions |

Commit Message

Alexey Lapshin Jan. 27, 2025, 10:43 a.m. UTC
  Move common macros to local.h header
---
 newlib/libc/string/local.h     | 32 +++++++++++++++++++++++
 newlib/libc/string/memccpy.c   | 34 +++++-------------------
 newlib/libc/string/memchr.c    | 43 ++++++-------------------------
 newlib/libc/string/memcmp.c    | 20 ++++-----------
 newlib/libc/string/memcpy.c    | 23 ++++-------------
 newlib/libc/string/memmove.c   | 23 ++++-------------
 newlib/libc/string/mempcpy.c   | 24 +++++------------
 newlib/libc/string/memrchr.c   | 47 ++++++++--------------------------
 newlib/libc/string/memset.c    | 18 +++++--------
 newlib/libc/string/rawmemchr.c | 35 +++----------------------
 newlib/libc/string/stpcpy.c    | 23 ++---------------
 newlib/libc/string/stpncpy.c   | 32 +++++------------------
 newlib/libc/string/strcat.c    | 25 +++---------------
 newlib/libc/string/strchr.c    | 30 ++++------------------
 newlib/libc/string/strcmp.c    | 23 ++---------------
 newlib/libc/string/strcpy.c    | 23 ++---------------
 newlib/libc/string/strlen.c    | 23 +++--------------
 newlib/libc/string/strncat.c   | 24 +++--------------
 newlib/libc/string/strncmp.c   | 24 +++--------------
 newlib/libc/string/strncpy.c   | 26 +++----------------
 20 files changed, 120 insertions(+), 432 deletions(-)

-- 
2.43.0
  

Comments

Corinna Vinschen Feb. 10, 2025, 12:10 p.m. UTC | #1
Hi Alexey,

On Jan 27 10:43, Alexey Lapshin wrote:
> Move common macros to local.h header
> ---
>  newlib/libc/string/local.h     | 32 +++++++++++++++++++++++
>  newlib/libc/string/memccpy.c   | 34 +++++-------------------
>  newlib/libc/string/memchr.c    | 43 ++++++-------------------------
>  newlib/libc/string/memcmp.c    | 20 ++++-----------
>  newlib/libc/string/memcpy.c    | 23 ++++-------------
>  newlib/libc/string/memmove.c   | 23 ++++-------------
>  newlib/libc/string/mempcpy.c   | 24 +++++------------
>  newlib/libc/string/memrchr.c   | 47 ++++++++--------------------------
>  newlib/libc/string/memset.c    | 18 +++++--------
>  newlib/libc/string/rawmemchr.c | 35 +++----------------------
>  newlib/libc/string/stpcpy.c    | 23 ++---------------
>  newlib/libc/string/stpncpy.c   | 32 +++++------------------
>  newlib/libc/string/strcat.c    | 25 +++---------------
>  newlib/libc/string/strchr.c    | 30 ++++------------------
>  newlib/libc/string/strcmp.c    | 23 ++---------------
>  newlib/libc/string/strcpy.c    | 23 ++---------------
>  newlib/libc/string/strlen.c    | 23 +++--------------
>  newlib/libc/string/strncat.c   | 24 +++--------------
>  newlib/libc/string/strncmp.c   | 24 +++--------------
>  newlib/libc/string/strncpy.c   | 26 +++----------------
>  20 files changed, 120 insertions(+), 432 deletions(-)

After applying this patch, I'm getting warnings:

newlib/libc/string/strcmp.c: In function ‘strcmp’:
newlib/libc/string/strcmp.c:52:8: warning: implicit declaration of function ‘UNALIGNED_X_Y’ [-Wimplicit-function-declaration]
   52 |   if (!UNALIGNED_X_Y(s1, s2))
      |        ^~~~~~~~~~~~~
newlib/libc/string/strcmp.c:61:15: warning: implicit declaration of function ‘DETECT_NULL’ [-Wimplicit-function-declaration]
   61 |           if (DETECT_NULL(*a1))
      |               ^~~~~~~~~~~

newlib/libc/string/strchr.c: In function ‘strchr’:
newlib/libc/string/strchr.c:48:14: warning: implicit declaration of function ‘UNALIGNED_X’ [-Wimplicit-function-declaration]
   48 |       while (UNALIGNED_X(s))
      |              ^~~~~~~~~~~
newlib/libc/string/strchr.c:56:15: warning: implicit declaration of function ‘DETECT_NULL’ [-Wimplicit-function-declaration]
   56 |       while (!DETECT_NULL(*aligned_addr))
      |               ^~~~~~~~~~~
newlib/libc/string/strchr.c:80:42: warning: implicit declaration of function ‘DETECT_CHAR’ [-Wimplicit-function-declaration]
   80 |   while (!DETECT_NULL(*aligned_addr) && !DETECT_CHAR(*aligned_addr, mask))
      |                                          ^~~~~~~~~~~

home/corinna/src/cygwin/vanilla/newlib/libc/string/strcpy.c: In function ‘strcpy’:
newlib/libc/string/strcpy.c:53:8: warning: implicit declaration of function ‘UNALIGNED_X_Y’ [-Wimplicit-function-declaration]
   53 |   if (!UNALIGNED_X_Y(src, dst))
      |        ^~~~~~~~~~~~~
newlib/libc/string/strcpy.c:60:15: warning: implicit declaration of function ‘DETECT_NULL’ [-Wimplicit-function-declaration]
   60 |       while (!DETECT_NULL(*aligned_src))
      |               ^~~~~~~~~~~

newlib/libc/string/stpcpy.c: In function ‘stpcpy’:
  CC       libc/reent/libc_a-statr.o
newlib/libc/string/stpcpy.c:45:8: warning: implicit declaration of function ‘UNALIGNED_X_Y’ [-Wimplicit-function-declaration]
   45 |   if (!UNALIGNED_X_Y(src, dst))
      |        ^~~~~~~~~~~~~
newlib/libc/string/stpcpy.c:52:15: warning: implicit declaration of function ‘DETECT_NULL’ [-Wimplicit-function-declaration]
   52 |       while (!DETECT_NULL(*aligned_src))
      |               ^~~~~~~~~~~

Looks like there's an include missing.


Thanks,
Corinna
  

Patch

diff --git a/newlib/libc/string/local.h b/newlib/libc/string/local.h
index 8d364fdaa..fb8e6c65c 100644
--- a/newlib/libc/string/local.h
+++ b/newlib/libc/string/local.h
@@ -17,4 +17,36 @@  int __wcwidth (wint_t);
 # define __inhibit_loop_to_libcall
 #endif
 
+/* Nonzero if X is not aligned on a "long" boundary.  */
+#define UNALIGNED_X(X) ((long)X & (sizeof (long) - 1))
 
+/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
+#define UNALIGNED_X_Y(X, Y) \
+  (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
+
+/* How many bytes are copied each iteration of the word copy loop.  */
+#define LITTLE_BLOCK_SIZE (sizeof (long))
+
+/* How many bytes are copied each iteration of the 4X unrolled loop.  */
+#define BIG_BLOCK_SIZE (sizeof (long) << 2)
+
+/* Threshhold for punting to the little block byte copier.  */
+#define TOO_SMALL_LITTLE_BLOCK(LEN)  ((LEN) < LITTLE_BLOCK_SIZE)
+
+/* Threshhold for punting to the big block byte copier.  */
+#define TOO_SMALL_BIG_BLOCK(LEN)  ((LEN) < BIG_BLOCK_SIZE)
+
+/* Macros for detecting endchar.  */
+#if LONG_MAX == 2147483647L
+#define DETECT_NULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
+#else
+#if LONG_MAX == 9223372036854775807L
+/* Nonzero if X (a long int) contains a NULL byte.  */
+#define DETECT_NULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
+#else
+#error long int is not a 32bit or 64bit type.
+#endif
+#endif
+
+/* Returns nonzero if (long)X contains the byte used to fill (long)MASK.  */
+#define DETECT_CHAR(X, MASK) (DETECT_NULL(X ^ MASK))
diff --git a/newlib/libc/string/memccpy.c b/newlib/libc/string/memccpy.c
index d6b2f8bea..332332489 100644
--- a/newlib/libc/string/memccpy.c
+++ b/newlib/libc/string/memccpy.c
@@ -31,29 +31,7 @@  PORTABILITY
 #include <stddef.h>
 #include <string.h>
 #include <limits.h>
-
-/* 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)))
-
-/* How many bytes are copied each iteration of the word copy loop.  */
-#define LITTLEBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the byte copier.  */
-#define TOO_SMALL(LEN)  ((LEN) < LITTLEBLOCKSIZE)
-
-/* Macros for detecting endchar */
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
+#include "local.h"
 
 void *
 memccpy (void *__restrict dst0,
@@ -88,7 +66,7 @@  memccpy (void *__restrict dst0,
 
   /* 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))
+  if (!TOO_SMALL_LITTLE_BLOCK(len0) && !UNALIGNED_X_Y(src, dst))
     {
       unsigned int i;
       unsigned long mask = 0;
@@ -102,19 +80,19 @@  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++)
+      for (i = 0; i < sizeof(mask); i++)
         mask = (mask << 8) + endchar;
 
 
       /* Copy one long word at a time if possible.  */
-      while (len0 >= LITTLEBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(len0))
         {
           unsigned long buffer = (unsigned long)(*aligned_src);
           buffer ^=  mask;
-          if (DETECTNULL (buffer))
+          if (DETECT_NULL(buffer))
             break; /* endchar is found, go byte by byte from here */
           *aligned_dst++ = *aligned_src++;
-          len0 -= LITTLEBLOCKSIZE;
+          len0 -= LITTLE_BLOCK_SIZE;
         }
 
        /* Pick up any residual with a byte copier.  */
diff --git a/newlib/libc/string/memchr.c b/newlib/libc/string/memchr.c
index 21bc4d879..a702a9142 100644
--- a/newlib/libc/string/memchr.c
+++ b/newlib/libc/string/memchr.c
@@ -32,34 +32,7 @@  QUICKREF
 #include <_ansi.h>
 #include <string.h>
 #include <limits.h>
-
-/* Nonzero if either X or Y is not aligned on a "long" boundary.  */
-#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
-
-/* How many bytes are loaded each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the bytewise iterator.  */
-#define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
-/* DETECTCHAR returns nonzero if (long)X contains the byte used
-   to fill (long)MASK. */
-#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
+#include "local.h"
 
 void *
 memchr (const void *src_void,
@@ -74,7 +47,7 @@  memchr (const void *src_void,
   unsigned long  mask;
   unsigned int i;
 
-  while (UNALIGNED (src))
+  while (UNALIGNED_X(src))
     {
       if (!length--)
         return NULL;
@@ -83,7 +56,7 @@  memchr (const void *src_void,
       src++;
     }
 
-  if (!TOO_SMALL (length))
+  if (!TOO_SMALL_LITTLE_BLOCK(length))
     {
       /* If we get this far, we know that length is large and src is
          word-aligned. */
@@ -96,18 +69,18 @@  memchr (const void *src_void,
       asrc = (unsigned long *) src;
       mask = d << 8 | d;
       mask = mask << 16 | mask;
-      for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+      for (i = 32; i < sizeof(mask) * 8; i <<= 1)
         mask = (mask << i) | mask;
 
-      while (length >= LBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(length))
         {
-          if (DETECTCHAR (*asrc, mask))
+          if (DETECT_CHAR(*asrc, mask))
             break;
-          length -= LBLOCKSIZE;
+          length -= LITTLE_BLOCK_SIZE;
           asrc++;
         }
 
-      /* If there are fewer than LBLOCKSIZE characters left,
+      /* If there are fewer than LITTLE_BLOCK_SIZE characters left,
          then we resort to the bytewise loop.  */
 
       src = (unsigned char *) asrc;
diff --git a/newlib/libc/string/memcmp.c b/newlib/libc/string/memcmp.c
index 342fb9fbc..c996f3349 100644
--- a/newlib/libc/string/memcmp.c
+++ b/newlib/libc/string/memcmp.c
@@ -30,17 +30,7 @@  QUICKREF
 */
 
 #include <string.h>
-
-
-/* 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)))
-
-/* How many bytes are copied each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the byte copier.  */
-#define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
+#include "local.h"
 
 int
 memcmp (const void *m1,
@@ -70,22 +60,22 @@  memcmp (const void *m1,
   /* If the size is too small, or either pointer is unaligned,
      then we punt to the byte compare loop.  Hopefully this will
      not turn up in inner loops.  */
-  if (!TOO_SMALL(n) && !UNALIGNED(s1,s2))
+  if (!TOO_SMALL_LITTLE_BLOCK(n) && !UNALIGNED_X_Y(s1,s2))
     {
       /* Otherwise, load and compare the blocks of memory one 
          word at a time.  */
       a1 = (unsigned long*) s1;
       a2 = (unsigned long*) s2;
-      while (n >= LBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(n))
         {
           if (*a1 != *a2) 
    	    break;
           a1++;
           a2++;
-          n -= LBLOCKSIZE;
+          n -= LITTLE_BLOCK_SIZE;
         }
 
-      /* check m mod LBLOCKSIZE remaining characters */
+      /* check m mod LITTLE_BLOCK_SIZE remaining characters */
 
       s1 = (unsigned char*)a1;
       s2 = (unsigned char*)a2;
diff --git a/newlib/libc/string/memcpy.c b/newlib/libc/string/memcpy.c
index 52f716b92..1bbd4e0bf 100644
--- a/newlib/libc/string/memcpy.c
+++ b/newlib/libc/string/memcpy.c
@@ -31,19 +31,6 @@  QUICKREF
 #include <string.h>
 #include "local.h"
 
-/* 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)))
-
-/* How many bytes are copied each iteration of the 4X unrolled loop.  */
-#define BIGBLOCKSIZE    (sizeof (long) << 2)
-
-/* How many bytes are copied each iteration of the word copy loop.  */
-#define LITTLEBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the byte copier.  */
-#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
-
 void *
 __inhibit_loop_to_libcall
 memcpy (void *__restrict dst0,
@@ -70,26 +57,26 @@  memcpy (void *__restrict dst0,
 
   /* 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))
+  if (!TOO_SMALL_BIG_BLOCK(len0) && !UNALIGNED_X_Y(src, dst))
     {
       aligned_dst = (long*)dst;
       aligned_src = (long*)src;
 
       /* Copy 4X long words at a time if possible.  */
-      while (len0 >= BIGBLOCKSIZE)
+      while (!TOO_SMALL_BIG_BLOCK(len0))
         {
           *aligned_dst++ = *aligned_src++;
           *aligned_dst++ = *aligned_src++;
           *aligned_dst++ = *aligned_src++;
           *aligned_dst++ = *aligned_src++;
-          len0 -= BIGBLOCKSIZE;
+          len0 -= BIG_BLOCK_SIZE;
         }
 
       /* Copy one long word at a time if possible.  */
-      while (len0 >= LITTLEBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(len0))
         {
           *aligned_dst++ = *aligned_src++;
-          len0 -= LITTLEBLOCKSIZE;
+          len0 -= LITTLE_BLOCK_SIZE;
         }
 
        /* Pick up any residual with a byte copier.  */
diff --git a/newlib/libc/string/memmove.c b/newlib/libc/string/memmove.c
index da5dfdbdd..a82744c7d 100644
--- a/newlib/libc/string/memmove.c
+++ b/newlib/libc/string/memmove.c
@@ -34,19 +34,6 @@  QUICKREF
 #include <limits.h>
 #include "local.h"
 
-/* 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)))
-
-/* How many bytes are copied each iteration of the 4X unrolled loop.  */
-#define BIGBLOCKSIZE    (sizeof (long) << 2)
-
-/* How many bytes are copied each iteration of the word copy loop.  */
-#define LITTLEBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the byte copier.  */
-#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
-
 /*SUPPRESS 20*/
 void *
 __inhibit_loop_to_libcall
@@ -98,26 +85,26 @@  memmove (void *dst_void,
       /* Use optimizing algorithm for a non-destructive copy to closely 
          match memcpy. 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(length) && !UNALIGNED (src, dst))
+      if (!TOO_SMALL_BIG_BLOCK(length) && !UNALIGNED_X_Y(src, dst))
         {
           aligned_dst = (long*)dst;
           aligned_src = (long*)src;
 
           /* Copy 4X long words at a time if possible.  */
-          while (length >= BIGBLOCKSIZE)
+          while (!TOO_SMALL_BIG_BLOCK(length))
             {
               *aligned_dst++ = *aligned_src++;
               *aligned_dst++ = *aligned_src++;
               *aligned_dst++ = *aligned_src++;
               *aligned_dst++ = *aligned_src++;
-              length -= BIGBLOCKSIZE;
+              length -= BIG_BLOCK_SIZE;
             }
 
           /* Copy one long word at a time if possible.  */
-          while (length >= LITTLEBLOCKSIZE)
+          while (!TOO_SMALL_LITTLE_BLOCK(length))
             {
               *aligned_dst++ = *aligned_src++;
-              length -= LITTLEBLOCKSIZE;
+              length -= LITTLE_BLOCK_SIZE;
             }
 
           /* Pick up any residual with a byte copier.  */
diff --git a/newlib/libc/string/mempcpy.c b/newlib/libc/string/mempcpy.c
index 129165603..06e97de85 100644
--- a/newlib/libc/string/mempcpy.c
+++ b/newlib/libc/string/mempcpy.c
@@ -28,19 +28,7 @@  PORTABILITY
 #include <stddef.h>
 #include <limits.h>
 #include <string.h>
-
-/* 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)))
-
-/* How many bytes are copied each iteration of the 4X unrolled loop.  */
-#define BIGBLOCKSIZE    (sizeof (long) << 2)
-
-/* How many bytes are copied each iteration of the word copy loop.  */
-#define LITTLEBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the byte copier.  */
-#define TOO_SMALL(LEN)  ((LEN) < BIGBLOCKSIZE)
+#include "local.h"
 
 void *
 mempcpy (void *dst0,
@@ -65,26 +53,26 @@  mempcpy (void *dst0,
 
   /* 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))
+  if (!TOO_SMALL_BIG_BLOCK(len0) && !UNALIGNED_X_Y(src, dst))
     {
       aligned_dst = (long*)dst;
       aligned_src = (long*)src;
 
       /* Copy 4X long words at a time if possible.  */
-      while (len0 >= BIGBLOCKSIZE)
+      while (!TOO_SMALL_BIG_BLOCK(len0))
         {
           *aligned_dst++ = *aligned_src++;
           *aligned_dst++ = *aligned_src++;
           *aligned_dst++ = *aligned_src++;
           *aligned_dst++ = *aligned_src++;
-          len0 -= BIGBLOCKSIZE;
+          len0 -= BIG_BLOCK_SIZE;
         }
 
       /* Copy one long word at a time if possible.  */
-      while (len0 >= LITTLEBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(len0))
         {
           *aligned_dst++ = *aligned_src++;
-          len0 -= LITTLEBLOCKSIZE;
+          len0 -= LITTLE_BLOCK_SIZE;
         }
 
        /* Pick up any residual with a byte copier.  */
diff --git a/newlib/libc/string/memrchr.c b/newlib/libc/string/memrchr.c
index 652efb359..0a0c80fd9 100644
--- a/newlib/libc/string/memrchr.c
+++ b/newlib/libc/string/memrchr.c
@@ -32,34 +32,7 @@  QUICKREF
 #include <_ansi.h>
 #include <string.h>
 #include <limits.h>
-
-/* Nonzero if X is not aligned on a "long" boundary.  */
-#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))
-
-/* Threshhold for punting to the bytewise iterator.  */
-#define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
-/* DETECTCHAR returns nonzero if (long)X contains the byte used
-   to fill (long)MASK. */
-#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
+#include "local.h"
 
 void *
 memrchr (const void *src_void,
@@ -74,7 +47,7 @@  memrchr (const void *src_void,
   unsigned long  mask;
   unsigned int i;
 
-  while (UNALIGNED (src))
+  while (UNALIGNED_X(src))
     {
       if (!length--)
         return NULL;
@@ -83,7 +56,7 @@  memrchr (const void *src_void,
       src--;
     }
 
-  if (!TOO_SMALL (length))
+  if (!TOO_SMALL_LITTLE_BLOCK(length))
     {
       /* If we get this far, we know that length is large and src is
          word-aligned. */
@@ -93,24 +66,24 @@  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 = (unsigned long *) (src - LITTLE_BLOCK_SIZE + 1);
       mask = d << 8 | d;
       mask = mask << 16 | mask;
-      for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+      for (i = 32; i < sizeof(mask) * 8; i <<= 1)
         mask = (mask << i) | mask;
 
-      while (length >= LBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(length))
         {
-          if (DETECTCHAR (*asrc, mask))
+          if (DETECT_CHAR(*asrc, mask))
             break;
-          length -= LBLOCKSIZE;
+          length -= LITTLE_BLOCK_SIZE;
           asrc--;
         }
 
-      /* If there are fewer than LBLOCKSIZE characters left,
+      /* If there are fewer than LITTLE_BLOCK_SIZE characters left,
          then we resort to the bytewise loop.  */
 
-      src = (unsigned char *) asrc + LBLOCKSIZE - 1;
+      src = (unsigned char *) asrc + LITTLE_BLOCK_SIZE - 1;
     }
 
 #endif /* not PREFER_SIZE_OVER_SPEED */
diff --git a/newlib/libc/string/memset.c b/newlib/libc/string/memset.c
index e8e667a24..99b5526c7 100644
--- a/newlib/libc/string/memset.c
+++ b/newlib/libc/string/memset.c
@@ -29,10 +29,6 @@  QUICKREF
 #include <string.h>
 #include "local.h"
 
-#define LBLOCKSIZE (sizeof(long))
-#define UNALIGNED(X)   ((long)X & (LBLOCKSIZE - 1))
-#define TOO_SMALL(LEN) ((LEN) < LBLOCKSIZE)
-
 void *
 __inhibit_loop_to_libcall
 memset (void *m,
@@ -48,7 +44,7 @@  memset (void *m,
   unsigned int d = c & 0xff;	/* To avoid sign extension, copy C to an
 				   unsigned variable.  */
 
-  while (UNALIGNED (s))
+  while (UNALIGNED_X(s))
     {
       if (n--)
         *s++ = (char) c;
@@ -56,7 +52,7 @@  memset (void *m,
         return m;
     }
 
-  if (!TOO_SMALL (n))
+  if (!TOO_SMALL_LITTLE_BLOCK(n))
     {
       /* If we get this far, we know that n is large and s is word-aligned. */
       aligned_addr = (unsigned long *) s;
@@ -65,23 +61,23 @@  memset (void *m,
          we can set large blocks quickly.  */
       buffer = (d << 8) | d;
       buffer |= (buffer << 16);
-      for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+      for (i = 32; i < sizeof(buffer) * 8; i <<= 1)
         buffer = (buffer << i) | buffer;
 
       /* Unroll the loop.  */
-      while (n >= LBLOCKSIZE*4)
+      while (!TOO_SMALL_BIG_BLOCK(n))
         {
           *aligned_addr++ = buffer;
           *aligned_addr++ = buffer;
           *aligned_addr++ = buffer;
           *aligned_addr++ = buffer;
-          n -= 4*LBLOCKSIZE;
+          n -= BIG_BLOCK_SIZE;
         }
 
-      while (n >= LBLOCKSIZE)
+      while (!TOO_SMALL_LITTLE_BLOCK(n))
         {
           *aligned_addr++ = buffer;
-          n -= LBLOCKSIZE;
+          n -= LITTLE_BLOCK_SIZE;
         }
       /* Pick up the remainder with a bytewise loop.  */
       s = (char*)aligned_addr;
diff --git a/newlib/libc/string/rawmemchr.c b/newlib/libc/string/rawmemchr.c
index 56e2b5e2d..1458a9d8b 100644
--- a/newlib/libc/string/rawmemchr.c
+++ b/newlib/libc/string/rawmemchr.c
@@ -31,34 +31,7 @@  QUICKREF
 #include <_ansi.h>
 #include <string.h>
 #include <limits.h>
-
-/* Nonzero if X is not aligned on a "long" boundary.  */
-#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
-
-/* How many bytes are loaded each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
-
-/* Threshhold for punting to the bytewise iterator.  */
-#define TOO_SMALL(LEN)  ((LEN) < LBLOCKSIZE)
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
-/* DETECTCHAR returns nonzero if (long)X contains the byte used
-   to fill (long)MASK. */
-#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
+#include "local.h"
 
 void *
 rawmemchr (const void *src_void,
@@ -72,7 +45,7 @@  rawmemchr (const void *src_void,
   unsigned long  mask;
   unsigned int i;
 
-  while (UNALIGNED (src))
+  while (UNALIGNED_X (src))
     {
       if (*src == d)
         return (void *) src;
@@ -89,12 +62,12 @@  rawmemchr (const void *src_void,
   asrc = (unsigned long *) src;
   mask = d << 8 | d;
   mask = mask << 16 | mask;
-  for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
+  for (i = 32; i < sizeof(mask) * 8; i <<= 1)
     mask = (mask << i) | mask;
 
   while (1)
     {
-      if (DETECTCHAR (*asrc, mask))
+      if (DETECT_CHAR (*asrc, mask))
         break;
       asrc++;
     }
diff --git a/newlib/libc/string/stpcpy.c b/newlib/libc/string/stpcpy.c
index 4e2ae9fe0..884ac8f10 100644
--- a/newlib/libc/string/stpcpy.c
+++ b/newlib/libc/string/stpcpy.c
@@ -33,25 +33,6 @@  QUICKREF
 /*SUPPRESS 560*/
 /*SUPPRESS 530*/
 
-/* 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)))
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
 char*
 stpcpy (char *__restrict dst,
 	const char *__restrict src)
@@ -61,14 +42,14 @@  stpcpy (char *__restrict dst,
   const long *aligned_src;
 
   /* If SRC or DEST is unaligned, then copy bytes.  */
-  if (!UNALIGNED (src, dst))
+  if (!UNALIGNED_X_Y(src, dst))
     {
       aligned_dst = (long*)dst;
       aligned_src = (long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
          sized copies.  */
-      while (!DETECTNULL(*aligned_src))
+      while (!DETECT_NULL(*aligned_src))
         {
           *aligned_dst++ = *aligned_src++;
         }
diff --git a/newlib/libc/string/stpncpy.c b/newlib/libc/string/stpncpy.c
index 87fe268cf..2e356c4b8 100644
--- a/newlib/libc/string/stpncpy.c
+++ b/newlib/libc/string/stpncpy.c
@@ -35,31 +35,11 @@  QUICKREF
 
 #include <string.h>
 #include <limits.h>
+#include "local.h"
 
 /*SUPPRESS 560*/
 /*SUPPRESS 530*/
 
-/* 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)))
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
-#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
-
 char *
 stpncpy (char *__restrict dst,
 	const char *__restrict src,
@@ -72,16 +52,16 @@  stpncpy (char *__restrict dst,
   const long *aligned_src;
 
   /* If SRC and DEST is aligned and count large enough, then copy words.  */
-  if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
+  if (!UNALIGNED_X_Y (src, dst) && !TOO_SMALL_LITTLE_BLOCK (count))
     {
       aligned_dst = (long*)dst;
       aligned_src = (long*)src;
 
-      /* SRC and DEST are both "long int" aligned, try to do "long int"
-	 sized copies.  */
-      while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
+      /* SRC and DEST are both LITTLE_BLOCK_SIZE aligned,
+	 try to do LITTLE_BLOCK_SIZE sized copies.  */
+      while (!TOO_SMALL_LITTLE_BLOCK (count) && !DETECT_NULL(*aligned_src))
 	{
-	  count -= sizeof (long int);
+	  count -= LITTLE_BLOCK_SIZE;
 	  *aligned_dst++ = *aligned_src++;
 	}
 
diff --git a/newlib/libc/string/strcat.c b/newlib/libc/string/strcat.c
index 92313c492..71dd1db75 100644
--- a/newlib/libc/string/strcat.c
+++ b/newlib/libc/string/strcat.c
@@ -29,26 +29,7 @@  QUICKREF
 
 #include <string.h>
 #include <limits.h>
-
-/* Nonzero if X is aligned on a "long" boundary.  */
-#define ALIGNED(X) \
-  (((long)X & (sizeof (long) - 1)) == 0)
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
+#include "local.h"
 
 /*SUPPRESS 560*/
 /*SUPPRESS 530*/
@@ -71,10 +52,10 @@  strcat (char *__restrict s1,
 
 
   /* Skip over the data in s1 as quickly as possible.  */
-  if (ALIGNED (s1))
+  if (!UNALIGNED_X(s1))
     {
       unsigned long *aligned_s1 = (unsigned long *)s1;
-      while (!DETECTNULL (*aligned_s1))
+      while (!DETECT_NULL(*aligned_s1))
 	aligned_s1++;
 
       s1 = (char *)aligned_s1;
diff --git a/newlib/libc/string/strchr.c b/newlib/libc/string/strchr.c
index 96f30be04..66afefdb1 100644
--- a/newlib/libc/string/strchr.c
+++ b/newlib/libc/string/strchr.c
@@ -30,26 +30,6 @@  QUICKREF
 #include <string.h>
 #include <limits.h>
 
-/* Nonzero if X is not aligned on a "long" boundary.  */
-#define UNALIGNED(X) ((long)X & (sizeof (long) - 1))
-
-/* How many bytes are loaded each iteration of the word copy loop.  */
-#define LBLOCKSIZE (sizeof (long))
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-/* DETECTCHAR returns nonzero if (long)X contains the byte used
-   to fill (long)MASK. */
-#define DETECTCHAR(X,MASK) (DETECTNULL(X ^ MASK))
 
 char *
 strchr (const char *s1,
@@ -65,7 +45,7 @@  strchr (const char *s1,
   /* Special case for finding 0.  */
   if (!c)
     {
-      while (UNALIGNED (s))
+      while (UNALIGNED_X(s))
         {
           if (!*s)
             return (char *) s;
@@ -73,7 +53,7 @@  strchr (const char *s1,
         }
       /* Operate a word at a time.  */
       aligned_addr = (unsigned long *) s;
-      while (!DETECTNULL (*aligned_addr))
+      while (!DETECT_NULL(*aligned_addr))
         aligned_addr++;
       /* Found the end of string.  */
       s = (const unsigned char *) aligned_addr;
@@ -83,7 +63,7 @@  strchr (const char *s1,
     }
 
   /* All other bytes.  Align the pointer, then search a long at a time.  */
-  while (UNALIGNED (s))
+  while (UNALIGNED_X(s))
     {
       if (!*s)
         return NULL;
@@ -93,11 +73,11 @@  strchr (const char *s1,
     }
 
   mask = c;
-  for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
+  for (j = 8; j < sizeof(mask) * 8; j <<= 1)
     mask = (mask << j) | mask;
 
   aligned_addr = (unsigned long *) s;
-  while (!DETECTNULL (*aligned_addr) && !DETECTCHAR (*aligned_addr, mask))
+  while (!DETECT_NULL(*aligned_addr) && !DETECT_CHAR(*aligned_addr, mask))
     aligned_addr++;
 
   /* The block of bytes currently pointed to by aligned_addr
diff --git a/newlib/libc/string/strcmp.c b/newlib/libc/string/strcmp.c
index 894424a69..1cd2ec1c1 100644
--- a/newlib/libc/string/strcmp.c
+++ b/newlib/libc/string/strcmp.c
@@ -32,25 +32,6 @@  QUICKREF
 #include <string.h>
 #include <limits.h>
 
-/* 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)))
-
-/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
 int
 strcmp (const char *s1,
 	const char *s2)
@@ -68,7 +49,7 @@  strcmp (const char *s1,
   unsigned long *a2;
 
   /* If s1 or s2 are unaligned, then compare bytes. */
-  if (!UNALIGNED (s1, s2))
+  if (!UNALIGNED_X_Y(s1, s2))
     {  
       /* If s1 and s2 are word-aligned, compare them a word at a time. */
       a1 = (unsigned long*)s1;
@@ -77,7 +58,7 @@  strcmp (const char *s1,
         {
           /* To get here, *a1 == *a2, thus if we find a null in *a1,
 	     then the strings must be equal, so return zero.  */
-          if (DETECTNULL (*a1))
+          if (DETECT_NULL(*a1))
 	    return 0;
 
           a1++;
diff --git a/newlib/libc/string/strcpy.c b/newlib/libc/string/strcpy.c
index 94e16b512..f79651e75 100644
--- a/newlib/libc/string/strcpy.c
+++ b/newlib/libc/string/strcpy.c
@@ -32,25 +32,6 @@  QUICKREF
 /*SUPPRESS 560*/
 /*SUPPRESS 530*/
 
-/* 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)))
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
 char*
 strcpy (char *dst0,
 	const char *src0)
@@ -69,14 +50,14 @@  strcpy (char *dst0,
   const long *aligned_src;
 
   /* If SRC or DEST is unaligned, then copy bytes.  */
-  if (!UNALIGNED (src, dst))
+  if (!UNALIGNED_X_Y(src, dst))
     {
       aligned_dst = (long*)dst;
       aligned_src = (long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
          sized copies.  */
-      while (!DETECTNULL(*aligned_src))
+      while (!DETECT_NULL(*aligned_src))
         {
           *aligned_dst++ = *aligned_src++;
         }
diff --git a/newlib/libc/string/strlen.c b/newlib/libc/string/strlen.c
index acffa49e1..f48d6d400 100644
--- a/newlib/libc/string/strlen.c
+++ b/newlib/libc/string/strlen.c
@@ -29,24 +29,7 @@  QUICKREF
 #include <_ansi.h>
 #include <string.h>
 #include <limits.h>
-
-#define LBLOCKSIZE   (sizeof (long))
-#define UNALIGNED(X) ((long)X & (LBLOCKSIZE - 1))
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
+#include "local.h"
 
 size_t
 strlen (const char *str)
@@ -57,7 +40,7 @@  strlen (const char *str)
   unsigned long *aligned_addr;
 
   /* Align the pointer, so we can search a word at a time.  */
-  while (UNALIGNED (str))
+  while (UNALIGNED_X(str))
     {
       if (!*str)
 	return str - start;
@@ -67,7 +50,7 @@  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;
-  while (!DETECTNULL (*aligned_addr))
+  while (!DETECT_NULL(*aligned_addr))
     aligned_addr++;
 
   /* Once a null is detected, we check each byte in that block for a
diff --git a/newlib/libc/string/strncat.c b/newlib/libc/string/strncat.c
index 7351913f9..01f20f681 100644
--- a/newlib/libc/string/strncat.c
+++ b/newlib/libc/string/strncat.c
@@ -37,25 +37,7 @@  QUICKREF
 
 #include <string.h>
 #include <limits.h>
-
-/* Nonzero if X is aligned on a "long" boundary.  */
-#define ALIGNED(X) \
-  (((long)X & (sizeof (long) - 1)) == 0)
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
+#include "local.h"
 
 char *
 strncat (char *__restrict s1,
@@ -78,10 +60,10 @@  strncat (char *__restrict s1,
   char *s = s1;
 
   /* Skip over the data in s1 as quickly as possible.  */
-  if (ALIGNED (s1))
+  if (!UNALIGNED_X(s1))
     {
       unsigned long *aligned_s1 = (unsigned long *)s1;
-      while (!DETECTNULL (*aligned_s1))
+      while (!DETECT_NULL(*aligned_s1))
 	aligned_s1++;
 
       s1 = (char *)aligned_s1;
diff --git a/newlib/libc/string/strncmp.c b/newlib/libc/string/strncmp.c
index 16f8a7729..d59a26364 100644
--- a/newlib/libc/string/strncmp.c
+++ b/newlib/libc/string/strncmp.c
@@ -31,25 +31,7 @@  QUICKREF
 
 #include <string.h>
 #include <limits.h>
-
-/* 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)))
-
-/* DETECTNULL returns nonzero if (long)X contains a NULL byte. */
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
+#include "local.h"
 
 int 
 strncmp (const char *s1,
@@ -77,7 +59,7 @@  strncmp (const char *s1,
     return 0;
 
   /* If s1 or s2 are unaligned, then compare bytes. */
-  if (!UNALIGNED (s1, s2))
+  if (!UNALIGNED_X_Y(s1, s2))
     {
       /* If s1 and s2 are word-aligned, compare them a word at a time. */
       a1 = (unsigned long*)s1;
@@ -88,7 +70,7 @@  strncmp (const char *s1,
 
           /* If we've run out of bytes or hit a null, return zero
 	     since we already know *a1 == *a2.  */
-          if (n == 0 || DETECTNULL (*a1))
+          if (n == 0 || DETECT_NULL (*a1))
 	    return 0;
 
           a1++;
diff --git a/newlib/libc/string/strncpy.c b/newlib/libc/string/strncpy.c
index e7eb34d72..98748a17d 100644
--- a/newlib/libc/string/strncpy.c
+++ b/newlib/libc/string/strncpy.c
@@ -33,31 +33,11 @@  QUICKREF
 
 #include <string.h>
 #include <limits.h>
+#include "local.h"
 
 /*SUPPRESS 560*/
 /*SUPPRESS 530*/
 
-/* 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)))
-
-#if LONG_MAX == 2147483647L
-#define DETECTNULL(X) (((X) - 0x01010101) & ~(X) & 0x80808080)
-#else
-#if LONG_MAX == 9223372036854775807L
-/* Nonzero if X (a long int) contains a NULL byte. */
-#define DETECTNULL(X) (((X) - 0x0101010101010101) & ~(X) & 0x8080808080808080)
-#else
-#error long int is not a 32bit or 64bit type.
-#endif
-#endif
-
-#ifndef DETECTNULL
-#error long int is not a 32bit or 64bit byte
-#endif
-
-#define TOO_SMALL(LEN) ((LEN) < sizeof (long))
-
 char *
 strncpy (char *__restrict dst0,
 	const char *__restrict src0,
@@ -86,14 +66,14 @@  strncpy (char *__restrict dst0,
   const long *aligned_src;
 
   /* If SRC and DEST is aligned and count large enough, then copy words.  */
-  if (!UNALIGNED (src, dst) && !TOO_SMALL (count))
+  if (!UNALIGNED_X_Y(src, dst) && !TOO_SMALL_LITTLE_BLOCK(count))
     {
       aligned_dst = (long*)dst;
       aligned_src = (long*)src;
 
       /* SRC and DEST are both "long int" aligned, try to do "long int"
 	 sized copies.  */
-      while (count >= sizeof (long int) && !DETECTNULL(*aligned_src))
+      while (!TOO_SMALL_LITTLE_BLOCK(count) && !DETECT_NULL(*aligned_src))
 	{
 	  count -= sizeof (long int);
 	  *aligned_dst++ = *aligned_src++;