Merge branch 'tj-percpu' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/misc...
[linux-2.6] / arch / m68k / lib / string.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 char *strcpy(char *dest, const char *src)
13 {
14         return __kernel_strcpy(dest, src);
15 }
16 EXPORT_SYMBOL(strcpy);
17
18 char *strcat(char *dest, const char *src)
19 {
20         return __kernel_strcpy(dest + __kernel_strlen(dest), src);
21 }
22 EXPORT_SYMBOL(strcat);
23
24 void *memset(void *s, int c, size_t count)
25 {
26         void *xs = s;
27         size_t temp, temp1;
28
29         if (!count)
30                 return xs;
31         c &= 0xff;
32         c |= c << 8;
33         c |= c << 16;
34         if ((long)s & 1) {
35                 char *cs = s;
36                 *cs++ = c;
37                 s = cs;
38                 count--;
39         }
40         if (count > 2 && (long)s & 2) {
41                 short *ss = s;
42                 *ss++ = c;
43                 s = ss;
44                 count -= 2;
45         }
46         temp = count >> 2;
47         if (temp) {
48                 long *ls = s;
49
50                 asm volatile (
51                         "       movel %1,%2\n"
52                         "       andw  #7,%2\n"
53                         "       lsrl  #3,%1\n"
54                         "       negw  %2\n"
55                         "       jmp   %%pc@(2f,%2:w:2)\n"
56                         "1:     movel %3,%0@+\n"
57                         "       movel %3,%0@+\n"
58                         "       movel %3,%0@+\n"
59                         "       movel %3,%0@+\n"
60                         "       movel %3,%0@+\n"
61                         "       movel %3,%0@+\n"
62                         "       movel %3,%0@+\n"
63                         "       movel %3,%0@+\n"
64                         "2:     dbra  %1,1b\n"
65                         "       clrw  %1\n"
66                         "       subql #1,%1\n"
67                         "       jpl   1b"
68                         : "=a" (ls), "=d" (temp), "=&d" (temp1)
69                         : "d" (c), "0" (ls), "1" (temp));
70                 s = ls;
71         }
72         if (count & 2) {
73                 short *ss = s;
74                 *ss++ = c;
75                 s = ss;
76         }
77         if (count & 1) {
78                 char *cs = s;
79                 *cs = c;
80         }
81         return xs;
82 }
83 EXPORT_SYMBOL(memset);
84
85 void *memcpy(void *to, const void *from, size_t n)
86 {
87         void *xto = to;
88         size_t temp, temp1;
89
90         if (!n)
91                 return xto;
92         if ((long)to & 1) {
93                 char *cto = to;
94                 const char *cfrom = from;
95                 *cto++ = *cfrom++;
96                 to = cto;
97                 from = cfrom;
98                 n--;
99         }
100         if (n > 2 && (long)to & 2) {
101                 short *sto = to;
102                 const short *sfrom = from;
103                 *sto++ = *sfrom++;
104                 to = sto;
105                 from = sfrom;
106                 n -= 2;
107         }
108         temp = n >> 2;
109         if (temp) {
110                 long *lto = to;
111                 const long *lfrom = from;
112
113                 asm volatile (
114                         "       movel %2,%3\n"
115                         "       andw  #7,%3\n"
116                         "       lsrl  #3,%2\n"
117                         "       negw  %3\n"
118                         "       jmp   %%pc@(1f,%3:w:2)\n"
119                         "4:     movel %0@+,%1@+\n"
120                         "       movel %0@+,%1@+\n"
121                         "       movel %0@+,%1@+\n"
122                         "       movel %0@+,%1@+\n"
123                         "       movel %0@+,%1@+\n"
124                         "       movel %0@+,%1@+\n"
125                         "       movel %0@+,%1@+\n"
126                         "       movel %0@+,%1@+\n"
127                         "1:     dbra  %2,4b\n"
128                         "       clrw  %2\n"
129                         "       subql #1,%2\n"
130                         "       jpl   4b"
131                         : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
132                         : "0" (lfrom), "1" (lto), "2" (temp));
133                 to = lto;
134                 from = lfrom;
135         }
136         if (n & 2) {
137                 short *sto = to;
138                 const short *sfrom = from;
139                 *sto++ = *sfrom++;
140                 to = sto;
141                 from = sfrom;
142         }
143         if (n & 1) {
144                 char *cto = to;
145                 const char *cfrom = from;
146                 *cto = *cfrom;
147         }
148         return xto;
149 }
150 EXPORT_SYMBOL(memcpy);
151
152 void *memmove(void *dest, const void *src, size_t n)
153 {
154         void *xdest = dest;
155         size_t temp;
156
157         if (!n)
158                 return xdest;
159
160         if (dest < src) {
161                 if ((long)dest & 1) {
162                         char *cdest = dest;
163                         const char *csrc = src;
164                         *cdest++ = *csrc++;
165                         dest = cdest;
166                         src = csrc;
167                         n--;
168                 }
169                 if (n > 2 && (long)dest & 2) {
170                         short *sdest = dest;
171                         const short *ssrc = src;
172                         *sdest++ = *ssrc++;
173                         dest = sdest;
174                         src = ssrc;
175                         n -= 2;
176                 }
177                 temp = n >> 2;
178                 if (temp) {
179                         long *ldest = dest;
180                         const long *lsrc = src;
181                         temp--;
182                         do
183                                 *ldest++ = *lsrc++;
184                         while (temp--);
185                         dest = ldest;
186                         src = lsrc;
187                 }
188                 if (n & 2) {
189                         short *sdest = dest;
190                         const short *ssrc = src;
191                         *sdest++ = *ssrc++;
192                         dest = sdest;
193                         src = ssrc;
194                 }
195                 if (n & 1) {
196                         char *cdest = dest;
197                         const char *csrc = src;
198                         *cdest = *csrc;
199                 }
200         } else {
201                 dest = (char *)dest + n;
202                 src = (const char *)src + n;
203                 if ((long)dest & 1) {
204                         char *cdest = dest;
205                         const char *csrc = src;
206                         *--cdest = *--csrc;
207                         dest = cdest;
208                         src = csrc;
209                         n--;
210                 }
211                 if (n > 2 && (long)dest & 2) {
212                         short *sdest = dest;
213                         const short *ssrc = src;
214                         *--sdest = *--ssrc;
215                         dest = sdest;
216                         src = ssrc;
217                         n -= 2;
218                 }
219                 temp = n >> 2;
220                 if (temp) {
221                         long *ldest = dest;
222                         const long *lsrc = src;
223                         temp--;
224                         do
225                                 *--ldest = *--lsrc;
226                         while (temp--);
227                         dest = ldest;
228                         src = lsrc;
229                 }
230                 if (n & 2) {
231                         short *sdest = dest;
232                         const short *ssrc = src;
233                         *--sdest = *--ssrc;
234                         dest = sdest;
235                         src = ssrc;
236                 }
237                 if (n & 1) {
238                         char *cdest = dest;
239                         const char *csrc = src;
240                         *--cdest = *--csrc;
241                 }
242         }
243         return xdest;
244 }
245 EXPORT_SYMBOL(memmove);
246
247 int memcmp(const void *cs, const void *ct, size_t count)
248 {
249         const unsigned char *su1, *su2;
250
251         for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--)
252                 if (*su1 != *su2)
253                         return *su1 < *su2 ? -1 : +1;
254         return 0;
255 }
256 EXPORT_SYMBOL(memcmp);