Pull misc-2.6.39 into release branch
[pandora-kernel.git] / arch / m68knommu / lib / memmove.c
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 #define __IN_STRING_C
8
9 #include <linux/module.h>
10 #include <linux/string.h>
11
12 void *memmove(void *dest, const void *src, size_t n)
13 {
14         void *xdest = dest;
15         size_t temp;
16
17         if (!n)
18                 return xdest;
19
20         if (dest < src) {
21                 if ((long)dest & 1) {
22                         char *cdest = dest;
23                         const char *csrc = src;
24                         *cdest++ = *csrc++;
25                         dest = cdest;
26                         src = csrc;
27                         n--;
28                 }
29                 if (n > 2 && (long)dest & 2) {
30                         short *sdest = dest;
31                         const short *ssrc = src;
32                         *sdest++ = *ssrc++;
33                         dest = sdest;
34                         src = ssrc;
35                         n -= 2;
36                 }
37                 temp = n >> 2;
38                 if (temp) {
39                         long *ldest = dest;
40                         const long *lsrc = src;
41                         temp--;
42                         do
43                                 *ldest++ = *lsrc++;
44                         while (temp--);
45                         dest = ldest;
46                         src = lsrc;
47                 }
48                 if (n & 2) {
49                         short *sdest = dest;
50                         const short *ssrc = src;
51                         *sdest++ = *ssrc++;
52                         dest = sdest;
53                         src = ssrc;
54                 }
55                 if (n & 1) {
56                         char *cdest = dest;
57                         const char *csrc = src;
58                         *cdest = *csrc;
59                 }
60         } else {
61                 dest = (char *)dest + n;
62                 src = (const char *)src + n;
63                 if ((long)dest & 1) {
64                         char *cdest = dest;
65                         const char *csrc = src;
66                         *--cdest = *--csrc;
67                         dest = cdest;
68                         src = csrc;
69                         n--;
70                 }
71                 if (n > 2 && (long)dest & 2) {
72                         short *sdest = dest;
73                         const short *ssrc = src;
74                         *--sdest = *--ssrc;
75                         dest = sdest;
76                         src = ssrc;
77                         n -= 2;
78                 }
79                 temp = n >> 2;
80                 if (temp) {
81                         long *ldest = dest;
82                         const long *lsrc = src;
83                         temp--;
84                         do
85                                 *--ldest = *--lsrc;
86                         while (temp--);
87                         dest = ldest;
88                         src = lsrc;
89                 }
90                 if (n & 2) {
91                         short *sdest = dest;
92                         const short *ssrc = src;
93                         *--sdest = *--ssrc;
94                         dest = sdest;
95                         src = ssrc;
96                 }
97                 if (n & 1) {
98                         char *cdest = dest;
99                         const char *csrc = src;
100                         *--cdest = *--csrc;
101                 }
102         }
103         return xdest;
104 }
105 EXPORT_SYMBOL(memmove);