blob: 891e1347bc4e4c1de3d0455d40905dce19992b08 [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
18void *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}
77EXPORT_SYMBOL(memset);
78
79void *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}
144EXPORT_SYMBOL(memcpy);
145
146void *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}
239EXPORT_SYMBOL(memmove);
240
241int 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}
250EXPORT_SYMBOL(memcmp);