1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#include <linux/types.h>
28#include <linux/stddef.h>
29#include <linux/compiler.h>
30#include <linux/module.h>
31
32#include <linux/string.h>
33#include <asm/system.h>
34
35#ifdef __HAVE_ARCH_MEMCPY
36#ifndef CONFIG_OPT_LIB_FUNCTION
37void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
38{
39 const char *src = v_src;
40 char *dst = v_dst;
41
42
43 while (c--)
44 *dst++ = *src++;
45
46 return v_dst;
47}
48#else
49void *memcpy(void *v_dst, const void *v_src, __kernel_size_t c)
50{
51 const char *src = v_src;
52 char *dst = v_dst;
53
54
55
56
57
58
59
60 const uint32_t *i_src;
61 uint32_t *i_dst;
62
63 if (likely(c >= 4)) {
64 unsigned value, buf_hold;
65
66
67
68 switch ((unsigned long)dst & 3) {
69 case 1:
70 *dst++ = *src++;
71 --c;
72 case 2:
73 *dst++ = *src++;
74 --c;
75 case 3:
76 *dst++ = *src++;
77 --c;
78 }
79
80 i_dst = (void *)dst;
81
82
83
84 switch ((unsigned long)src & 3) {
85 case 0x0:
86 i_src = (const void *)src;
87
88 for (; c >= 4; c -= 4)
89 *i_dst++ = *i_src++;
90
91 src = (const void *)i_src;
92 break;
93 case 0x1:
94
95 i_src = (const void *) ((unsigned)src & ~3);
96#ifndef __MICROBLAZEEL__
97
98 buf_hold = *i_src++ << 8;
99
100 for (; c >= 4; c -= 4) {
101 value = *i_src++;
102 *i_dst++ = buf_hold | value >> 24;
103 buf_hold = value << 8;
104 }
105#else
106
107 buf_hold = (*i_src++ & 0xFFFFFF00) >>8;
108
109 for (; c >= 4; c -= 4) {
110 value = *i_src++;
111 *i_dst++ = buf_hold | ((value & 0xFF) << 24);
112 buf_hold = (value & 0xFFFFFF00) >>8;
113 }
114#endif
115
116 src = (const void *)i_src;
117 src -= 3;
118 break;
119 case 0x2:
120
121 i_src = (const void *) ((unsigned)src & ~3);
122#ifndef __MICROBLAZEEL__
123
124 buf_hold = *i_src++ << 16;
125
126 for (; c >= 4; c -= 4) {
127 value = *i_src++;
128 *i_dst++ = buf_hold | value >> 16;
129 buf_hold = value << 16;
130 }
131#else
132
133 buf_hold = (*i_src++ & 0xFFFF0000 )>>16;
134
135 for (; c >= 4; c -= 4) {
136 value = *i_src++;
137 *i_dst++ = buf_hold | ((value & 0xFFFF)<<16);
138 buf_hold = (value & 0xFFFF0000) >>16;
139 }
140#endif
141
142 src = (const void *)i_src;
143 src -= 2;
144 break;
145 case 0x3:
146
147 i_src = (const void *) ((unsigned)src & ~3);
148#ifndef __MICROBLAZEEL__
149
150 buf_hold = *i_src++ << 24;
151
152 for (; c >= 4; c -= 4) {
153 value = *i_src++;
154 *i_dst++ = buf_hold | value >> 8;
155 buf_hold = value << 24;
156 }
157#else
158
159 buf_hold = (*i_src++ & 0xFF000000) >> 24;
160
161 for (; c >= 4; c -= 4) {
162 value = *i_src++;
163 *i_dst++ = buf_hold | ((value & 0xFFFFFF) << 8);
164 buf_hold = (value & 0xFF000000) >> 24;
165 }
166#endif
167
168 src = (const void *)i_src;
169 src -= 1;
170 break;
171 }
172 dst = (void *)i_dst;
173 }
174
175
176
177 switch (c) {
178 case 3:
179 *dst++ = *src++;
180 case 2:
181 *dst++ = *src++;
182 case 1:
183 *dst++ = *src++;
184 }
185
186 return v_dst;
187}
188#endif
189EXPORT_SYMBOL(memcpy);
190#endif
191