1
2
3
4
5
6
7
8
9
10#include <linux/types.h>
11#include <linux/string.h>
12
13#ifdef __HAVE_ARCH_MEMMOVE
14void *memmove(void *d, const void *s, size_t count)
15{
16 unsigned long dst, src;
17
18 if (!count)
19 return d;
20
21 if (d < s) {
22 dst = (unsigned long) d;
23 src = (unsigned long) s;
24
25 if ((count < 8) || ((dst ^ src) & 3))
26 goto restup;
27
28 if (dst & 1) {
29 *(char *)dst++ = *(char *)src++;
30 count--;
31 }
32 if (dst & 2) {
33 *(short *)dst = *(short *)src;
34 src += 2;
35 dst += 2;
36 count -= 2;
37 }
38 while (count > 3) {
39 *(long *)dst = *(long *)src;
40 src += 4;
41 dst += 4;
42 count -= 4;
43 }
44restup:
45 while (count--)
46 *(char *)dst++ = *(char *)src++;
47 } else {
48 dst = (unsigned long) d + count;
49 src = (unsigned long) s + count;
50
51 if ((count < 8) || ((dst ^ src) & 3))
52 goto restdown;
53
54 if (dst & 1) {
55 src--;
56 dst--;
57 count--;
58 *(char *)dst = *(char *)src;
59 }
60 if (dst & 2) {
61 src -= 2;
62 dst -= 2;
63 count -= 2;
64 *(short *)dst = *(short *)src;
65 }
66 while (count > 3) {
67 src -= 4;
68 dst -= 4;
69 count -= 4;
70 *(long *)dst = *(long *)src;
71 }
72restdown:
73 while (count--) {
74 src--;
75 dst--;
76 *(char *)dst = *(char *)src;
77 }
78 }
79
80 return d;
81}
82#endif
83