xref: /linux/arch/m68k/lib/memmove.c (revision ca220141fa8ebae09765a242076b2b77338106b0)
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 
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 defined(CONFIG_M68000)
28 		if ((long)src & 1) {
29 			char *cdest = dest;
30 			const char *csrc = src;
31 			for (; n; n--)
32 				*cdest++ = *csrc++;
33 			return xdest;
34 		}
35 #endif
36 		if (n > 2 && (long)dest & 2) {
37 			short *sdest = dest;
38 			const short *ssrc = src;
39 			*sdest++ = *ssrc++;
40 			dest = sdest;
41 			src = ssrc;
42 			n -= 2;
43 		}
44 		temp = n >> 2;
45 		if (temp) {
46 			long *ldest = dest;
47 			const long *lsrc = src;
48 			temp--;
49 			do
50 				*ldest++ = *lsrc++;
51 			while (temp--);
52 			dest = ldest;
53 			src = lsrc;
54 		}
55 		if (n & 2) {
56 			short *sdest = dest;
57 			const short *ssrc = src;
58 			*sdest++ = *ssrc++;
59 			dest = sdest;
60 			src = ssrc;
61 		}
62 		if (n & 1) {
63 			char *cdest = dest;
64 			const char *csrc = src;
65 			*cdest = *csrc;
66 		}
67 	} else {
68 		dest = (char *)dest + n;
69 		src = (const char *)src + n;
70 		if ((long)dest & 1) {
71 			char *cdest = dest;
72 			const char *csrc = src;
73 			*--cdest = *--csrc;
74 			dest = cdest;
75 			src = csrc;
76 			n--;
77 		}
78 #if defined(CONFIG_M68000)
79 		if ((long)src & 1) {
80 			char *cdest = dest;
81 			const char *csrc = src;
82 			for (; n; n--)
83 				*--cdest = *--csrc;
84 			return xdest;
85 		}
86 #endif
87 		if (n > 2 && (long)dest & 2) {
88 			short *sdest = dest;
89 			const short *ssrc = src;
90 			*--sdest = *--ssrc;
91 			dest = sdest;
92 			src = ssrc;
93 			n -= 2;
94 		}
95 		temp = n >> 2;
96 		if (temp) {
97 			long *ldest = dest;
98 			const long *lsrc = src;
99 			temp--;
100 			do
101 				*--ldest = *--lsrc;
102 			while (temp--);
103 			dest = ldest;
104 			src = lsrc;
105 		}
106 		if (n & 2) {
107 			short *sdest = dest;
108 			const short *ssrc = src;
109 			*--sdest = *--ssrc;
110 			dest = sdest;
111 			src = ssrc;
112 		}
113 		if (n & 1) {
114 			char *cdest = dest;
115 			const char *csrc = src;
116 			*--cdest = *--csrc;
117 		}
118 	}
119 	return xdest;
120 }
121 EXPORT_SYMBOL(memmove);
122