1 /* Copyright (c) 2017  SiFive Inc. All rights reserved.
2 
3    This copyrighted material is made available to anyone wishing to use,
4    modify, copy, or redistribute it subject to the terms and conditions
5    of the FreeBSD License.   This program is distributed in the hope that
6    it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
7    including the implied warranties of MERCHANTABILITY or FITNESS FOR
8    A PARTICULAR PURPOSE.  A copy of this license is available at
9    http://www.opensource.org/licenses.
10 */
11 
12 #include <string.h>
13 #include <stdint.h>
14 
15 #undef strcpy
16 
strcpy(char * dst,const char * src)17 char *strcpy(char *dst, const char *src)
18 {
19   char *dst0 = dst;
20 
21 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
22   int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof (long) - 1);
23   if (__builtin_expect(!misaligned, 1))
24     {
25       long *ldst = (long *)dst;
26       const long *lsrc = (const long *)src;
27 
28       while (!__libc_detect_null(*lsrc))
29 	*ldst++ = *lsrc++;
30 
31       dst = (char *)ldst;
32       src = (const char *)lsrc;
33 
34       char c0 = src[0];
35       char c1 = src[1];
36       char c2 = src[2];
37       if (!(*dst++ = c0)) return dst0;
38       if (!(*dst++ = c1)) return dst0;
39       char c3 = src[3];
40       if (!(*dst++ = c2)) return dst0;
41       if (sizeof (long) == 4) goto out;
42       char c4 = src[4];
43       if (!(*dst++ = c3)) return dst0;
44       char c5 = src[5];
45       if (!(*dst++ = c4)) return dst0;
46       char c6 = src[6];
47       if (!(*dst++ = c5)) return dst0;
48       if (!(*dst++ = c6)) return dst0;
49 
50 out:
51       *dst++ = 0;
52       return dst0;
53     }
54 #endif /* not PREFER_SIZE_OVER_SPEED */
55 
56   char ch;
57   do
58     {
59       ch = *src;
60       src++;
61       dst++;
62       *(dst - 1) = ch;
63     } while (ch);
64 
65   return dst0;
66 }
67