[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