[3/4] newlib: riscv: Add stpcpy() port

Message ID cfb8c503b5a34ecf9b0f08aaa257d08446df9f99.1742483743.git.ericsalem@gmail.com
State New
Headers
Series newlib: riscv: Optimize string functions |

Commit Message

Eric Salem March 20, 2025, 3:28 p.m. UTC
  Add implementation of stpcpy() to the RISC-V port. Also refactor shared
code between strcpy() and stpcpy() to a common function.

Reviewed-by: Christian Herber <christian.herber@oss.nxp.com>
Signed-off-by: Eric Salem <ericsalem@gmail.com>
---
 newlib/libc/machine/riscv/Makefile.inc |  2 +-
 newlib/libc/machine/riscv/stpcpy.c     |  7 +++
 newlib/libc/machine/riscv/strcpy.c     | 46 +-----------------
 newlib/libc/machine/riscv/sys/string.h | 65 ++++++++++++++++++++++++++
 4 files changed, 75 insertions(+), 45 deletions(-)
 create mode 100644 newlib/libc/machine/riscv/stpcpy.c
  

Patch

diff --git a/newlib/libc/machine/riscv/Makefile.inc b/newlib/libc/machine/riscv/Makefile.inc
index 47bbce00b79e..4d6c0469abb3 100644
--- a/newlib/libc/machine/riscv/Makefile.inc
+++ b/newlib/libc/machine/riscv/Makefile.inc
@@ -1,3 +1,3 @@ 
 libc_a_SOURCES += \
 	%D%/memmove.S %D%/memmove-stub.c %D%/memset.S %D%/memcpy-asm.S %D%/memcpy.c %D%/strlen.c \
-	%D%/strcpy.c %D%/strcmp.S %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c
+	%D%/strcpy.c %D%/stpcpy.c %D%/strcmp.S %D%/setjmp.S %D%/ieeefp.c %D%/ffs.c
diff --git a/newlib/libc/machine/riscv/stpcpy.c b/newlib/libc/machine/riscv/stpcpy.c
new file mode 100644
index 000000000000..9243457b25a2
--- /dev/null
+++ b/newlib/libc/machine/riscv/stpcpy.c
@@ -0,0 +1,7 @@ 
+#include <string.h>
+#include <stdbool.h>
+
+char *stpcpy(char *dst, const char *src)
+{
+  return __libc_strcpy(dst, src, false);
+}
diff --git a/newlib/libc/machine/riscv/strcpy.c b/newlib/libc/machine/riscv/strcpy.c
index 7b1780025ab9..f770493fbc2d 100644
--- a/newlib/libc/machine/riscv/strcpy.c
+++ b/newlib/libc/machine/riscv/strcpy.c
@@ -10,51 +10,9 @@ 
 */
 
 #include <string.h>
-#include <stdint.h>
-#include "sys/asm.h"
+#include <stdbool.h>
 
 char *strcpy(char *dst, const char *src)
 {
-  char *dst0 = dst;
-
-#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
-#if !(__riscv_misaligned_slow || __riscv_misaligned_fast)
-  int misaligned = ((uintxlen_t)dst | (uintxlen_t)src) & (sizeof (uintxlen_t) - 1);
-  if (__builtin_expect(!misaligned, 1))
-#endif
-    {
-      uintxlen_t *pdst = (uintxlen_t *)dst;
-      const uintxlen_t *psrc = (const uintxlen_t *)src;
-
-      while (!__libc_detect_null(*psrc))
-        *pdst++ = *psrc++;
-
-      dst = (char *)pdst;
-      src = (const char *)psrc;
-
-      if (!(*dst++ = src[0])) return dst0;
-      if (!(*dst++ = src[1])) return dst0;
-      if (!(*dst++ = src[2])) return dst0;
-      if (sizeof (*pdst ) == 4) goto out;
-      if (!(*dst++ = src[3])) return dst0;
-      if (!(*dst++ = src[4])) return dst0;
-      if (!(*dst++ = src[5])) return dst0;
-      if (!(*dst++ = src[6])) return dst0;
-
-out:
-      *dst = 0;
-      return dst0;
-    }
-#endif /* not PREFER_SIZE_OVER_SPEED */
-
-  char ch;
-  do
-    {
-      ch = *src;
-      src++;
-      dst++;
-      *(dst - 1) = ch;
-    } while (ch);
-
-  return dst0;
+  return __libc_strcpy(dst, src, true);
 }
diff --git a/newlib/libc/machine/riscv/sys/string.h b/newlib/libc/machine/riscv/sys/string.h
index 88e5dea20c6a..b65635cb6cb6 100644
--- a/newlib/libc/machine/riscv/sys/string.h
+++ b/newlib/libc/machine/riscv/sys/string.h
@@ -12,6 +12,7 @@ 
 #ifndef _SYS_STRING_H
 #define _SYS_STRING_H
 
+#include <stdbool.h>
 #include "asm.h"
 
 #if __riscv_zbb
@@ -56,4 +57,68 @@  static __inline uintxlen_t __libc_detect_null(uintxlen_t w)
 #endif
 }
 
+
+static __inline char *__libc_strcpy(char *dst, const char *src, bool ret_start)
+{
+  char *dst0 = dst;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+#if !(__riscv_misaligned_slow || __riscv_misaligned_fast)
+  int misaligned = ((uintxlen_t)dst | (uintxlen_t)src) & (sizeof (uintxlen_t) - 1);
+  if (__builtin_expect(!misaligned, 1))
+#endif
+    {
+      uintxlen_t *pdst = (uintxlen_t *)dst;
+      const uintxlen_t *psrc = (const uintxlen_t *)src;
+
+      while (!__libc_detect_null(*psrc))
+        *pdst++ = *psrc++;
+
+      dst = (char *)pdst;
+      src = (const char *)psrc;
+
+      if (ret_start)
+        {
+          if (!(*dst++ = src[0])) return dst0;
+          if (!(*dst++ = src[1])) return dst0;
+          if (!(*dst++ = src[2])) return dst0;
+          if (!(*dst++ = src[3])) return dst0;
+          #if __riscv_xlen == 64
+            if (!(*dst++ = src[4])) return dst0;
+            if (!(*dst++ = src[5])) return dst0;
+            if (!(*dst++ = src[6])) return dst0;
+          #endif
+        }
+      else
+        {
+          if (!(*dst++ = src[0])) return dst - 1;
+          if (!(*dst++ = src[1])) return dst - 1;
+          if (!(*dst++ = src[2])) return dst - 1;
+          if (!(*dst++ = src[3])) return dst - 1;
+          #if __riscv_xlen == 64
+            if (!(*dst++ = src[4])) return dst - 1;
+            if (!(*dst++ = src[5])) return dst - 1;
+            if (!(*dst++ = src[6])) return dst - 1;
+            dst0 = dst;
+          #endif
+        }
+
+      *dst = 0;
+      return dst0;
+    }
+#endif /* not PREFER_SIZE_OVER_SPEED */
+
+  char ch;
+  do
+    {
+      ch = *src;
+      src++;
+      dst++;
+      *(dst - 1) = ch;
+    } while (ch);
+
+  return ret_start ? dst0 : dst - 1;
+}
+
+
 #endif