Commit | Line | Data |
---|---|---|
eea9507a LFT |
1 | /* |
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 | ||
eea9507a LFT |
13 | void *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 | } | |
43 | restup: | |
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 | } | |
71 | restdown: | |
72 | while (count--) { | |
73 | src--; | |
74 | dst--; | |
75 | *(char *)dst = *(char *)src; | |
76 | } | |
77 | } | |
78 | ||
79 | return d; | |
80 | } |