summaryrefslogtreecommitdiffstats
path: root/newlib/libc/machine/riscv/strcpy.c
diff options
context:
space:
mode:
authorKito Cheng <kito@andestech.com>2017-07-27 16:44:22 +0800
committerJeff Johnston <jjohnstn@redhat.com>2017-08-16 18:00:58 -0400
commit363dbb9e44d0101f29ec34cadd001893daab3fc6 (patch)
tree8c39ab14c5b090653f88bd4624b593ef4819e059 /newlib/libc/machine/riscv/strcpy.c
parent7e69f983a46dfb9ae9c09e30fc20ad6a91f0ddc4 (diff)
downloadcygnal-363dbb9e44d0101f29ec34cadd001893daab3fc6.tar.gz
cygnal-363dbb9e44d0101f29ec34cadd001893daab3fc6.tar.bz2
cygnal-363dbb9e44d0101f29ec34cadd001893daab3fc6.zip
Add RISC-V port for newlib
Contributor list: - Andrew Waterman <andrew@sifive.com> - Palmer Dabbelt <palmer@dabbelt.com> - Kito Cheng <kito.cheng@gmail.com> - Scott Beamer <sbeamer@eecs.berkeley.edu>
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;
+}