[5/6] newlib: str[n]cat: optimize skipping of the destination string

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

Commit Message

Alexey Lapshin Jan. 27, 2025, 10:50 a.m. UTC
  Prepare pointer to be aligned and than use word-size iterator on aligned
memory.
---
 newlib/libc/string/strcat.c  | 18 +++++++++---------
 newlib/libc/string/strncat.c | 17 +++++++++--------
 2 files changed, 18 insertions(+), 17 deletions(-)

-- 
2.43.0
  

Patch

diff --git a/newlib/libc/string/strcat.c b/newlib/libc/string/strcat.c
index 71dd1db75..47c53a5d2 100644
--- a/newlib/libc/string/strcat.c
+++ b/newlib/libc/string/strcat.c
@@ -50,17 +50,17 @@  strcat (char *__restrict s1,
 #else
   char *s = s1;
 
+  /* Skip unaligned memory in s1.  */
+  while (UNALIGNED_X(s1) && *s1)
+    s1++;
 
-  /* Skip over the data in s1 as quickly as possible.  */
-  if (!UNALIGNED_X(s1))
-    {
-      unsigned long *aligned_s1 = (unsigned long *)s1;
-      while (!DETECT_NULL(*aligned_s1))
-	aligned_s1++;
-
-      s1 = (char *)aligned_s1;
-    }
+  /* Skip over the aligned data in s1 as quickly as possible.  */
+  unsigned long *aligned_s1 = (unsigned long *)s1;
+  while (!DETECT_NULL(*aligned_s1))
+    aligned_s1++;
+  s1 = (char *)aligned_s1;
 
+  /* Find string terminator.  */
   while (*s1)
     s1++;
 
diff --git a/newlib/libc/string/strncat.c b/newlib/libc/string/strncat.c
index 01f20f681..fc9fe5b1c 100644
--- a/newlib/libc/string/strncat.c
+++ b/newlib/libc/string/strncat.c
@@ -59,16 +59,17 @@  strncat (char *__restrict s1,
 #else
   char *s = s1;
 
-  /* Skip over the data in s1 as quickly as possible.  */
-  if (!UNALIGNED_X(s1))
-    {
-      unsigned long *aligned_s1 = (unsigned long *)s1;
-      while (!DETECT_NULL(*aligned_s1))
-	aligned_s1++;
+  /* Skip unaligned memory in s1.  */
+  while (UNALIGNED_X(s1) && *s1)
+    s1++;
 
-      s1 = (char *)aligned_s1;
-    }
+  /* Skip over the aligned data in s1 as quickly as possible.  */
+  unsigned long *aligned_s1 = (unsigned long *)s1;
+  while (!DETECT_NULL(*aligned_s1))
+    aligned_s1++;
+  s1 = (char *)aligned_s1;
 
+  /* Find string terminator.  */
   while (*s1)
     s1++;