Commit d6359fd783251238dbbf70b7c2fc745db25cf51f

Authored by Roman Zippel
Committed by Linus Torvalds
1 parent 7236e978a3

[PATCH] m68k: cleanup string functions

- cleanup asm of string functions
- deinline strncat()/strncmp()
- provide non-inlined strcpy()

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 3 changed files with 102 additions and 115 deletions Inline Diff

arch/m68k/kernel/m68k_ksyms.c
1 #include <linux/module.h> 1 #include <linux/module.h>
2 #include <linux/linkage.h> 2 #include <linux/linkage.h>
3 #include <linux/sched.h> 3 #include <linux/sched.h>
4 #include <linux/string.h>
5 #include <linux/mm.h> 4 #include <linux/mm.h>
6 #include <linux/user.h> 5 #include <linux/user.h>
7 #include <linux/elfcore.h> 6 #include <linux/elfcore.h>
8 #include <linux/in6.h> 7 #include <linux/in6.h>
9 #include <linux/interrupt.h> 8 #include <linux/interrupt.h>
10 9
11 #include <asm/setup.h> 10 #include <asm/setup.h>
12 #include <asm/machdep.h> 11 #include <asm/machdep.h>
13 #include <asm/pgalloc.h> 12 #include <asm/pgalloc.h>
14 #include <asm/irq.h> 13 #include <asm/irq.h>
15 #include <asm/io.h> 14 #include <asm/io.h>
16 #include <asm/semaphore.h> 15 #include <asm/semaphore.h>
17 #include <asm/checksum.h> 16 #include <asm/checksum.h>
18 17
19 asmlinkage long long __ashldi3 (long long, int); 18 asmlinkage long long __ashldi3 (long long, int);
20 asmlinkage long long __ashrdi3 (long long, int); 19 asmlinkage long long __ashrdi3 (long long, int);
21 asmlinkage long long __lshrdi3 (long long, int); 20 asmlinkage long long __lshrdi3 (long long, int);
22 asmlinkage long long __muldi3 (long long, long long); 21 asmlinkage long long __muldi3 (long long, long long);
23 extern char m68k_debug_device[]; 22 extern char m68k_debug_device[];
24 23
25 /* platform dependent support */ 24 /* platform dependent support */
26 25
27 EXPORT_SYMBOL(m68k_machtype); 26 EXPORT_SYMBOL(m68k_machtype);
28 EXPORT_SYMBOL(m68k_cputype); 27 EXPORT_SYMBOL(m68k_cputype);
29 EXPORT_SYMBOL(m68k_is040or060); 28 EXPORT_SYMBOL(m68k_is040or060);
30 EXPORT_SYMBOL(m68k_realnum_memory); 29 EXPORT_SYMBOL(m68k_realnum_memory);
31 EXPORT_SYMBOL(m68k_memory); 30 EXPORT_SYMBOL(m68k_memory);
32 #ifndef CONFIG_SUN3 31 #ifndef CONFIG_SUN3
33 EXPORT_SYMBOL(cache_push); 32 EXPORT_SYMBOL(cache_push);
34 EXPORT_SYMBOL(cache_clear); 33 EXPORT_SYMBOL(cache_clear);
35 #ifndef CONFIG_SINGLE_MEMORY_CHUNK 34 #ifndef CONFIG_SINGLE_MEMORY_CHUNK
36 EXPORT_SYMBOL(mm_vtop); 35 EXPORT_SYMBOL(mm_vtop);
37 EXPORT_SYMBOL(mm_ptov); 36 EXPORT_SYMBOL(mm_ptov);
38 EXPORT_SYMBOL(mm_end_of_chunk); 37 EXPORT_SYMBOL(mm_end_of_chunk);
39 #else 38 #else
40 EXPORT_SYMBOL(m68k_memoffset); 39 EXPORT_SYMBOL(m68k_memoffset);
41 #endif /* !CONFIG_SINGLE_MEMORY_CHUNK */ 40 #endif /* !CONFIG_SINGLE_MEMORY_CHUNK */
42 EXPORT_SYMBOL(__ioremap); 41 EXPORT_SYMBOL(__ioremap);
43 EXPORT_SYMBOL(iounmap); 42 EXPORT_SYMBOL(iounmap);
44 EXPORT_SYMBOL(kernel_set_cachemode); 43 EXPORT_SYMBOL(kernel_set_cachemode);
45 #endif /* !CONFIG_SUN3 */ 44 #endif /* !CONFIG_SUN3 */
46 EXPORT_SYMBOL(m68k_debug_device); 45 EXPORT_SYMBOL(m68k_debug_device);
47 EXPORT_SYMBOL(mach_hwclk); 46 EXPORT_SYMBOL(mach_hwclk);
48 EXPORT_SYMBOL(mach_get_ss); 47 EXPORT_SYMBOL(mach_get_ss);
49 EXPORT_SYMBOL(mach_get_rtc_pll); 48 EXPORT_SYMBOL(mach_get_rtc_pll);
50 EXPORT_SYMBOL(mach_set_rtc_pll); 49 EXPORT_SYMBOL(mach_set_rtc_pll);
51 #ifdef CONFIG_INPUT_M68K_BEEP_MODULE 50 #ifdef CONFIG_INPUT_M68K_BEEP_MODULE
52 EXPORT_SYMBOL(mach_beep); 51 EXPORT_SYMBOL(mach_beep);
53 #endif 52 #endif
54 EXPORT_SYMBOL(dump_fpu); 53 EXPORT_SYMBOL(dump_fpu);
55 EXPORT_SYMBOL(dump_thread); 54 EXPORT_SYMBOL(dump_thread);
56 EXPORT_SYMBOL(strnlen);
57 EXPORT_SYMBOL(strrchr);
58 EXPORT_SYMBOL(strstr);
59 EXPORT_SYMBOL(kernel_thread); 55 EXPORT_SYMBOL(kernel_thread);
60 #ifdef CONFIG_VME 56 #ifdef CONFIG_VME
61 EXPORT_SYMBOL(vme_brdtype); 57 EXPORT_SYMBOL(vme_brdtype);
62 #endif 58 #endif
63 59
64 /* The following are special because they're not called 60 /* The following are special because they're not called
65 explicitly (the C compiler generates them). Fortunately, 61 explicitly (the C compiler generates them). Fortunately,
66 their interface isn't gonna change any time soon now, so 62 their interface isn't gonna change any time soon now, so
67 it's OK to leave it out of version control. */ 63 it's OK to leave it out of version control. */
68 EXPORT_SYMBOL(__ashldi3); 64 EXPORT_SYMBOL(__ashldi3);
69 EXPORT_SYMBOL(__ashrdi3); 65 EXPORT_SYMBOL(__ashrdi3);
70 EXPORT_SYMBOL(__lshrdi3); 66 EXPORT_SYMBOL(__lshrdi3);
71 EXPORT_SYMBOL(__muldi3); 67 EXPORT_SYMBOL(__muldi3);
72 68
73 EXPORT_SYMBOL(__down_failed); 69 EXPORT_SYMBOL(__down_failed);
74 EXPORT_SYMBOL(__down_failed_interruptible); 70 EXPORT_SYMBOL(__down_failed_interruptible);
75 EXPORT_SYMBOL(__down_failed_trylock); 71 EXPORT_SYMBOL(__down_failed_trylock);
76 EXPORT_SYMBOL(__up_wakeup); 72 EXPORT_SYMBOL(__up_wakeup);
77 73
78 74
arch/m68k/lib/string.c
1 /*
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 */
1 6
2 #include <linux/types.h> 7 #define __IN_STRING_C
8
3 #include <linux/module.h> 9 #include <linux/module.h>
10 #include <linux/string.h>
11
12 char *strcpy(char *dest, const char *src)
13 {
14 return __kernel_strcpy(dest, src);
15 }
16 EXPORT_SYMBOL(strcpy);
4 17
5 void *memset(void *s, int c, size_t count) 18 void *memset(void *s, int c, size_t count)
6 { 19 {
7 void *xs = s; 20 void *xs = s;
8 size_t temp, temp1; 21 size_t temp, temp1;
9 22
10 if (!count) 23 if (!count)
11 return xs; 24 return xs;
12 c &= 0xff; 25 c &= 0xff;
13 c |= c << 8; 26 c |= c << 8;
14 c |= c << 16; 27 c |= c << 16;
15 if ((long)s & 1) { 28 if ((long)s & 1) {
16 char *cs = s; 29 char *cs = s;
17 *cs++ = c; 30 *cs++ = c;
18 s = cs; 31 s = cs;
19 count--; 32 count--;
20 } 33 }
21 if (count > 2 && (long)s & 2) { 34 if (count > 2 && (long)s & 2) {
22 short *ss = s; 35 short *ss = s;
23 *ss++ = c; 36 *ss++ = c;
24 s = ss; 37 s = ss;
25 count -= 2; 38 count -= 2;
26 } 39 }
27 temp = count >> 2; 40 temp = count >> 2;
28 if (temp) { 41 if (temp) {
29 long *ls = s; 42 long *ls = s;
30 43
31 asm volatile ( 44 asm volatile (
32 " movel %1,%2\n" 45 " movel %1,%2\n"
33 " andw #7,%2\n" 46 " andw #7,%2\n"
34 " lsrl #3,%1\n" 47 " lsrl #3,%1\n"
35 " negw %2\n" 48 " negw %2\n"
36 " jmp %%pc@(2f,%2:w:2)\n" 49 " jmp %%pc@(2f,%2:w:2)\n"
37 "1: movel %3,%0@+\n" 50 "1: movel %3,%0@+\n"
38 " movel %3,%0@+\n" 51 " movel %3,%0@+\n"
39 " movel %3,%0@+\n" 52 " movel %3,%0@+\n"
40 " movel %3,%0@+\n" 53 " movel %3,%0@+\n"
41 " movel %3,%0@+\n" 54 " movel %3,%0@+\n"
42 " movel %3,%0@+\n" 55 " movel %3,%0@+\n"
43 " movel %3,%0@+\n" 56 " movel %3,%0@+\n"
44 " movel %3,%0@+\n" 57 " movel %3,%0@+\n"
45 "2: dbra %1,1b\n" 58 "2: dbra %1,1b\n"
46 " clrw %1\n" 59 " clrw %1\n"
47 " subql #1,%1\n" 60 " subql #1,%1\n"
48 " jpl 1b" 61 " jpl 1b"
49 : "=a" (ls), "=d" (temp), "=&d" (temp1) 62 : "=a" (ls), "=d" (temp), "=&d" (temp1)
50 : "d" (c), "0" (ls), "1" (temp)); 63 : "d" (c), "0" (ls), "1" (temp));
51 s = ls; 64 s = ls;
52 } 65 }
53 if (count & 2) { 66 if (count & 2) {
54 short *ss = s; 67 short *ss = s;
55 *ss++ = c; 68 *ss++ = c;
56 s = ss; 69 s = ss;
57 } 70 }
58 if (count & 1) { 71 if (count & 1) {
59 char *cs = s; 72 char *cs = s;
60 *cs = c; 73 *cs = c;
61 } 74 }
62 return xs; 75 return xs;
63 } 76 }
64 EXPORT_SYMBOL(memset); 77 EXPORT_SYMBOL(memset);
65 78
66 void *memcpy(void *to, const void *from, size_t n) 79 void *memcpy(void *to, const void *from, size_t n)
67 { 80 {
68 void *xto = to; 81 void *xto = to;
69 size_t temp, temp1; 82 size_t temp, temp1;
70 83
71 if (!n) 84 if (!n)
72 return xto; 85 return xto;
73 if ((long)to & 1) { 86 if ((long)to & 1) {
74 char *cto = to; 87 char *cto = to;
75 const char *cfrom = from; 88 const char *cfrom = from;
76 *cto++ = *cfrom++; 89 *cto++ = *cfrom++;
77 to = cto; 90 to = cto;
78 from = cfrom; 91 from = cfrom;
79 n--; 92 n--;
80 } 93 }
81 if (n > 2 && (long)to & 2) { 94 if (n > 2 && (long)to & 2) {
82 short *sto = to; 95 short *sto = to;
83 const short *sfrom = from; 96 const short *sfrom = from;
84 *sto++ = *sfrom++; 97 *sto++ = *sfrom++;
85 to = sto; 98 to = sto;
86 from = sfrom; 99 from = sfrom;
87 n -= 2; 100 n -= 2;
88 } 101 }
89 temp = n >> 2; 102 temp = n >> 2;
90 if (temp) { 103 if (temp) {
91 long *lto = to; 104 long *lto = to;
92 const long *lfrom = from; 105 const long *lfrom = from;
93 106
94 asm volatile ( 107 asm volatile (
95 " movel %2,%3\n" 108 " movel %2,%3\n"
96 " andw #7,%3\n" 109 " andw #7,%3\n"
97 " lsrl #3,%2\n" 110 " lsrl #3,%2\n"
98 " negw %3\n" 111 " negw %3\n"
99 " jmp %%pc@(1f,%3:w:2)\n" 112 " jmp %%pc@(1f,%3:w:2)\n"
100 "4: movel %0@+,%1@+\n" 113 "4: movel %0@+,%1@+\n"
101 " movel %0@+,%1@+\n" 114 " movel %0@+,%1@+\n"
102 " movel %0@+,%1@+\n" 115 " movel %0@+,%1@+\n"
103 " movel %0@+,%1@+\n" 116 " movel %0@+,%1@+\n"
104 " movel %0@+,%1@+\n" 117 " movel %0@+,%1@+\n"
105 " movel %0@+,%1@+\n" 118 " movel %0@+,%1@+\n"
106 " movel %0@+,%1@+\n" 119 " movel %0@+,%1@+\n"
107 " movel %0@+,%1@+\n" 120 " movel %0@+,%1@+\n"
108 "1: dbra %2,4b\n" 121 "1: dbra %2,4b\n"
109 " clrw %2\n" 122 " clrw %2\n"
110 " subql #1,%2\n" 123 " subql #1,%2\n"
111 " jpl 4b" 124 " jpl 4b"
112 : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1) 125 : "=a" (lfrom), "=a" (lto), "=d" (temp), "=&d" (temp1)
113 : "0" (lfrom), "1" (lto), "2" (temp)); 126 : "0" (lfrom), "1" (lto), "2" (temp));
114 to = lto; 127 to = lto;
115 from = lfrom; 128 from = lfrom;
116 } 129 }
117 if (n & 2) { 130 if (n & 2) {
118 short *sto = to; 131 short *sto = to;
119 const short *sfrom = from; 132 const short *sfrom = from;
120 *sto++ = *sfrom++; 133 *sto++ = *sfrom++;
121 to = sto; 134 to = sto;
122 from = sfrom; 135 from = sfrom;
123 } 136 }
124 if (n & 1) { 137 if (n & 1) {
125 char *cto = to; 138 char *cto = to;
126 const char *cfrom = from; 139 const char *cfrom = from;
127 *cto = *cfrom; 140 *cto = *cfrom;
128 } 141 }
129 return xto; 142 return xto;
130 } 143 }
131 EXPORT_SYMBOL(memcpy); 144 EXPORT_SYMBOL(memcpy);
132 145
133 void *memmove(void *dest, const void *src, size_t n) 146 void *memmove(void *dest, const void *src, size_t n)
134 { 147 {
135 void *xdest = dest; 148 void *xdest = dest;
136 size_t temp; 149 size_t temp;
137 150
138 if (!n) 151 if (!n)
139 return xdest; 152 return xdest;
140 153
141 if (dest < src) { 154 if (dest < src) {
142 if ((long)dest & 1) { 155 if ((long)dest & 1) {
143 char *cdest = dest; 156 char *cdest = dest;
144 const char *csrc = src; 157 const char *csrc = src;
145 *cdest++ = *csrc++; 158 *cdest++ = *csrc++;
146 dest = cdest; 159 dest = cdest;
147 src = csrc; 160 src = csrc;
148 n--; 161 n--;
149 } 162 }
150 if (n > 2 && (long)dest & 2) { 163 if (n > 2 && (long)dest & 2) {
151 short *sdest = dest; 164 short *sdest = dest;
152 const short *ssrc = src; 165 const short *ssrc = src;
153 *sdest++ = *ssrc++; 166 *sdest++ = *ssrc++;
154 dest = sdest; 167 dest = sdest;
155 src = ssrc; 168 src = ssrc;
156 n -= 2; 169 n -= 2;
157 } 170 }
158 temp = n >> 2; 171 temp = n >> 2;
159 if (temp) { 172 if (temp) {
160 long *ldest = dest; 173 long *ldest = dest;
161 const long *lsrc = src; 174 const long *lsrc = src;
162 temp--; 175 temp--;
163 do 176 do
164 *ldest++ = *lsrc++; 177 *ldest++ = *lsrc++;
165 while (temp--); 178 while (temp--);
166 dest = ldest; 179 dest = ldest;
167 src = lsrc; 180 src = lsrc;
168 } 181 }
169 if (n & 2) { 182 if (n & 2) {
170 short *sdest = dest; 183 short *sdest = dest;
171 const short *ssrc = src; 184 const short *ssrc = src;
172 *sdest++ = *ssrc++; 185 *sdest++ = *ssrc++;
173 dest = sdest; 186 dest = sdest;
174 src = ssrc; 187 src = ssrc;
175 } 188 }
176 if (n & 1) { 189 if (n & 1) {
177 char *cdest = dest; 190 char *cdest = dest;
178 const char *csrc = src; 191 const char *csrc = src;
179 *cdest = *csrc; 192 *cdest = *csrc;
180 } 193 }
181 } else { 194 } else {
182 dest = (char *)dest + n; 195 dest = (char *)dest + n;
183 src = (const char *)src + n; 196 src = (const char *)src + n;
184 if ((long)dest & 1) { 197 if ((long)dest & 1) {
185 char *cdest = dest; 198 char *cdest = dest;
186 const char *csrc = src; 199 const char *csrc = src;
187 *--cdest = *--csrc; 200 *--cdest = *--csrc;
188 dest = cdest; 201 dest = cdest;
189 src = csrc; 202 src = csrc;
190 n--; 203 n--;
191 } 204 }
192 if (n > 2 && (long)dest & 2) { 205 if (n > 2 && (long)dest & 2) {
193 short *sdest = dest; 206 short *sdest = dest;
194 const short *ssrc = src; 207 const short *ssrc = src;
195 *--sdest = *--ssrc; 208 *--sdest = *--ssrc;
196 dest = sdest; 209 dest = sdest;
197 src = ssrc; 210 src = ssrc;
198 n -= 2; 211 n -= 2;
199 } 212 }
200 temp = n >> 2; 213 temp = n >> 2;
201 if (temp) { 214 if (temp) {
202 long *ldest = dest; 215 long *ldest = dest;
203 const long *lsrc = src; 216 const long *lsrc = src;
204 temp--; 217 temp--;
205 do 218 do
206 *--ldest = *--lsrc; 219 *--ldest = *--lsrc;
207 while (temp--); 220 while (temp--);
208 dest = ldest; 221 dest = ldest;
209 src = lsrc; 222 src = lsrc;
210 } 223 }
211 if (n & 2) { 224 if (n & 2) {
212 short *sdest = dest; 225 short *sdest = dest;
213 const short *ssrc = src; 226 const short *ssrc = src;
214 *--sdest = *--ssrc; 227 *--sdest = *--ssrc;
215 dest = sdest; 228 dest = sdest;
216 src = ssrc; 229 src = ssrc;
217 } 230 }
218 if (n & 1) { 231 if (n & 1) {
219 char *cdest = dest; 232 char *cdest = dest;
220 const char *csrc = src; 233 const char *csrc = src;
221 *--cdest = *--csrc; 234 *--cdest = *--csrc;
222 } 235 }
223 } 236 }
224 return xdest; 237 return xdest;
225 } 238 }
226 EXPORT_SYMBOL(memmove); 239 EXPORT_SYMBOL(memmove);
227 240
228 int memcmp(const void *cs, const void *ct, size_t count) 241 int memcmp(const void *cs, const void *ct, size_t count)
229 { 242 {
230 const unsigned char *su1, *su2; 243 const unsigned char *su1, *su2;
231 244
232 for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--) 245 for (su1 = cs, su2 = ct; count > 0; ++su1, ++su2, count--)
233 if (*su1 != *su2) 246 if (*su1 != *su2)
234 return *su1 < *su2 ? -1 : +1; 247 return *su1 < *su2 ? -1 : +1;
235 return 0; 248 return 0;
236 } 249 }
237 EXPORT_SYMBOL(memcmp); 250 EXPORT_SYMBOL(memcmp);
238 251
include/asm-m68k/string.h
1 #ifndef _M68K_STRING_H_ 1 #ifndef _M68K_STRING_H_
2 #define _M68K_STRING_H_ 2 #define _M68K_STRING_H_
3 3
4 #include <asm/setup.h> 4 #include <linux/types.h>
5 #include <asm/page.h> 5 #include <linux/compiler.h>
6 6
7 #define __HAVE_ARCH_STRCPY 7 static inline size_t __kernel_strlen(const char *s)
8 static inline char * strcpy(char * dest,const char *src)
9 { 8 {
10 char *xdest = dest; 9 const char *sc;
11 10
12 __asm__ __volatile__ 11 for (sc = s; *sc++; )
13 ("1:\tmoveb %1@+,%0@+\n\t" 12 ;
14 "jne 1b" 13 return sc - s - 1;
15 : "=a" (dest), "=a" (src)
16 : "0" (dest), "1" (src) : "memory");
17 return xdest;
18 } 14 }
19 15
20 #define __HAVE_ARCH_STRNCPY 16 static inline char *__kernel_strcpy(char *dest, const char *src)
21 static inline char * strncpy(char *dest, const char *src, size_t n)
22 { 17 {
23 char *xdest = dest; 18 char *xdest = dest;
24 19
25 if (n == 0) 20 asm volatile ("\n"
26 return xdest; 21 "1: move.b (%1)+,(%0)+\n"
27 22 " jne 1b"
28 __asm__ __volatile__ 23 : "+a" (dest), "+a" (src)
29 ("1:\tmoveb %1@+,%0@+\n\t" 24 : : "memory");
30 "jeq 2f\n\t" 25 return xdest;
31 "subql #1,%2\n\t"
32 "jne 1b\n\t"
33 "2:"
34 : "=a" (dest), "=a" (src), "=d" (n)
35 : "0" (dest), "1" (src), "2" (n)
36 : "memory");
37 return xdest;
38 } 26 }
39 27
40 #define __HAVE_ARCH_STRCAT 28 #ifndef __IN_STRING_C
41 static inline char * strcat(char * dest, const char * src)
42 {
43 char *tmp = dest;
44 29
45 while (*dest) 30 #define __HAVE_ARCH_STRLEN
46 dest++; 31 #define strlen(s) (__builtin_constant_p(s) ? \
47 while ((*dest++ = *src++)) 32 __builtin_strlen(s) : \
48 ; 33 __kernel_strlen(s))
49 34
50 return tmp; 35 #define __HAVE_ARCH_STRNLEN
51 } 36 static inline size_t strnlen(const char *s, size_t count)
52
53 #define __HAVE_ARCH_STRNCAT
54 static inline char * strncat(char *dest, const char *src, size_t count)
55 { 37 {
56 char *tmp = dest; 38 const char *sc = s;
57 39
58 if (count) { 40 asm volatile ("\n"
59 while (*dest) 41 "1: subq.l #1,%1\n"
60 dest++; 42 " jcs 2f\n"
61 while ((*dest++ = *src++)) { 43 " tst.b (%0)+\n"
62 if (--count == 0) { 44 " jne 1b\n"
63 *dest++='\0'; 45 " subq.l #1,%0\n"
64 break; 46 "2:"
65 } 47 : "+a" (sc), "+d" (count));
66 } 48 return sc - s;
67 }
68
69 return tmp;
70 } 49 }
71 50
72 #define __HAVE_ARCH_STRCHR 51 #define __HAVE_ARCH_STRCPY
73 static inline char * strchr(const char * s, int c) 52 #if __GNUC__ >= 4
53 #define strcpy(d, s) (__builtin_constant_p(s) && \
54 __builtin_strlen(s) <= 32 ? \
55 __builtin_strcpy(d, s) : \
56 __kernel_strcpy(d, s))
57 #else
58 #define strcpy(d, s) __kernel_strcpy(d, s)
59 #endif
60
61 #define __HAVE_ARCH_STRNCPY
62 static inline char *strncpy(char *dest, const char *src, size_t n)
74 { 63 {
75 const char ch = c; 64 char *xdest = dest;
76 65
77 for(; *s != ch; ++s) 66 asm volatile ("\n"
78 if (*s == '\0') 67 " jra 2f\n"
79 return( NULL ); 68 "1: move.b (%1),(%0)+\n"
80 return( (char *) s); 69 " jeq 2f\n"
70 " addq.l #1,%1\n"
71 "2: subq.l #1,%2\n"
72 " jcc 1b\n"
73 : "+a" (dest), "+a" (src), "+d" (n)
74 : : "memory");
75 return xdest;
81 } 76 }
82 77
83 /* strstr !! */ 78 #define __HAVE_ARCH_STRCAT
79 #define strcat(d, s) ({ \
80 char *__d = (d); \
81 strcpy(__d + strlen(__d), (s)); \
82 })
84 83
85 #define __HAVE_ARCH_STRLEN 84 #define __HAVE_ARCH_STRCHR
86 static inline size_t strlen(const char * s) 85 static inline char *strchr(const char *s, int c)
87 { 86 {
88 const char *sc; 87 char sc, ch = c;
89 for (sc = s; *sc != '\0'; ++sc) ; 88
90 return(sc - s); 89 for (; (sc = *s++) != ch; ) {
90 if (!sc)
91 return NULL;
92 }
93 return (char *)s - 1;
91 } 94 }
92 95
93 /* strnlen !! */
94
95 #define __HAVE_ARCH_STRCMP 96 #define __HAVE_ARCH_STRCMP
96 static inline int strcmp(const char * cs,const char * ct) 97 static inline int strcmp(const char *cs, const char *ct)
97 { 98 {
98 char __res; 99 char res;
99 100
100 __asm__ 101 asm ("\n"
101 ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ 102 "1: move.b (%0)+,%2\n" /* get *cs */
102 "cmpb %1@+,%2\n\t" /* compare a byte */ 103 " cmp.b (%1)+,%2\n" /* compare a byte */
103 "jne 2f\n\t" /* not equal, break out */ 104 " jne 2f\n" /* not equal, break out */
104 "tstb %2\n\t" /* at end of cs? */ 105 " tst.b %2\n" /* at end of cs? */
105 "jne 1b\n\t" /* no, keep going */ 106 " jne 1b\n" /* no, keep going */
106 "jra 3f\n\t" /* strings are equal */ 107 " jra 3f\n" /* strings are equal */
107 "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ 108 "2: sub.b -(%1),%2\n" /* *cs - *ct */
108 "3:" 109 "3:"
109 : "=a" (cs), "=a" (ct), "=d" (__res) 110 : "+a" (cs), "+a" (ct), "=d" (res));
110 : "0" (cs), "1" (ct)); 111 return res;
111 return __res;
112 } 112 }
113 113
114 #define __HAVE_ARCH_STRNCMP
115 static inline int strncmp(const char * cs,const char * ct,size_t count)
116 {
117 char __res;
118
119 if (!count)
120 return 0;
121 __asm__
122 ("1:\tmovb %0@+,%3\n\t" /* get *cs */
123 "cmpb %1@+,%3\n\t" /* compare a byte */
124 "jne 3f\n\t" /* not equal, break out */
125 "tstb %3\n\t" /* at end of cs? */
126 "jeq 4f\n\t" /* yes, all done */
127 "subql #1,%2\n\t" /* no, adjust count */
128 "jne 1b\n\t" /* more to do, keep going */
129 "2:\tmoveq #0,%3\n\t" /* strings are equal */
130 "jra 4f\n\t"