Commit d6359fd783251238dbbf70b7c2fc745db25cf51f
Committed by
Linus Torvalds
1 parent
7236e978a3
Exists in
master
and in
7 other branches
[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" |