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
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);
104