[3/4] newlib: riscv: Add stpcpy() port
Commit Message
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
@@ -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
new file mode 100644
@@ -0,0 +1,7 @@
+#include <string.h>
+#include <stdbool.h>
+
+char *stpcpy(char *dst, const char *src)
+{
+ return __libc_strcpy(dst, src, false);
+}
@@ -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);
}
@@ -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