This is an automated email from the ASF dual-hosted git repository.

jerpelea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit d1dc791d11363c1366289112d7d3c5b92674d708
Author: Xiang Xiao <[email protected]>
AuthorDate: Sun Aug 16 22:54:21 2026 +0800

    libs/libc/string: Add 4-byte alignment middle path for BSD functions.
    
    libc_data_t is 8 bytes wide, so a buffer which is 4-byte but not
    8-byte aligned falls back to the byte at a time loop.  Add a 32-bit
    middle path so such buffers still handle four bytes per iteration.
    
    * Add DETECTNULL32/DETECTCHAR32, UNALIGNED4/UNALIGNED4_X,
      LITTLEBLOCKSIZE4/BIGBLOCKSIZE4 and TOO_SMALL4 to libs/libc/libc.h.
    * Take the new path in memccpy, memcmp, memcpy, memset, stpcpy,
      stpncpy, strcmp, strcpy, strncmp and strncpy when both pointers are
      4-byte aligned but the 8-byte path can't be used.
    
    Assisted-by: Claude:claude-opus-5
    Signed-off-by: Xiang Xiao <[email protected]>
---
 libs/libc/libc.h                  | 26 +++++++++++++++++-
 libs/libc/string/lib_bsdmemccpy.c | 55 +++++++++++++++++++++++----------------
 libs/libc/string/lib_bsdmemchr.c  |  2 --
 libs/libc/string/lib_bsdmemcmp.c  | 29 +++++++++++++++------
 libs/libc/string/lib_bsdmemcpy.c  | 35 ++++++++++++++++++++-----
 libs/libc/string/lib_bsdmemrchr.c |  2 --
 libs/libc/string/lib_bsdmemset.c  | 45 +++++++++++++++++++++++++-------
 libs/libc/string/lib_bsdstpcpy.c  | 24 ++++++++++-------
 libs/libc/string/lib_bsdstpncpy.c | 24 +++++++++++------
 libs/libc/string/lib_bsdstrcmp.c  | 33 ++++++++++++++---------
 libs/libc/string/lib_bsdstrcpy.c  | 23 ++++++++++------
 libs/libc/string/lib_bsdstrncmp.c | 39 +++++++++++++++------------
 libs/libc/string/lib_bsdstrncpy.c | 24 +++++++++++------
 13 files changed, 247 insertions(+), 114 deletions(-)

diff --git a/libs/libc/libc.h b/libs/libc/libc.h
index 3e010bdb9e6..2cc91f5069d 100644
--- a/libs/libc/libc.h
+++ b/libs/libc/libc.h
@@ -184,6 +184,7 @@
 /* How many bytes are copied each iteration of the word copy loop. */
 
 #define LITTLEBLOCKSIZE (sizeof(libc_data_t))
+#define BIGBLOCKSIZE    (sizeof(libc_data_t) << 2)
 
 /* Threshold for punting to the byte copier. */
 
@@ -191,7 +192,30 @@
 
 /* Macros for detecting endchar */
 
-#define DETECTNULL(x) (((x) - 0x0101010101010101LL) & ~(x) & 
0x8080808080808080LL)
+#define DETECTNULL(x) \
+     (((x) - 0x0101010101010101LL) & ~(x) & 0x8080808080808080LL)
+
+#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
+
+/* 32-bit helpers for the 4-byte middle path on 64-bit platforms.
+ * When libc_data_t is 8 bytes, pointers that are 4-byte aligned
+ * but not 8-byte aligned would otherwise fall back to byte-at-a-time.
+ */
+
+#define DETECTNULL32(x) \
+     (((x) - (uint32_t)0x01010101) & ~(x) & (uint32_t)0x80808080)
+
+#define DETECTCHAR32(x, mask) (DETECTNULL32((x) ^ (mask)))
+
+#define UNALIGNED4(x, y) \
+     ((((uintptr_t)(x)) | ((uintptr_t)(y))) & 3)
+
+#define UNALIGNED4_X(x) (((uintptr_t)(x)) & 3)
+
+#define LITTLEBLOCKSIZE4 (sizeof(uint32_t))
+#define BIGBLOCKSIZE4    (sizeof(uint32_t) << 2)
+
+#define TOO_SMALL4(len) ((len) < LITTLEBLOCKSIZE4)
 
 #ifndef __ASSEMBLY__
 
diff --git a/libs/libc/string/lib_bsdmemccpy.c 
b/libs/libc/string/lib_bsdmemccpy.c
index 406f1ddc408..610c482c400 100644
--- a/libs/libc/string/lib_bsdmemccpy.c
+++ b/libs/libc/string/lib_bsdmemccpy.c
@@ -56,11 +56,8 @@
 #undef memccpy
 FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
 {
-  FAR void *ptr = NULL;
   FAR unsigned char *pout = (FAR unsigned char *)s1;
   FAR const unsigned char *pin = (FAR const unsigned char *)s2;
-  FAR libc_data_t *paligned_out;
-  FAR const libc_data_t *paligned_in;
   unsigned char endchar = c & 0xff;
 
   /* If the size is small, or either pin or pout is unaligned,
@@ -69,41 +66,56 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, 
size_t n)
 
   if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
     {
-      unsigned int i;
+      FAR libc_data_t *paligned_out = (FAR libc_data_t *)pout;
+      FAR const libc_data_t *paligned_in = (FAR libc_data_t *)pin;
       libc_data_t mask = 0;
-
-      paligned_out = (FAR libc_data_t *)pout;
-      paligned_in = (FAR libc_data_t *)pin;
-
-      /* The fast code reads the ASCII one word at a time and only
-       * performs the bytewise search on word-sized segments if they
-       * contain the search character, which is detected by XORing
-       * the word-sized segment with a word-sized block of the search
-       * character and then detecting for the presence of NULL in the
-       * result.
-       */
+      unsigned int i;
 
       for (i = 0; i < LITTLEBLOCKSIZE; i++)
         {
           mask = (mask << 8) + endchar;
         }
 
-      /* Copy one libc_data_t word at a time if possible.  */
-
       while (n >= LITTLEBLOCKSIZE)
         {
           libc_data_t buffer = (libc_data_t)(*paligned_in);
           buffer ^= mask;
           if (DETECTNULL(buffer))
             {
-              break; /* endchar is found, go byte by byte from here */
+              break;
             }
 
           *paligned_out++ = *paligned_in++;
           n -= LITTLEBLOCKSIZE;
         }
 
-      /* Pick up any residual with a byte copier.  */
+      pout = (FAR unsigned char *)paligned_out;
+      pin = (FAR unsigned char *)paligned_in;
+    }
+  else if (!TOO_SMALL4(n) && !UNALIGNED4(pin, pout))
+    {
+      FAR uint32_t *paligned_out = (FAR uint32_t *)pout;
+      FAR const uint32_t *paligned_in = (FAR uint32_t *)pin;
+      uint32_t mask = 0;
+      unsigned int i;
+
+      for (i = 0; i < LITTLEBLOCKSIZE4; i++)
+        {
+          mask = (mask << 8) + endchar;
+        }
+
+      while (n >= LITTLEBLOCKSIZE4)
+        {
+          uint32_t buffer = *paligned_in;
+          buffer ^= mask;
+          if (DETECTNULL32(buffer))
+            {
+              break;
+            }
+
+          *paligned_out++ = *paligned_in++;
+          n -= LITTLEBLOCKSIZE4;
+        }
 
       pout = (FAR unsigned char *)paligned_out;
       pin = (FAR unsigned char *)paligned_in;
@@ -113,10 +125,9 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, 
size_t n)
     {
       if ((*pout++ = *pin++) == endchar)
         {
-          ptr = pout;
-          break;
+          return pout;
         }
     }
 
-  return ptr;
+  return NULL;
 }
diff --git a/libs/libc/string/lib_bsdmemchr.c b/libs/libc/string/lib_bsdmemchr.c
index 88ed624fc7b..30db3b0a7c7 100644
--- a/libs/libc/string/lib_bsdmemchr.c
+++ b/libs/libc/string/lib_bsdmemchr.c
@@ -33,8 +33,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
diff --git a/libs/libc/string/lib_bsdmemcmp.c b/libs/libc/string/lib_bsdmemcmp.c
index 5a7a532c936..871b2275aa7 100644
--- a/libs/libc/string/lib_bsdmemcmp.c
+++ b/libs/libc/string/lib_bsdmemcmp.c
@@ -44,8 +44,6 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
 {
   FAR unsigned char *p1 = (FAR unsigned char *)s1;
   FAR unsigned char *p2 = (FAR unsigned char *)s2;
-  FAR libc_data_t *a1;
-  FAR libc_data_t *a2;
 
   /* If the size is too small, or either pointer is unaligned,
    * then we punt to the byte compare loop.  Hopefully this will
@@ -54,12 +52,9 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
 
   if (!TOO_SMALL(n) && !UNALIGNED(p1, p2))
     {
-      /* Otherwise, load and compare the blocks of memory one
-       * word at a time.
-       */
+      FAR libc_data_t *a1 = (FAR libc_data_t *)p1;
+      FAR libc_data_t *a2 = (FAR libc_data_t *)p2;
 
-      a1 = (FAR libc_data_t *)p1;
-      a2 = (FAR libc_data_t *)p2;
       while (n >= LITTLEBLOCKSIZE)
         {
           if (*a1 != *a2)
@@ -72,7 +67,25 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
           n -= LITTLEBLOCKSIZE;
         }
 
-      /* check s mod LBLOCKSIZE remaining characters */
+      p1 = (FAR unsigned char *)a1;
+      p2 = (FAR unsigned char *)a2;
+    }
+  else if (!TOO_SMALL4(n) && !UNALIGNED4(p1, p2))
+    {
+      FAR uint32_t *a1 = (FAR uint32_t *)p1;
+      FAR uint32_t *a2 = (FAR uint32_t *)p2;
+
+      while (n >= LITTLEBLOCKSIZE4)
+        {
+          if (*a1 != *a2)
+            {
+              break;
+            }
+
+          a1++;
+          a2++;
+          n -= LITTLEBLOCKSIZE4;
+        }
 
       p1 = (FAR unsigned char *)a1;
       p2 = (FAR unsigned char *)a2;
diff --git a/libs/libc/string/lib_bsdmemcpy.c b/libs/libc/string/lib_bsdmemcpy.c
index 6686088f6eb..3950a85f9c0 100644
--- a/libs/libc/string/lib_bsdmemcpy.c
+++ b/libs/libc/string/lib_bsdmemcpy.c
@@ -33,8 +33,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define BIGBLOCKSIZE (sizeof(libc_data_t) << 2)
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -50,8 +48,6 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, size_t 
n)
 {
   FAR char *pout = dest;
   FAR const char *pin = src;
-  FAR libc_data_t *paligned_out;
-  FAR const libc_data_t *paligned_in;
 
   /* If the size is small, or either pin or pout is unaligned,
    * then punt into the byte copy loop.  This should be rare.
@@ -59,8 +55,8 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, size_t 
n)
 
   if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
     {
-      paligned_out = (FAR libc_data_t *)pout;
-      paligned_in = (FAR libc_data_t *)pin;
+      FAR libc_data_t *paligned_out = (FAR libc_data_t *)pout;
+      FAR const libc_data_t *paligned_in = (FAR libc_data_t *)pin;
 
       /* Copy 4X libc_data_t words at a time if possible. */
 
@@ -81,7 +77,32 @@ FAR void *memcpy(FAR void *dest, FAR const void *src, size_t 
n)
           n -= LITTLEBLOCKSIZE;
         }
 
-      /* Pick up any residual with a byte copier. */
+      pout = (FAR char *)paligned_out;
+      pin = (FAR char *)paligned_in;
+    }
+  else if (!TOO_SMALL4(n) && !UNALIGNED4(pin, pout))
+    {
+      FAR uint32_t *paligned_out = (FAR uint32_t *)pout;
+      FAR const uint32_t *paligned_in = (FAR uint32_t *)pin;
+
+      /* Copy 4X uint32_t words at a time if possible. */
+
+      while (n >= BIGBLOCKSIZE4)
+        {
+          *paligned_out++ = *paligned_in++;
+          *paligned_out++ = *paligned_in++;
+          *paligned_out++ = *paligned_in++;
+          *paligned_out++ = *paligned_in++;
+          n -= BIGBLOCKSIZE4;
+        }
+
+      /* Copy one uint32_t word at a time if possible. */
+
+      while (n >= LITTLEBLOCKSIZE4)
+        {
+          *paligned_out++ = *paligned_in++;
+          n -= LITTLEBLOCKSIZE4;
+        }
 
       pout = (FAR char *)paligned_out;
       pin = (FAR char *)paligned_in;
diff --git a/libs/libc/string/lib_bsdmemrchr.c 
b/libs/libc/string/lib_bsdmemrchr.c
index b16651dfcf0..22d8875de97 100644
--- a/libs/libc/string/lib_bsdmemrchr.c
+++ b/libs/libc/string/lib_bsdmemrchr.c
@@ -33,8 +33,6 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
-
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
diff --git a/libs/libc/string/lib_bsdmemset.c b/libs/libc/string/lib_bsdmemset.c
index 1a0b0ecabd2..efdafdea9dd 100644
--- a/libs/libc/string/lib_bsdmemset.c
+++ b/libs/libc/string/lib_bsdmemset.c
@@ -48,7 +48,6 @@ FAR void *memset(FAR void *m, int c, size_t n)
 {
   FAR libc_data_t *aligned_addr;
   FAR char *s = (FAR char *)m;
-  unsigned int d = (unsigned char)c;
   libc_data_t buffer;
   int i;
 
@@ -66,17 +65,19 @@ FAR void *memset(FAR void *m, int c, size_t n)
         }
     }
 
+  buffer  = (uint8_t)c;
+  buffer |= (buffer << 8);
+  buffer |= (buffer << 16);
+  for (i = 32; i < LITTLEBLOCKSIZE * 8; i <<= 1)
+    {
+      buffer = (buffer << i) | buffer;
+    }
+
   if (!TOO_SMALL(n))
     {
       /* If we get this far, we know that n is large and s is word-aligned. */
 
       aligned_addr = (FAR libc_data_t *)s;
-      buffer = (d << 8) | d;
-      buffer |= (buffer << 16);
-      for (i = 32; i < LITTLEBLOCKSIZE * 8; i <<= 1)
-        {
-          buffer = (buffer << i) | buffer;
-        }
 
       /* Unroll the loop.  */
 
@@ -100,9 +101,35 @@ FAR void *memset(FAR void *m, int c, size_t n)
       s = (FAR char *)aligned_addr;
     }
 
-  while (n--)
+  /* Tail: here s is libc_data_t-aligned and n < LITTLEBLOCKSIZE.
+   * Fill with aligned stores of decreasing width - no unaligned access,
+   * no overlap, no over-write.
+   */
+
+  if (LITTLEBLOCKSIZE > 8 && n >= 8)
+    {
+      *(FAR uint64_t *)s = (uint64_t)buffer;
+      s += 8;
+      n -= 8;
+    }
+
+  if (n >= 4)
+    {
+      *(FAR uint32_t *)s = (uint32_t)buffer;
+      s += 4;
+      n -= 4;
+    }
+
+  if (n >= 2)
+    {
+      *(FAR uint16_t *)s = (uint16_t)buffer;
+      s += 2;
+      n -= 2;
+    }
+
+  if (n)
     {
-      *s++ = c;
+      *s = (uint8_t)buffer;
     }
 
   return m;
diff --git a/libs/libc/string/lib_bsdstpcpy.c b/libs/libc/string/lib_bsdstpcpy.c
index db6a5090841..fbd9687adef 100644
--- a/libs/libc/string/lib_bsdstpcpy.c
+++ b/libs/libc/string/lib_bsdstpcpy.c
@@ -56,19 +56,12 @@ no_builtin("stpcpy")
 nosanitize_address
 FAR char *stpcpy(FAR char *dest, FAR const char *src)
 {
-  FAR libc_data_t *aligned_dst;
-  FAR const libc_data_t *aligned_src;
-
   /* If src or dest is unaligned, then copy bytes. */
 
   if (!UNALIGNED(src, dest))
     {
-      aligned_dst = (FAR libc_data_t *)dest;
-      aligned_src = (FAR libc_data_t *)src;
-
-      /* src and dest are both "libc_data_t" aligned, try to do "libc_data_t"
-       * sized copies.
-       */
+      FAR libc_data_t *aligned_dst = (FAR libc_data_t *)dest;
+      FAR const libc_data_t *aligned_src = (FAR libc_data_t *)src;
 
       while (!DETECTNULL(*aligned_src))
         {
@@ -78,6 +71,19 @@ FAR char *stpcpy(FAR char *dest, FAR const char *src)
       dest = (FAR char *)aligned_dst;
       src = (FAR char *)aligned_src;
     }
+  else if (!UNALIGNED4(src, dest))
+    {
+      FAR uint32_t *aligned_dst = (FAR uint32_t *)dest;
+      FAR const uint32_t *aligned_src = (FAR uint32_t *)src;
+
+      while (!DETECTNULL32(*aligned_src))
+        {
+          *aligned_dst++ = *aligned_src++;
+        }
+
+      dest = (FAR char *)aligned_dst;
+      src = (FAR char *)aligned_src;
+    }
 
   while ((*dest++ = *src++) != '\0');
 
diff --git a/libs/libc/string/lib_bsdstpncpy.c 
b/libs/libc/string/lib_bsdstpncpy.c
index c06533a8835..1f8914551d4 100644
--- a/libs/libc/string/lib_bsdstpncpy.c
+++ b/libs/libc/string/lib_bsdstpncpy.c
@@ -66,19 +66,13 @@ no_builtin("stpncpy")
 FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
 {
   FAR char *ret = NULL;
-  FAR libc_data_t *aligned_dst;
-  FAR const libc_data_t *aligned_src;
 
   /* If src and dest is aligned and n large enough, then copy words. */
 
   if (!UNALIGNED(src, dest) && !TOO_SMALL(n))
     {
-      aligned_dst = (FAR libc_data_t *)dest;
-      aligned_src = (FAR libc_data_t *)src;
-
-      /* src and dest are both "libc_data_t" aligned, try to do "libc_data_t"
-       * sized copies.
-       */
+      FAR libc_data_t *aligned_dst = (FAR libc_data_t *)dest;
+      FAR const libc_data_t *aligned_src = (FAR libc_data_t *)src;
 
       while (n >= LITTLEBLOCKSIZE && !DETECTNULL(*aligned_src))
         {
@@ -89,6 +83,20 @@ FAR char *stpncpy(FAR char *dest, FAR const char *src, 
size_t n)
       dest = (FAR char *)aligned_dst;
       src = (FAR char *)aligned_src;
     }
+  else if (!UNALIGNED4(src, dest) && !TOO_SMALL4(n))
+    {
+      FAR uint32_t *aligned_dst = (FAR uint32_t *)dest;
+      FAR const uint32_t *aligned_src = (FAR uint32_t *)src;
+
+      while (n >= LITTLEBLOCKSIZE4 && !DETECTNULL32(*aligned_src))
+        {
+          n -= LITTLEBLOCKSIZE4;
+          *aligned_dst++ = *aligned_src++;
+        }
+
+      dest = (FAR char *)aligned_dst;
+      src = (FAR char *)aligned_src;
+    }
 
   while (n > 0)
     {
diff --git a/libs/libc/string/lib_bsdstrcmp.c b/libs/libc/string/lib_bsdstrcmp.c
index fb2224e4f41..2ec0fed57cb 100644
--- a/libs/libc/string/lib_bsdstrcmp.c
+++ b/libs/libc/string/lib_bsdstrcmp.c
@@ -43,23 +43,15 @@ no_builtin("strcmp")
 nosanitize_address
 int strcmp(FAR const char *cs, FAR const char *ct)
 {
-  FAR libc_data_t *a1;
-  FAR libc_data_t *a2;
-
   /* If cs or ct are unaligned, then compare bytes. */
 
   if (!UNALIGNED(cs, ct))
     {
-      /* If cs and ct are word-aligned, compare them a word at a time. */
+      FAR libc_data_t *a1 = (FAR libc_data_t *)cs;
+      FAR libc_data_t *a2 = (FAR libc_data_t *)ct;
 
-      a1 = (FAR libc_data_t *)cs;
-      a2 = (FAR libc_data_t *)ct;
       while (*a1 == *a2)
         {
-          /* 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))
             {
               return 0;
@@ -69,9 +61,24 @@ int strcmp(FAR const char *cs, FAR const char *ct)
           a2++;
         }
 
-      /* A difference was detected in last few bytes of cs,
-       * so search bytewise.
-       */
+      cs = (FAR char *)a1;
+      ct = (FAR char *)a2;
+    }
+  else if (!UNALIGNED4(cs, ct))
+    {
+      FAR uint32_t *a1 = (FAR uint32_t *)cs;
+      FAR uint32_t *a2 = (FAR uint32_t *)ct;
+
+      while (*a1 == *a2)
+        {
+          if (DETECTNULL32(*a1))
+            {
+              return 0;
+            }
+
+          a1++;
+          a2++;
+        }
 
       cs = (FAR char *)a1;
       ct = (FAR char *)a2;
diff --git a/libs/libc/string/lib_bsdstrcpy.c b/libs/libc/string/lib_bsdstrcpy.c
index 439489c1a64..a19e44d4c94 100644
--- a/libs/libc/string/lib_bsdstrcpy.c
+++ b/libs/libc/string/lib_bsdstrcpy.c
@@ -57,19 +57,13 @@ FAR char *strcpy(FAR char *dest, FAR const char *src)
 {
   FAR char *dst0 = dest;
   FAR const char *src0 = src;
-  FAR libc_data_t *aligned_dst;
-  FAR const libc_data_t *aligned_src;
 
   /* If SRC or DEST is unaligned, then copy bytes. */
 
   if (!UNALIGNED(src0, dst0))
     {
-      aligned_dst = (FAR libc_data_t *)dst0;
-      aligned_src = (FAR libc_data_t *)src0;
-
-      /* SRC and DEST are both "libc_data_t" aligned, try to do "libc_data_t"
-       * sized copies.
-       */
+      FAR libc_data_t *aligned_dst = (FAR libc_data_t *)dst0;
+      FAR const libc_data_t *aligned_src = (FAR libc_data_t *)src0;
 
       while (!DETECTNULL(*aligned_src))
         {
@@ -79,6 +73,19 @@ FAR char *strcpy(FAR char *dest, FAR const char *src)
       dst0 = (FAR char *)aligned_dst;
       src0 = (FAR char *)aligned_src;
     }
+  else if (!UNALIGNED4(src0, dst0))
+    {
+      FAR uint32_t *aligned_dst = (FAR uint32_t *)dst0;
+      FAR const uint32_t *aligned_src = (FAR uint32_t *)src0;
+
+      while (!DETECTNULL32(*aligned_src))
+        {
+          *aligned_dst++ = *aligned_src++;
+        }
+
+      dst0 = (FAR char *)aligned_dst;
+      src0 = (FAR char *)aligned_src;
+    }
 
   while ((*dst0++ = *src0++) != '\0');
 
diff --git a/libs/libc/string/lib_bsdstrncmp.c 
b/libs/libc/string/lib_bsdstrncmp.c
index 747b3b55a22..20f127e1716 100644
--- a/libs/libc/string/lib_bsdstrncmp.c
+++ b/libs/libc/string/lib_bsdstrncmp.c
@@ -43,9 +43,6 @@ no_builtin("strncmp")
 nosanitize_address
 int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
 {
-  FAR libc_data_t *a1;
-  FAR libc_data_t *a2;
-
   if (nb == 0)
     {
       return 0;
@@ -55,18 +52,13 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t 
nb)
 
   if (!UNALIGNED(cs, ct))
     {
-      /* If cs and ct are word-aligned, compare them a word at a time. */
+      FAR libc_data_t *a1 = (FAR libc_data_t *)cs;
+      FAR libc_data_t *a2 = (FAR libc_data_t *)ct;
 
-      a1 = (FAR libc_data_t *)cs;
-      a2 = (FAR libc_data_t *)ct;
       while (nb >= LITTLEBLOCKSIZE && *a1 == *a2)
         {
           nb -= LITTLEBLOCKSIZE;
 
-          /* If we've run out of bytes or hit a null, return zero
-           * since we already know *a1 == *a2.
-           */
-
           if (nb == 0 || DETECTNULL(*a1))
             {
               return 0;
@@ -76,9 +68,26 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t 
nb)
           a2++;
         }
 
-      /* A difference was detected in last few bytes of cs, so search
-       * bytewise.
-       */
+      cs = (FAR char *)a1;
+      ct = (FAR char *)a2;
+    }
+  else if (!UNALIGNED4(cs, ct))
+    {
+      FAR uint32_t *a1 = (FAR uint32_t *)cs;
+      FAR uint32_t *a2 = (FAR uint32_t *)ct;
+
+      while (nb >= LITTLEBLOCKSIZE4 && *a1 == *a2)
+        {
+          nb -= LITTLEBLOCKSIZE4;
+
+          if (nb == 0 || DETECTNULL32(*a1))
+            {
+              return 0;
+            }
+
+          a1++;
+          a2++;
+        }
 
       cs = (FAR char *)a1;
       ct = (FAR char *)a2;
@@ -86,10 +95,6 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t 
nb)
 
   while (nb-- > 0 && *cs == *ct)
     {
-      /* If we've run out of bytes or hit a null, return zero
-       * since we already know *cs == *ct.
-       */
-
       if (nb == 0 || *cs == '\0')
         {
           return 0;
diff --git a/libs/libc/string/lib_bsdstrncpy.c 
b/libs/libc/string/lib_bsdstrncpy.c
index adeed181234..79aeca0aba7 100644
--- a/libs/libc/string/lib_bsdstrncpy.c
+++ b/libs/libc/string/lib_bsdstrncpy.c
@@ -66,19 +66,13 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, 
size_t n)
 {
   FAR char *dst0 = dest;
   FAR const char *src0 = src;
-  FAR libc_data_t *aligned_dst;
-  FAR const libc_data_t *aligned_src;
 
   /* If src and dest is aligned and n large enough, then copy words. */
 
   if (!UNALIGNED(src0, dst0) && !TOO_SMALL(n))
     {
-      aligned_dst = (FAR libc_data_t *)dst0;
-      aligned_src = (FAR libc_data_t *)src0;
-
-      /* src and dest are both "libc_data_t" aligned, try to do "libc_data_t"
-       * sized copies.
-       */
+      FAR libc_data_t *aligned_dst = (FAR libc_data_t *)dst0;
+      FAR const libc_data_t *aligned_src = (FAR libc_data_t *)src0;
 
       while (n >= LITTLEBLOCKSIZE && !DETECTNULL(*aligned_src))
         {
@@ -89,6 +83,20 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, 
size_t n)
       dst0 = (FAR char *)aligned_dst;
       src0 = (FAR char *)aligned_src;
     }
+  else if (!UNALIGNED4(src0, dst0) && !TOO_SMALL4(n))
+    {
+      FAR uint32_t *aligned_dst = (FAR uint32_t *)dst0;
+      FAR const uint32_t *aligned_src = (FAR uint32_t *)src0;
+
+      while (n >= LITTLEBLOCKSIZE4 && !DETECTNULL32(*aligned_src))
+        {
+          n -= LITTLEBLOCKSIZE4;
+          *aligned_dst++ = *aligned_src++;
+        }
+
+      dst0 = (FAR char *)aligned_dst;
+      src0 = (FAR char *)aligned_src;
+    }
 
   while (n > 0)
     {

Reply via email to