diff options
author | Eric Salem <ericsalem@gmail.com> | 2025-03-20 10:28:16 -0500 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2025-03-24 12:00:18 +0100 |
commit | c3b9bb173c8c48fb44135d512b39cc856c9acd9c (patch) | |
tree | e554fa4f013dc3fe827e9082c1a0abec2e65c778 | |
parent | 0bfd91d578632b9348d769d2bc8611d6e9493d3a (diff) | |
download | newlib-c3b9bb173c8c48fb44135d512b39cc856c9acd9c.zip newlib-c3b9bb173c8c48fb44135d512b39cc856c9acd9c.tar.gz newlib-c3b9bb173c8c48fb44135d512b39cc856c9acd9c.tar.bz2 |
newlib: riscv: Add XLEN typedef and clean up types
The size of the long data type isn't precisely defined in the C
standard, so create a new typedef that uses either uint32_t or uint64_t
based on XLEN. The fixed width types are more robust against any ABI
changes and fit the data types of the intrinsic functions. Use the new
uintxlen_t type instead of long and uintptr_t.
Reviewed-by: Christian Herber <christian.herber@oss.nxp.com>
Signed-off-by: Eric Salem <ericsalem@gmail.com>
-rw-r--r-- | newlib/libc/machine/riscv/strcpy.c | 40 | ||||
-rw-r--r-- | newlib/libc/machine/riscv/strlen.c | 37 | ||||
-rw-r--r-- | newlib/libc/machine/riscv/sys/asm.h | 4 | ||||
-rw-r--r-- | newlib/libc/machine/riscv/sys/string.h | 8 |
4 files changed, 45 insertions, 44 deletions
diff --git a/newlib/libc/machine/riscv/strcpy.c b/newlib/libc/machine/riscv/strcpy.c index 08aef64..7b17800 100644 --- a/newlib/libc/machine/riscv/strcpy.c +++ b/newlib/libc/machine/riscv/strcpy.c @@ -11,6 +11,7 @@ #include <string.h> #include <stdint.h> +#include "sys/asm.h" char *strcpy(char *dst, const char *src) { @@ -18,37 +19,30 @@ char *strcpy(char *dst, const char *src) #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__) #if !(__riscv_misaligned_slow || __riscv_misaligned_fast) - int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof (long) - 1); + int misaligned = ((uintxlen_t)dst | (uintxlen_t)src) & (sizeof (uintxlen_t) - 1); if (__builtin_expect(!misaligned, 1)) #endif { - long *ldst = (long *)dst; - const long *lsrc = (const long *)src; + uintxlen_t *pdst = (uintxlen_t *)dst; + const uintxlen_t *psrc = (const uintxlen_t *)src; - while (!__libc_detect_null(*lsrc)) - *ldst++ = *lsrc++; + while (!__libc_detect_null(*psrc)) + *pdst++ = *psrc++; - dst = (char *)ldst; - src = (const char *)lsrc; + dst = (char *)pdst; + src = (const char *)psrc; - char c0 = src[0]; - char c1 = src[1]; - char c2 = src[2]; - if (!(*dst++ = c0)) return dst0; - if (!(*dst++ = c1)) return dst0; - char c3 = src[3]; - if (!(*dst++ = c2)) return dst0; - if (sizeof (long) == 4) goto out; - char c4 = src[4]; - if (!(*dst++ = c3)) return dst0; - char c5 = src[5]; - if (!(*dst++ = c4)) return dst0; - char c6 = src[6]; - if (!(*dst++ = c5)) return dst0; - if (!(*dst++ = c6)) return dst0; + 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; + *dst = 0; return dst0; } #endif /* not PREFER_SIZE_OVER_SPEED */ diff --git a/newlib/libc/machine/riscv/strlen.c b/newlib/libc/machine/riscv/strlen.c index 3b04066..5d314ec 100644 --- a/newlib/libc/machine/riscv/strlen.c +++ b/newlib/libc/machine/riscv/strlen.c @@ -11,6 +11,7 @@ #include <string.h> #include <stdint.h> +#include "sys/asm.h" size_t strlen(const char *str) { @@ -21,33 +22,33 @@ size_t strlen(const char *str) ; return str - start - 1; #else - if (__builtin_expect ((uintptr_t)str & (sizeof (long) - 1), 0)) do + if (__builtin_expect ((uintxlen_t)str & (sizeof (uintxlen_t) - 1), 0)) do { char ch = *str; str++; if (!ch) - return str - start - 1; - } while ((uintptr_t)str & (sizeof (long) - 1)); + return str - start - 1; + } while ((uintxlen_t)str & (sizeof (uintxlen_t) - 1)); - unsigned long *ls = (unsigned long *)str; - while (!__libc_detect_null (*ls++)) + uintxlen_t *ps = (uintxlen_t *)str; + while (!__libc_detect_null (*ps++)) ; - asm volatile ("" : "+r"(ls)); /* prevent "optimization" */ + asm volatile ("" : "+r"(ps)); /* prevent "optimization" */ - str = (const char *)ls; - size_t ret = str - start, sl = sizeof (long); + str = (const char *)ps; + size_t ret = str - start, sp = sizeof (*ps); - char c0 = str[0 - sl], c1 = str[1 - sl], c2 = str[2 - sl], c3 = str[3 - sl]; - if (c0 == 0) return ret + 0 - sl; - if (c1 == 0) return ret + 1 - sl; - if (c2 == 0) return ret + 2 - sl; - if (sl == 4 || c3 == 0) return ret + 3 - sl; + char c0 = str[0 - sp], c1 = str[1 - sp], c2 = str[2 - sp], c3 = str[3 - sp]; + if (c0 == 0) return ret + 0 - sp; + if (c1 == 0) return ret + 1 - sp; + if (c2 == 0) return ret + 2 - sp; + if (sp == 4 || c3 == 0) return ret + 3 - sp; - c0 = str[4 - sl], c1 = str[5 - sl], c2 = str[6 - sl], c3 = str[7 - sl]; - if (c0 == 0) return ret + 4 - sl; - if (c1 == 0) return ret + 5 - sl; - if (c2 == 0) return ret + 6 - sl; + c0 = str[4 - sp], c1 = str[5 - sp], c2 = str[6 - sp]; + if (c0 == 0) return ret + 4 - sp; + if (c1 == 0) return ret + 5 - sp; + if (c2 == 0) return ret + 6 - sp; - return ret + 7 - sl; + return ret + 7 - sp; #endif /* not PREFER_SIZE_OVER_SPEED */ } diff --git a/newlib/libc/machine/riscv/sys/asm.h b/newlib/libc/machine/riscv/sys/asm.h index 8c8aeb3..0a354b2 100644 --- a/newlib/libc/machine/riscv/sys/asm.h +++ b/newlib/libc/machine/riscv/sys/asm.h @@ -12,6 +12,8 @@ #ifndef _SYS_ASM_H #define _SYS_ASM_H +#include <stdint.h> + /* * Macros to handle different pointer/register sizes for 32/64-bit code */ @@ -20,11 +22,13 @@ # define SZREG 8 # define REG_S sd # define REG_L ld +typedef uint64_t uintxlen_t; #elif __riscv_xlen == 32 # define PTRLOG 2 # define SZREG 4 # define REG_S sw # define REG_L lw +typedef uint32_t uintxlen_t; #else # error __riscv_xlen must equal 32 or 64 #endif diff --git a/newlib/libc/machine/riscv/sys/string.h b/newlib/libc/machine/riscv/sys/string.h index beebe31..6a0c42a 100644 --- a/newlib/libc/machine/riscv/sys/string.h +++ b/newlib/libc/machine/riscv/sys/string.h @@ -12,10 +12,12 @@ #ifndef _SYS_STRING_H #define _SYS_STRING_H -static __inline unsigned long __libc_detect_null(unsigned long w) +#include "asm.h" + +static __inline uintxlen_t __libc_detect_null(uintxlen_t w) { - unsigned long mask = 0x7f7f7f7f; - if (sizeof (long) == 8) + uintxlen_t mask = 0x7f7f7f7f; + if (sizeof (w) == 8) mask = ((mask << 16) << 16) | mask; return ~(((w & mask) + mask) | w | mask); } |