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 <picolibc.h>
13 
14 #include <string.h>
15 #include <stdint.h>
16 #include "local.h"
17 
18 #undef strcpy
19 
strcpy(char * dst,const char * src)20 char *strcpy(char *dst, const char *src)
21 {
22   char *dst0 = dst;
23 
24 #if !defined(PREFER_SIZE_OVER_SPEED) && !defined(__OPTIMIZE_SIZE__)
25   int misaligned = ((uintptr_t)dst | (uintptr_t)src) & (sizeof (long) - 1);
26   if (__builtin_expect(!misaligned, 1))
27     {
28       long *ldst = (long *)dst;
29       const long *lsrc = (const long *)src;
30 
31       while (!__libc_detect_null(*lsrc))
32 	*ldst++ = *lsrc++;
33 
34       dst = (char *)ldst;
35       src = (const char *)lsrc;
36 
37       char c0 = src[0];
38       char c1 = src[1];
39       char c2 = src[2];
40       if (!(*dst++ = c0)) return dst0;
41       if (!(*dst++ = c1)) return dst0;
42       char c3 = src[3];
43       if (!(*dst++ = c2)) return dst0;
44       if (sizeof (long) == 4) goto out;
45       char c4 = src[4];
46       if (!(*dst++ = c3)) return dst0;
47       char c5 = src[5];
48       if (!(*dst++ = c4)) return dst0;
49       char c6 = src[6];
50       if (!(*dst++ = c5)) return dst0;
51       if (!(*dst++ = c6)) return dst0;
52 
53 out:
54       *dst++ = 0;
55       return dst0;
56     }
57 #endif /* not PREFER_SIZE_OVER_SPEED */
58 
59   char ch;
60   do
61     {
62       ch = *src;
63       src++;
64       dst++;
65       *(dst - 1) = ch;
66     } while (ch);
67 
68   return dst0;
69 }
70