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