18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public
38c2ecf20Sopenharmony_ci * License.  See the file COPYING in the main directory of this archive
48c2ecf20Sopenharmony_ci * for more details.
58c2ecf20Sopenharmony_ci */
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ci#include <linux/module.h>
88c2ecf20Sopenharmony_ci#include <linux/string.h>
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_civoid *memmove(void *dest, const void *src, size_t n)
118c2ecf20Sopenharmony_ci{
128c2ecf20Sopenharmony_ci	void *xdest = dest;
138c2ecf20Sopenharmony_ci	size_t temp;
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci	if (!n)
168c2ecf20Sopenharmony_ci		return xdest;
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci	if (dest < src) {
198c2ecf20Sopenharmony_ci		if ((long)dest & 1) {
208c2ecf20Sopenharmony_ci			char *cdest = dest;
218c2ecf20Sopenharmony_ci			const char *csrc = src;
228c2ecf20Sopenharmony_ci			*cdest++ = *csrc++;
238c2ecf20Sopenharmony_ci			dest = cdest;
248c2ecf20Sopenharmony_ci			src = csrc;
258c2ecf20Sopenharmony_ci			n--;
268c2ecf20Sopenharmony_ci		}
278c2ecf20Sopenharmony_ci		if (n > 2 && (long)dest & 2) {
288c2ecf20Sopenharmony_ci			short *sdest = dest;
298c2ecf20Sopenharmony_ci			const short *ssrc = src;
308c2ecf20Sopenharmony_ci			*sdest++ = *ssrc++;
318c2ecf20Sopenharmony_ci			dest = sdest;
328c2ecf20Sopenharmony_ci			src = ssrc;
338c2ecf20Sopenharmony_ci			n -= 2;
348c2ecf20Sopenharmony_ci		}
358c2ecf20Sopenharmony_ci		temp = n >> 2;
368c2ecf20Sopenharmony_ci		if (temp) {
378c2ecf20Sopenharmony_ci			long *ldest = dest;
388c2ecf20Sopenharmony_ci			const long *lsrc = src;
398c2ecf20Sopenharmony_ci			temp--;
408c2ecf20Sopenharmony_ci			do
418c2ecf20Sopenharmony_ci				*ldest++ = *lsrc++;
428c2ecf20Sopenharmony_ci			while (temp--);
438c2ecf20Sopenharmony_ci			dest = ldest;
448c2ecf20Sopenharmony_ci			src = lsrc;
458c2ecf20Sopenharmony_ci		}
468c2ecf20Sopenharmony_ci		if (n & 2) {
478c2ecf20Sopenharmony_ci			short *sdest = dest;
488c2ecf20Sopenharmony_ci			const short *ssrc = src;
498c2ecf20Sopenharmony_ci			*sdest++ = *ssrc++;
508c2ecf20Sopenharmony_ci			dest = sdest;
518c2ecf20Sopenharmony_ci			src = ssrc;
528c2ecf20Sopenharmony_ci		}
538c2ecf20Sopenharmony_ci		if (n & 1) {
548c2ecf20Sopenharmony_ci			char *cdest = dest;
558c2ecf20Sopenharmony_ci			const char *csrc = src;
568c2ecf20Sopenharmony_ci			*cdest = *csrc;
578c2ecf20Sopenharmony_ci		}
588c2ecf20Sopenharmony_ci	} else {
598c2ecf20Sopenharmony_ci		dest = (char *)dest + n;
608c2ecf20Sopenharmony_ci		src = (const char *)src + n;
618c2ecf20Sopenharmony_ci		if ((long)dest & 1) {
628c2ecf20Sopenharmony_ci			char *cdest = dest;
638c2ecf20Sopenharmony_ci			const char *csrc = src;
648c2ecf20Sopenharmony_ci			*--cdest = *--csrc;
658c2ecf20Sopenharmony_ci			dest = cdest;
668c2ecf20Sopenharmony_ci			src = csrc;
678c2ecf20Sopenharmony_ci			n--;
688c2ecf20Sopenharmony_ci		}
698c2ecf20Sopenharmony_ci		if (n > 2 && (long)dest & 2) {
708c2ecf20Sopenharmony_ci			short *sdest = dest;
718c2ecf20Sopenharmony_ci			const short *ssrc = src;
728c2ecf20Sopenharmony_ci			*--sdest = *--ssrc;
738c2ecf20Sopenharmony_ci			dest = sdest;
748c2ecf20Sopenharmony_ci			src = ssrc;
758c2ecf20Sopenharmony_ci			n -= 2;
768c2ecf20Sopenharmony_ci		}
778c2ecf20Sopenharmony_ci		temp = n >> 2;
788c2ecf20Sopenharmony_ci		if (temp) {
798c2ecf20Sopenharmony_ci			long *ldest = dest;
808c2ecf20Sopenharmony_ci			const long *lsrc = src;
818c2ecf20Sopenharmony_ci			temp--;
828c2ecf20Sopenharmony_ci			do
838c2ecf20Sopenharmony_ci				*--ldest = *--lsrc;
848c2ecf20Sopenharmony_ci			while (temp--);
858c2ecf20Sopenharmony_ci			dest = ldest;
868c2ecf20Sopenharmony_ci			src = lsrc;
878c2ecf20Sopenharmony_ci		}
888c2ecf20Sopenharmony_ci		if (n & 2) {
898c2ecf20Sopenharmony_ci			short *sdest = dest;
908c2ecf20Sopenharmony_ci			const short *ssrc = src;
918c2ecf20Sopenharmony_ci			*--sdest = *--ssrc;
928c2ecf20Sopenharmony_ci			dest = sdest;
938c2ecf20Sopenharmony_ci			src = ssrc;
948c2ecf20Sopenharmony_ci		}
958c2ecf20Sopenharmony_ci		if (n & 1) {
968c2ecf20Sopenharmony_ci			char *cdest = dest;
978c2ecf20Sopenharmony_ci			const char *csrc = src;
988c2ecf20Sopenharmony_ci			*--cdest = *--csrc;
998c2ecf20Sopenharmony_ci		}
1008c2ecf20Sopenharmony_ci	}
1018c2ecf20Sopenharmony_ci	return xdest;
1028c2ecf20Sopenharmony_ci}
1038c2ecf20Sopenharmony_ciEXPORT_SYMBOL(memmove);
104