blob: 6519f7f349f665d9f2321b6c87beee45f8d15645 [file] [log] [blame]
Greg Ungerer982cd252011-02-03 21:58:39 +10001/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file COPYING in the main directory of this archive
4 * for more details.
5 */
6
Greg Ungerer982cd252011-02-03 21:58:39 +10007#include <linux/module.h>
8#include <linux/string.h>
9
10void *memmove(void *dest, const void *src, size_t n)
11{
12 void *xdest = dest;
13 size_t temp;
14
15 if (!n)
16 return xdest;
17
18 if (dest < src) {
19 if ((long)dest & 1) {
20 char *cdest = dest;
21 const char *csrc = src;
22 *cdest++ = *csrc++;
23 dest = cdest;
24 src = csrc;
25 n--;
26 }
27 if (n > 2 && (long)dest & 2) {
28 short *sdest = dest;
29 const short *ssrc = src;
30 *sdest++ = *ssrc++;
31 dest = sdest;
32 src = ssrc;
33 n -= 2;
34 }
35 temp = n >> 2;
36 if (temp) {
37 long *ldest = dest;
38 const long *lsrc = src;
39 temp--;
40 do
41 *ldest++ = *lsrc++;
42 while (temp--);
43 dest = ldest;
44 src = lsrc;
45 }
46 if (n & 2) {
47 short *sdest = dest;
48 const short *ssrc = src;
49 *sdest++ = *ssrc++;
50 dest = sdest;
51 src = ssrc;
52 }
53 if (n & 1) {
54 char *cdest = dest;
55 const char *csrc = src;
56 *cdest = *csrc;
57 }
58 } else {
59 dest = (char *)dest + n;
60 src = (const char *)src + n;
61 if ((long)dest & 1) {
62 char *cdest = dest;
63 const char *csrc = src;
64 *--cdest = *--csrc;
65 dest = cdest;
66 src = csrc;
67 n--;
68 }
69 if (n > 2 && (long)dest & 2) {
70 short *sdest = dest;
71 const short *ssrc = src;
72 *--sdest = *--ssrc;
73 dest = sdest;
74 src = ssrc;
75 n -= 2;
76 }
77 temp = n >> 2;
78 if (temp) {
79 long *ldest = dest;
80 const long *lsrc = src;
81 temp--;
82 do
83 *--ldest = *--lsrc;
84 while (temp--);
85 dest = ldest;
86 src = lsrc;
87 }
88 if (n & 2) {
89 short *sdest = dest;
90 const short *ssrc = src;
91 *--sdest = *--ssrc;
92 dest = sdest;
93 src = ssrc;
94 }
95 if (n & 1) {
96 char *cdest = dest;
97 const char *csrc = src;
98 *--cdest = *--csrc;
99 }
100 }
101 return xdest;
102}
103EXPORT_SYMBOL(memmove);