Commit 072dffda1d35c391fe893ec9b1d098145e668fef

Authored by Roman Zippel
Committed by Linus Torvalds
1 parent 2855b97020

[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>

Showing 7 changed files with 245 additions and 555 deletions Side-by-side Diff

arch/m68k/kernel/m68k_ksyms.c
... ... @@ -74,10 +74,6 @@
74 74 EXPORT_SYMBOL(__ashldi3);
75 75 EXPORT_SYMBOL(__ashrdi3);
76 76 EXPORT_SYMBOL(__lshrdi3);
77   -EXPORT_SYMBOL(memcpy);
78   -EXPORT_SYMBOL(memset);
79   -EXPORT_SYMBOL(memcmp);
80   -EXPORT_SYMBOL(memscan);
81 77 EXPORT_SYMBOL(__muldi3);
82 78  
83 79 EXPORT_SYMBOL(__down_failed);
arch/m68k/lib/Makefile
... ... @@ -5,5 +5,5 @@
5 5 EXTRA_AFLAGS := -traditional
6 6  
7 7 lib-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
arch/m68k/lib/memcmp.c
1   -#include <linux/types.h>
2   -
3   -int 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   -}
arch/m68k/lib/memcpy.c
1   -#include <linux/types.h>
2   -
3   -void * 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   -}
arch/m68k/lib/memset.c
1   -#include <linux/types.h>
2   -
3   -void * 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   -}
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);
include/asm-m68k/string.h
... ... @@ -80,43 +80,6 @@
80 80 return( (char *) s);
81 81 }
82 82  
83   -#if 0
84   -#define __HAVE_ARCH_STRPBRK
85   -static 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
99   -static 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 83 /* strstr !! */
121 84  
122 85 #define __HAVE_ARCH_STRLEN
123 86  
124 87  
125 88  
126 89  
127 90  
128 91  
... ... @@ -173,371 +136,19 @@
173 136 }
174 137  
175 138 #define __HAVE_ARCH_MEMSET
176   -/*
177   - * This is really ugly, but its highly optimizatiable by the
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   - */
185   -static inline void * __memset_g(void * s, int c, size_t count)
186   -{
187   - void *xs = s;
188   - size_t temp;
  139 +extern void *memset(void *, int, __kernel_size_t);
  140 +#define memset(d, c, n) __builtin_memset(d, c, n)
189 141  
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   - */
290   -static 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   -
341   -extern 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   -
353 142 #define __HAVE_ARCH_MEMCPY
354   -extern void * memcpy(void *, const void *, size_t );
355   -/*
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   - */
369   -static inline void * __memcpy_page(void * to, const void * from, size_t count)
370   -{
371   - unsigned long tmp;
372   - void *xto = to;
  143 +extern void *memcpy(void *, const void *, __kernel_size_t);
  144 +#define memcpy(d, s, n) __builtin_memcpy(d, s, n)
373 145  
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   -
416 146 #define __HAVE_ARCH_MEMMOVE
417   -static inline void * memmove(void * dest,const void * src, size_t n)
418   -{
419   - void *xdest = dest;
420   - size_t temp;
  147 +extern void *memmove(void *, const void *, __kernel_size_t);
421 148  
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   -
524 149 #define __HAVE_ARCH_MEMCMP
525   -extern int memcmp(const void * ,const void * ,size_t );
526   -#define memcmp(cs, ct, n) \
527   -(__builtin_constant_p(n) ? \
528   - __builtin_memcmp((cs),(ct),(n)) : \
529   - memcmp((cs),(ct),(n)))
530   -
531   -#define __HAVE_ARCH_MEMCHR
532   -static 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   -}
  150 +extern int memcmp(const void *, const void *, __kernel_size_t);
  151 +#define memcmp(d, s, n) __builtin_memcmp(d, s, n)
541 152  
542 153 #endif /* _M68K_STRING_H_ */