These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / nios2 / lib / memmove.c
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
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 }