blob: 866c021f278c3e9407064abcbe1abf8410f73506 [file] [log] [blame]
Ley Foon Taneea95072014-11-06 15:20:00 +08001/*
2 * Copyright (C) 2011 Tobias Klauser <tklauser@distanz.ch>
3 * Copyright (C) 2004 Microtronix Datacom Ltd
4 *
5 * This file is subject to the terms and conditions of the GNU General Public
6 * License. See the file "COPYING" in the main directory of this archive
7 * for more details.
8 */
9
10#include <linux/types.h>
11#include <linux/string.h>
12
Ley Foon Taneea95072014-11-06 15:20:00 +080013void *memmove(void *d, const void *s, size_t count)
14{
15 unsigned long dst, src;
16
17 if (!count)
18 return d;
19
20 if (d < s) {
21 dst = (unsigned long) d;
22 src = (unsigned long) s;
23
24 if ((count < 8) || ((dst ^ src) & 3))
25 goto restup;
26
27 if (dst & 1) {
28 *(char *)dst++ = *(char *)src++;
29 count--;
30 }
31 if (dst & 2) {
32 *(short *)dst = *(short *)src;
33 src += 2;
34 dst += 2;
35 count -= 2;
36 }
37 while (count > 3) {
38 *(long *)dst = *(long *)src;
39 src += 4;
40 dst += 4;
41 count -= 4;
42 }
43restup:
44 while (count--)
45 *(char *)dst++ = *(char *)src++;
46 } else {
47 dst = (unsigned long) d + count;
48 src = (unsigned long) s + count;
49
50 if ((count < 8) || ((dst ^ src) & 3))
51 goto restdown;
52
53 if (dst & 1) {
54 src--;
55 dst--;
56 count--;
57 *(char *)dst = *(char *)src;
58 }
59 if (dst & 2) {
60 src -= 2;
61 dst -= 2;
62 count -= 2;
63 *(short *)dst = *(short *)src;
64 }
65 while (count > 3) {
66 src -= 4;
67 dst -= 4;
68 count -= 4;
69 *(long *)dst = *(long *)src;
70 }
71restdown:
72 while (count--) {
73 src--;
74 dst--;
75 *(char *)dst = *(char *)src;
76 }
77 }
78
79 return d;
80}