blob: 4253f870e54fc8fe24d510bfef948c3751300a69 [file] [log] [blame]
Roman Zippeld6359fd2006-10-06 00:43:55 -07001/*
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 */
Roman Zippel072dffd2005-09-03 15:57:10 -07006
Roman Zippeld6359fd2006-10-06 00:43:55 -07007#define __IN_STRING_C
8
Roman Zippel072dffd2005-09-03 15:57:10 -07009#include <linux/module.h>
Roman Zippeld6359fd2006-10-06 00:43:55 -070010#include <linux/string.h>
11
12char *strcpy(char *dest, const char *src)
13{
14 return __kernel_strcpy(dest, src);
15}
16EXPORT_SYMBOL(strcpy);
Roman Zippel072dffd2005-09-03 15:57:10 -070017
Al Viro337e3c42008-05-21 06:32:11 +010018char *strcat(char *dest, const char *src)
19{
20 return __kernel_strcpy(dest + __kernel_strlen(dest), src);
21}
22EXPORT_SYMBOL(strcat);
23
Roman Zippel072dffd2005-09-03 15:57:10 -070024void *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}
83EXPORT_SYMBOL(memset);
84
85void *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}
150EXPORT_SYMBOL(memcpy);
151
152void *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}
245EXPORT_SYMBOL(memmove);
246
247int 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}
256EXPORT_SYMBOL(memcmp);