aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--newlib/libc/machine/riscv/strcpy.c40
-rw-r--r--newlib/libc/machine/riscv/strlen.c37
-rw-r--r--newlib/libc/machine/riscv/sys/asm.h4
-rw-r--r--newlib/libc/machine/riscv/sys/string.h8
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);
}