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

Eric Salem <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <cfb8c503b5a34ecf9b0f08aaa257d08446df9f99.1742483743.git.ericsalem@gmail.com>
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 <[email protected]>
Signed-off-by: Eric Salem <[email protected]>
---
 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

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
-- 
2.49.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.