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