1 /*
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 
7 #include <linux/module.h>
8 #include <linux/string.h>
9 
memmove(void * dest,const void * src,size_t n)10 void *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 }
103 EXPORT_SYMBOL(memmove);
104