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