aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoman Zippel <zippel@linux-m68k.org>2005-09-03 18:57:10 -0400
committerLinus Torvalds <torvalds@evo.osdl.org>2005-09-05 03:06:19 -0400
commit072dffda1d35c391fe893ec9b1d098145e668fef (patch)
tree2eee1530619abb7cf751db022216ab483e6fc823
parent2855b97020f6d4a4dfb005fb77c0b79c8cb9d13f (diff)
[PATCH] m68k: cleanup inline mem functions
Use the builtin functions for memset/memclr/memcpy, special optimizations for page operations have dedicated functions now. Uninline memmove/memchr and move all functions into a single file and clean it up a little. Signed-off-by: Roman Zippel <zippel@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c4
-rw-r--r--arch/m68k/lib/Makefile2
-rw-r--r--arch/m68k/lib/memcmp.c11
-rw-r--r--arch/m68k/lib/memcpy.c75
-rw-r--r--arch/m68k/lib/memset.c68
-rw-r--r--arch/m68k/lib/string.c237
-rw-r--r--include/asm-m68k/string.h403
7 files changed, 245 insertions, 555 deletions
diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c
index fe837e31afbf..73e2f5e168dd 100644
--- a/arch/m68k/kernel/m68k_ksyms.c
+++ b/arch/m68k/kernel/m68k_ksyms.c
@@ -74,10 +74,6 @@ EXPORT_SYMBOL(vme_brdtype);
74EXPORT_SYMBOL(__ashldi3); 74EXPORT_SYMBOL(__ashldi3);
75EXPORT_SYMBOL(__ashrdi3); 75EXPORT_SYMBOL(__ashrdi3);
76EXPORT_SYMBOL(__lshrdi3); 76EXPORT_SYMBOL(__lshrdi3);
77EXPORT_SYMBOL(memcpy);
78EXPORT_SYMBOL(memset);
79EXPORT_SYMBOL(memcmp);
80EXPORT_SYMBOL(memscan);
81EXPORT_SYMBOL(__muldi3); 77EXPORT_SYMBOL(__muldi3);
82 78
83EXPORT_SYMBOL(__down_failed); 79EXPORT_SYMBOL(__down_failed);
diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile
index 34b6dbc29c85..ebe51a513817 100644
--- a/arch/m68k/lib/Makefile
+++ b/arch/m68k/lib/Makefile
@@ -5,4 +5,4 @@
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ 7lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
8 checksum.o memcmp.o memcpy.o memset.o semaphore.o 8 checksum.o string.o semaphore.o
diff --git a/arch/m68k/lib/memcmp.c b/arch/m68k/lib/memcmp.c
deleted file mode 100644
index f4796febb773..000000000000
--- a/arch/m68k/lib/memcmp.c
+++ /dev/null
@@ -1,11 +0,0 @@
1#include <linux/types.h>
2
3int memcmp(const void * cs,const void * ct,size_t count)
4{
5 const unsigned char *su1, *su2;
6
7 for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
8 if (*su1 != *su2)
9 return((*su1 < *su2) ? -1 : +1);
10 return(0);
11}
diff --git a/arch/m68k/lib/memcpy.c b/arch/m68k/lib/memcpy.c
deleted file mode 100644
index 73e181823d9b..000000000000
--- a/arch/m68k/lib/memcpy.c
+++ /dev/null
@@ -1,75 +0,0 @@
1#include <linux/types.h>
2
3void * memcpy(void * to, const void * from, size_t n)
4{
5 void *xto = to;
6 size_t temp, temp1;
7
8 if (!n)
9 return xto;
10 if ((long) to & 1)
11 {
12 char *cto = to;
13 const char *cfrom = from;
14 *cto++ = *cfrom++;
15 to = cto;
16 from = cfrom;
17 n--;
18 }
19 if (n > 2 && (long) to & 2)
20 {
21 short *sto = to;
22 const short *sfrom = from;
23 *sto++ = *sfrom++;
24 to = sto;
25 from = sfrom;
26 n -= 2;
27 }
28 temp = n >> 2;
29 if (temp)
30 {
31 long *lto = to;
32 const long *lfrom = from;
33
34 __asm__ __volatile__("movel %2,%3\n\t"
35 "andw #7,%3\n\t"
36 "lsrl #3,%2\n\t"
37 "negw %3\n\t"
38 "jmp %%pc@(1f,%3:w:2)\n\t"
39 "4:\t"
40 "movel %0@+,%1@+\n\t"
41 "movel %0@+,%1@+\n\t"
42 "movel %0@+,%1@+\n\t"
43 "movel %0@+,%1@+\n\t"
44 "movel %0@+,%1@+\n\t"
45 "movel %0@+,%1@+\n\t"
46 "movel %0@+,%1@+\n\t"
47 "movel %0@+,%1@+\n\t"
48 "1:\t"
49 "dbra %2,4b\n\t"
50 "clrw %2\n\t"
51 "subql #1,%2\n\t"
52 "jpl 4b\n\t"
53 : "=a" (lfrom), "=a" (lto), "=d" (temp),
54 "=&d" (temp1)
55 : "0" (lfrom), "1" (lto), "2" (temp)
56 );
57 to = lto;
58 from = lfrom;
59 }
60 if (n & 2)
61 {
62 short *sto = to;
63 const short *sfrom = from;
64 *sto++ = *sfrom++;
65 to = sto;
66 from = sfrom;
67 }
68 if (n & 1)
69 {
70 char *cto = to;
71 const char *cfrom = from;
72 *cto = *cfrom;
73 }
74 return xto;
75}
diff --git a/arch/m68k/lib/memset.c b/arch/m68k/lib/memset.c
deleted file mode 100644
index d55fdb2ee9d3..000000000000
--- a/arch/m68k/lib/memset.c
+++ /dev/null
@@ -1,68 +0,0 @@
1#include <linux/types.h>
2
3void * memset(void * s, int c, size_t count)
4{
5 void *xs = s;
6 size_t temp, temp1;
7
8 if (!count)
9 return xs;
10 c &= 0xff;
11 c |= c << 8;
12 c |= c << 16;
13 if ((long) s & 1)
14 {
15 char *cs = s;
16 *cs++ = c;
17 s = cs;
18 count--;
19 }
20 if (count > 2 && (long) s & 2)
21 {
22 short *ss = s;
23 *ss++ = c;
24 s = ss;
25 count -= 2;
26 }
27 temp = count >> 2;
28 if (temp)
29 {
30 long *ls = s;
31
32 __asm__ __volatile__("movel %1,%2\n\t"
33 "andw #7,%2\n\t"
34 "lsrl #3,%1\n\t"
35 "negw %2\n\t"
36 "jmp %%pc@(2f,%2:w:2)\n\t"
37 "1:\t"
38 "movel %3,%0@+\n\t"
39 "movel %3,%0@+\n\t"
40 "movel %3,%0@+\n\t"
41 "movel %3,%0@+\n\t"
42 "movel %3,%0@+\n\t"
43 "movel %3,%0@+\n\t"
44 "movel %3,%0@+\n\t"
45 "movel %3,%0@+\n\t"
46 "2:\t"
47 "dbra %1,1b\n\t"
48 "clrw %1\n\t"
49 "subql #1,%1\n\t"
50 "jpl 1b\n\t"
51 : "=a" (ls), "=d" (temp), "=&d" (temp1)
52 : "d" (c), "0" (ls), "1" (temp)
53 );
54 s = ls;
55 }
56 if (count & 2)
57 {
58 short *ss = s;
59 *ss++ = c;
60 s = ss;
61 }
62 if (count & 1)
63 {
64 char *cs = s;
65 *cs = c;
66 }
67 return xs;
68}
diff --git a/arch/m68k/lib/string.c b/arch/m68k/lib/string.c
new file mode 100644
index 000000000000..b92b89e1ea0c
--- /dev/null
+++ b/arch/m68k/lib/string.c
@@ -0,0 +1,237 @@
1
2#include <linux/types.h>
3#include <linux/module.h>
4
5void *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}
64EXPORT_SYMBOL(memset);
65
66void *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}
131EXPORT_SYMBOL(memcpy);
132
133void *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}
226EXPORT_SYMBOL(memmove);
227
228int 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}
237EXPORT_SYMBOL(memcmp);
diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h
index 44def078132a..6c59215b285e 100644
--- a/include/asm-m68k/string.h
+++ b/include/asm-m68k/string.h
@@ -80,43 +80,6 @@ static inline char * strchr(const char * s, int c)
80 return( (char *) s); 80 return( (char *) s);
81} 81}
82 82
83#if 0
84#define __HAVE_ARCH_STRPBRK
85static inline char *strpbrk(const char *cs,const char *ct)
86{
87 const char *sc1,*sc2;
88
89 for( sc1 = cs; *sc1 != '\0'; ++sc1)
90 for( sc2 = ct; *sc2 != '\0'; ++sc2)
91 if (*sc1 == *sc2)
92 return((char *) sc1);
93 return( NULL );
94}
95#endif
96
97#if 0
98#define __HAVE_ARCH_STRSPN
99static inline size_t strspn(const char *s, const char *accept)
100{
101 const char *p;
102 const char *a;
103 size_t count = 0;
104
105 for (p = s; *p != '\0'; ++p)
106 {
107 for (a = accept; *a != '\0'; ++a)
108 if (*p == *a)
109 break;
110 if (*a == '\0')
111 return count;
112 else
113 ++count;
114 }
115
116 return count;
117}
118#endif
119
120/* strstr !! */ 83/* strstr !! */
121 84
122#define __HAVE_ARCH_STRLEN 85#define __HAVE_ARCH_STRLEN
@@ -173,370 +136,18 @@ static inline int strncmp(const char * cs,const char * ct,size_t count)
173} 136}
174 137
175#define __HAVE_ARCH_MEMSET 138#define __HAVE_ARCH_MEMSET
176/* 139extern void *memset(void *, int, __kernel_size_t);
177 * This is really ugly, but its highly optimizatiable by the 140#define memset(d, c, n) __builtin_memset(d, c, n)
178 * compiler and is meant as compensation for gcc's missing
179 * __builtin_memset(). For the 680[23]0 it might be worth considering
180 * the optimal number of misaligned writes compared to the number of
181 * tests'n'branches needed to align the destination address. The
182 * 680[46]0 doesn't really care due to their copy-back caches.
183 * 10/09/96 - Jes Sorensen
184 */
185static inline void * __memset_g(void * s, int c, size_t count)
186{
187 void *xs = s;
188 size_t temp;
189
190 if (!count)
191 return xs;
192
193 c &= 0xff;
194 c |= c << 8;
195 c |= c << 16;
196
197 if (count < 36){
198 long *ls = s;
199
200 switch(count){
201 case 32: case 33: case 34: case 35:
202 *ls++ = c;
203 case 28: case 29: case 30: case 31:
204 *ls++ = c;
205 case 24: case 25: case 26: case 27:
206 *ls++ = c;
207 case 20: case 21: case 22: case 23:
208 *ls++ = c;
209 case 16: case 17: case 18: case 19:
210 *ls++ = c;
211 case 12: case 13: case 14: case 15:
212 *ls++ = c;
213 case 8: case 9: case 10: case 11:
214 *ls++ = c;
215 case 4: case 5: case 6: case 7:
216 *ls++ = c;
217 break;
218 default:
219 break;
220 }
221 s = ls;
222 if (count & 0x02){
223 short *ss = s;
224 *ss++ = c;
225 s = ss;
226 }
227 if (count & 0x01){
228 char *cs = s;
229 *cs++ = c;
230 s = cs;
231 }
232 return xs;
233 }
234
235 if ((long) s & 1)
236 {
237 char *cs = s;
238 *cs++ = c;
239 s = cs;
240 count--;
241 }
242 if (count > 2 && (long) s & 2)
243 {
244 short *ss = s;
245 *ss++ = c;
246 s = ss;
247 count -= 2;
248 }
249 temp = count >> 2;
250 if (temp)
251 {
252 long *ls = s;
253 temp--;
254 do
255 *ls++ = c;
256 while (temp--);
257 s = ls;
258 }
259 if (count & 2)
260 {
261 short *ss = s;
262 *ss++ = c;
263 s = ss;
264 }
265 if (count & 1)
266 {
267 char *cs = s;
268 *cs = c;
269 }
270 return xs;
271}
272
273/*
274 * __memset_page assumes that data is longword aligned. Most, if not
275 * all, of these page sized memsets are performed on page aligned
276 * areas, thus we do not need to check if the destination is longword
277 * aligned. Of course we suffer a serious performance loss if this is
278 * not the case but I think the risk of this ever happening is
279 * extremely small. We spend a lot of time clearing pages in
280 * get_empty_page() so I think it is worth it anyway. Besides, the
281 * 680[46]0 do not really care about misaligned writes due to their
282 * copy-back cache.
283 *
284 * The optimized case for the 680[46]0 is implemented using the move16
285 * instruction. My tests showed that this implementation is 35-45%
286 * faster than the original implementation using movel, the only
287 * caveat is that the destination address must be 16-byte aligned.
288 * 01/09/96 - Jes Sorensen
289 */
290static inline void * __memset_page(void * s,int c,size_t count)
291{
292 unsigned long data, tmp;
293 void *xs = s;
294
295 c = c & 255;
296 data = c | (c << 8);
297 data |= data << 16;
298
299#ifdef CPU_M68040_OR_M68060_ONLY
300
301 if (((unsigned long) s) & 0x0f)
302 __memset_g(s, c, count);
303 else{
304 unsigned long *sp = s;
305 *sp++ = data;
306 *sp++ = data;
307 *sp++ = data;
308 *sp++ = data;
309
310 __asm__ __volatile__("1:\t"
311 ".chip 68040\n\t"
312 "move16 %2@+,%0@+\n\t"
313 ".chip 68k\n\t"
314 "subqw #8,%2\n\t"
315 "subqw #8,%2\n\t"
316 "dbra %1,1b\n\t"
317 : "=a" (sp), "=d" (tmp)
318 : "a" (s), "0" (sp), "1" ((count - 16) / 16 - 1)
319 );
320 }
321
322#else
323 __asm__ __volatile__("1:\t"
324 "movel %2,%0@+\n\t"
325 "movel %2,%0@+\n\t"
326 "movel %2,%0@+\n\t"
327 "movel %2,%0@+\n\t"
328 "movel %2,%0@+\n\t"
329 "movel %2,%0@+\n\t"
330 "movel %2,%0@+\n\t"
331 "movel %2,%0@+\n\t"
332 "dbra %1,1b\n\t"
333 : "=a" (s), "=d" (tmp)
334 : "d" (data), "0" (s), "1" (count / 32 - 1)
335 );
336#endif
337
338 return xs;
339}
340
341extern void *memset(void *,int,__kernel_size_t);
342
343#define __memset_const(s,c,count) \
344((count==PAGE_SIZE) ? \
345 __memset_page((s),(c),(count)) : \
346 __memset_g((s),(c),(count)))
347
348#define memset(s, c, count) \
349(__builtin_constant_p(count) ? \
350 __memset_const((s),(c),(count)) : \
351 __memset_g((s),(c),(count)))
352 141
353#define __HAVE_ARCH_MEMCPY 142#define __HAVE_ARCH_MEMCPY
354extern void * memcpy(void *, const void *, size_t ); 143extern void *memcpy(void *, const void *, __kernel_size_t);
355/* 144#define memcpy(d, s, n) __builtin_memcpy(d, s, n)
356 * __builtin_memcpy() does not handle page-sized memcpys very well,
357 * thus following the same assumptions as for page-sized memsets, this
358 * function copies page-sized areas using an unrolled loop, without
359 * considering alignment.
360 *
361 * For the 680[46]0 only kernels we use the move16 instruction instead
362 * as it writes through the data-cache, invalidating the cache-lines
363 * touched. In this way we do not use up the entire data-cache (well,
364 * half of it on the 68060) by copying a page. An unrolled loop of two
365 * move16 instructions seem to the fastest. The only caveat is that
366 * both source and destination must be 16-byte aligned, if not we fall
367 * back to the generic memcpy function. - Jes
368 */
369static inline void * __memcpy_page(void * to, const void * from, size_t count)
370{
371 unsigned long tmp;
372 void *xto = to;
373
374#ifdef CPU_M68040_OR_M68060_ONLY
375
376 if (((unsigned long) to | (unsigned long) from) & 0x0f)
377 return memcpy(to, from, count);
378
379 __asm__ __volatile__("1:\t"
380 ".chip 68040\n\t"
381 "move16 %1@+,%0@+\n\t"
382 "move16 %1@+,%0@+\n\t"
383 ".chip 68k\n\t"
384 "dbra %2,1b\n\t"
385 : "=a" (to), "=a" (from), "=d" (tmp)
386 : "0" (to), "1" (from) , "2" (count / 32 - 1)
387 );
388#else
389 __asm__ __volatile__("1:\t"
390 "movel %1@+,%0@+\n\t"
391 "movel %1@+,%0@+\n\t"
392 "movel %1@+,%0@+\n\t"
393 "movel %1@+,%0@+\n\t"
394 "movel %1@+,%0@+\n\t"
395 "movel %1@+,%0@+\n\t"
396 "movel %1@+,%0@+\n\t"
397 "movel %1@+,%0@+\n\t"
398 "dbra %2,1b\n\t"
399 : "=a" (to), "=a" (from), "=d" (tmp)
400 : "0" (to), "1" (from) , "2" (count / 32 - 1)
401 );
402#endif
403 return xto;
404}
405
406#define __memcpy_const(to, from, n) \
407((n==PAGE_SIZE) ? \
408 __memcpy_page((to),(from),(n)) : \
409 __builtin_memcpy((to),(from),(n)))
410
411#define memcpy(to, from, n) \
412(__builtin_constant_p(n) ? \
413 __memcpy_const((to),(from),(n)) : \
414 memcpy((to),(from),(n)))
415 145
416#define __HAVE_ARCH_MEMMOVE 146#define __HAVE_ARCH_MEMMOVE
417static inline void * memmove(void * dest,const void * src, size_t n) 147extern void *memmove(void *, const void *, __kernel_size_t);
418{
419 void *xdest = dest;
420 size_t temp;
421
422 if (!n)
423 return xdest;
424
425 if (dest < src)
426 {
427 if ((long) dest & 1)
428 {
429 char *cdest = dest;
430 const char *csrc = src;
431 *cdest++ = *csrc++;
432 dest = cdest;
433 src = csrc;
434 n--;
435 }
436 if (n > 2 && (long) dest & 2)
437 {
438 short *sdest = dest;
439 const short *ssrc = src;
440 *sdest++ = *ssrc++;
441 dest = sdest;
442 src = ssrc;
443 n -= 2;
444 }
445 temp = n >> 2;
446 if (temp)
447 {
448 long *ldest = dest;
449 const long *lsrc = src;
450 temp--;
451 do
452 *ldest++ = *lsrc++;
453 while (temp--);
454 dest = ldest;
455 src = lsrc;
456 }
457 if (n & 2)
458 {
459 short *sdest = dest;
460 const short *ssrc = src;
461 *sdest++ = *ssrc++;
462 dest = sdest;
463 src = ssrc;
464 }
465 if (n & 1)
466 {
467 char *cdest = dest;
468 const char *csrc = src;
469 *cdest = *csrc;
470 }
471 }
472 else
473 {
474 dest = (char *) dest + n;
475 src = (const char *) src + n;
476 if ((long) dest & 1)
477 {
478 char *cdest = dest;
479 const char *csrc = src;
480 *--cdest = *--csrc;
481 dest = cdest;
482 src = csrc;
483 n--;
484 }
485 if (n > 2 && (long) dest & 2)
486 {
487 short *sdest = dest;
488 const short *ssrc = src;
489 *--sdest = *--ssrc;
490 dest = sdest;
491 src = ssrc;
492 n -= 2;
493 }
494 temp = n >> 2;
495 if (temp)
496 {
497 long *ldest = dest;
498 const long *lsrc = src;
499 temp--;
500 do
501 *--ldest = *--lsrc;
502 while (temp--);
503 dest = ldest;
504 src = lsrc;
505 }
506 if (n & 2)
507 {
508 short *sdest = dest;
509 const short *ssrc = src;
510 *--sdest = *--ssrc;
511 dest = sdest;
512 src = ssrc;
513 }
514 if (n & 1)
515 {
516 char *cdest = dest;
517 const char *csrc = src;
518 *--cdest = *--csrc;
519 }
520 }
521 return xdest;
522}
523 148
524#define __HAVE_ARCH_MEMCMP 149#define __HAVE_ARCH_MEMCMP
525extern int memcmp(const void * ,const void * ,size_t ); 150extern int memcmp(const void *, const void *, __kernel_size_t);
526#define memcmp(cs, ct, n) \ 151#define memcmp(d, s, n) __builtin_memcmp(d, s, n)
527(__builtin_constant_p(n) ? \
528 __builtin_memcmp((cs),(ct),(n)) : \
529 memcmp((cs),(ct),(n)))
530
531#define __HAVE_ARCH_MEMCHR
532static inline void *memchr(const void *cs, int c, size_t count)
533{
534 /* Someone else can optimize this, I don't care - tonym@mac.linux-m68k.org */
535 unsigned char *ret = (unsigned char *)cs;
536 for(;count>0;count--,ret++)
537 if(*ret == c) return ret;
538
539 return NULL;
540}
541 152
542#endif /* _M68K_STRING_H_ */ 153#endif /* _M68K_STRING_H_ */