summaryrefslogtreecommitdiffstats
path: root/newlib/libc/machine/riscv/strcpy.c
diff options
context:
space:
mode:
Diffstat (limited to 'newlib/libc/machine/riscv/strcpy.c')
-rw-r--r--newlib/libc/machine/riscv/strcpy.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/newlib/libc/machine/riscv/strcpy.c b/newlib/libc/machine/riscv/strcpy.c
new file mode 100644
index 000000000..905a9b8df
--- /dev/null
+++ b/newlib/libc/machine/riscv/strcpy.c
@@ -0,0 +1,64 @@
+/* Copyright (c) 2017 SiFive Inc. All rights reserved.
+
+ This copyrighted material is made available to anyone wishing to use,
+ modify, copy, or redistribute it subject to the terms and conditions
+ of the BSD License. This program is distributed in the hope that
+ it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
+ including the implied warranties of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. A copy of this license is available at
+ http://www.opensource.org/licenses.
+*/
+
+#include <string.h>
+#include <stdint.h>
+
+char *strcpy(char *dst, const char *src)
+{
+ char *dst0 = dst;
+
+#if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
+ int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof (long) - 1);
+ if (__builtin_expect(!misaligned, 1))
+ {
+ long *ldst = (long *)dst;
+ const long *lsrc = (const long *)src;
+
+ while (!__libc_detect_null(*lsrc))
+ *ldst++ = *lsrc++;
+
+ dst = (char *)ldst;
+ src = (const char *)lsrc;
+
+ 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;
+
+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;
+}