1 /*
2 FUNCTION
3 <<memcpy>>---copy memory regions
4
5 ANSI_SYNOPSIS
6 #include <string.h>
7 void* memcpy(void *restrict <[out]>, const void *restrict <[in]>,
8 size_t <[n]>);
9
10 TRAD_SYNOPSIS
11 #include <string.h>
12 void *memcpy(<[out]>, <[in]>, <[n]>
13 void *<[out]>;
14 void *<[in]>;
15 size_t <[n]>;
16
17 DESCRIPTION
18 This function copies <[n]> bytes from the memory region
19 pointed to by <[in]> to the memory region pointed to by
20 <[out]>.
21
22 If the regions overlap, the behavior is undefined.
23
24 RETURNS
25 <<memcpy>> returns a pointer to the first byte of the <[out]>
26 region.
27
28 PORTABILITY
29 <<memcpy>> is ANSI C.
30
31 <<memcpy>> requires no supporting OS subroutines.
32
33 QUICKREF
34 memcpy ansi pure
35 */
36
37 #include <section_config.h>
38 #include <basic_types.h>
39
40 #include <_ansi.h>
41 #include <string.h>
42
43 /* Nonzero if either X or Y is not aligned on a "long" boundary. */
44 #define UNALIGNED(X, Y) \
45 (((long)X & (sizeof (long) - 1)) | ((long)Y & (sizeof (long) - 1)))
46
47 /* How many bytes are copied each iteration of the 4X unrolled loop. */
48 #define BIGBLOCKSIZE (sizeof (long) << 2)
49
50 /* How many bytes are copied each iteration of the word copy loop. */
51 #define LITTLEBLOCKSIZE (sizeof (long))
52
53 /* Threshhold for punting to the byte copier. */
54 #define TOO_SMALL(LEN) ((LEN) < BIGBLOCKSIZE)
55
56 LIBC_ROM_TEXT_SECTION
57 _LONG_CALL_
_memcpy(void * __restrict dst0,const void * __restrict src0,size_t len0)58 void * _memcpy(void * __restrict dst0 , const void * __restrict src0 , size_t len0)
59 {
60 #if defined(PREFER_SIZE_OVER_SPEED)
61 char *dst = (char *) dst0;
62 char *src = (char *) src0;
63
64 void * save = dst0;
65
66 while (len0--)
67 {
68 *dst++ = *src++;
69 }
70
71 return save;
72 #else
73 char *dst = dst0;
74 const char *src = src0;
75 long *aligned_dst;
76 const long *aligned_src;
77
78 /* If the size is small, or either SRC or DST is unaligned,
79 then punt into the byte copy loop. This should be rare. */
80 if (!TOO_SMALL(len0) && !UNALIGNED (src, dst))
81 {
82 aligned_dst = (long*)dst;
83 aligned_src = (long*)src;
84
85 /* Copy 4X long words at a time if possible. */
86 while (len0 >= BIGBLOCKSIZE)
87 {
88 *aligned_dst++ = *aligned_src++;
89 *aligned_dst++ = *aligned_src++;
90 *aligned_dst++ = *aligned_src++;
91 *aligned_dst++ = *aligned_src++;
92 len0 -= BIGBLOCKSIZE;
93 }
94
95 /* Copy one long word at a time if possible. */
96 while (len0 >= LITTLEBLOCKSIZE)
97 {
98 *aligned_dst++ = *aligned_src++;
99 len0 -= LITTLEBLOCKSIZE;
100 }
101
102 /* Pick up any residual with a byte copier. */
103 dst = (char*)aligned_dst;
104 src = (char*)aligned_src;
105 }
106
107 while (len0--)
108 *dst++ = *src++;
109
110 return dst0;
111 #endif /* not PREFER_SIZE_OVER_SPEED */
112 }
113