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 Side-by-side Diff
arch/m68k/kernel/m68k_ksyms.c
1 | 1 | #include <linux/module.h> |
2 | 2 | #include <linux/linkage.h> |
3 | 3 | #include <linux/sched.h> |
4 | -#include <linux/string.h> | |
5 | 4 | #include <linux/mm.h> |
6 | 5 | #include <linux/user.h> |
7 | 6 | #include <linux/elfcore.h> |
... | ... | @@ -53,9 +52,6 @@ |
53 | 52 | #endif |
54 | 53 | EXPORT_SYMBOL(dump_fpu); |
55 | 54 | EXPORT_SYMBOL(dump_thread); |
56 | -EXPORT_SYMBOL(strnlen); | |
57 | -EXPORT_SYMBOL(strrchr); | |
58 | -EXPORT_SYMBOL(strstr); | |
59 | 55 | EXPORT_SYMBOL(kernel_thread); |
60 | 56 | #ifdef CONFIG_VME |
61 | 57 | EXPORT_SYMBOL(vme_brdtype); |
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 | 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 | 18 | void *memset(void *s, int c, size_t count) |
6 | 19 | { |
include/asm-m68k/string.h
1 | 1 | #ifndef _M68K_STRING_H_ |
2 | 2 | #define _M68K_STRING_H_ |
3 | 3 | |
4 | -#include <asm/setup.h> | |
5 | -#include <asm/page.h> | |
4 | +#include <linux/types.h> | |
5 | +#include <linux/compiler.h> | |
6 | 6 | |
7 | -#define __HAVE_ARCH_STRCPY | |
8 | -static inline char * strcpy(char * dest,const char *src) | |
7 | +static inline size_t __kernel_strlen(const char *s) | |
9 | 8 | { |
10 | - char *xdest = dest; | |
9 | + const char *sc; | |
11 | 10 | |
12 | - __asm__ __volatile__ | |
13 | - ("1:\tmoveb %1@+,%0@+\n\t" | |
14 | - "jne 1b" | |
15 | - : "=a" (dest), "=a" (src) | |
16 | - : "0" (dest), "1" (src) : "memory"); | |
17 | - return xdest; | |
11 | + for (sc = s; *sc++; ) | |
12 | + ; | |
13 | + return sc - s - 1; | |
18 | 14 | } |
19 | 15 | |
20 | -#define __HAVE_ARCH_STRNCPY | |
21 | -static inline char * strncpy(char *dest, const char *src, size_t n) | |
16 | +static inline char *__kernel_strcpy(char *dest, const char *src) | |
22 | 17 | { |
23 | - char *xdest = dest; | |
18 | + char *xdest = dest; | |
24 | 19 | |
25 | - if (n == 0) | |
26 | - return xdest; | |
27 | - | |
28 | - __asm__ __volatile__ | |
29 | - ("1:\tmoveb %1@+,%0@+\n\t" | |
30 | - "jeq 2f\n\t" | |
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; | |
20 | + asm volatile ("\n" | |
21 | + "1: move.b (%1)+,(%0)+\n" | |
22 | + " jne 1b" | |
23 | + : "+a" (dest), "+a" (src) | |
24 | + : : "memory"); | |
25 | + return xdest; | |
38 | 26 | } |
39 | 27 | |
40 | -#define __HAVE_ARCH_STRCAT | |
41 | -static inline char * strcat(char * dest, const char * src) | |
42 | -{ | |
43 | - char *tmp = dest; | |
28 | +#ifndef __IN_STRING_C | |
44 | 29 | |
45 | - while (*dest) | |
46 | - dest++; | |
47 | - while ((*dest++ = *src++)) | |
48 | - ; | |
30 | +#define __HAVE_ARCH_STRLEN | |
31 | +#define strlen(s) (__builtin_constant_p(s) ? \ | |
32 | + __builtin_strlen(s) : \ | |
33 | + __kernel_strlen(s)) | |
49 | 34 | |
50 | - return tmp; | |
51 | -} | |
52 | - | |
53 | -#define __HAVE_ARCH_STRNCAT | |
54 | -static inline char * strncat(char *dest, const char *src, size_t count) | |
35 | +#define __HAVE_ARCH_STRNLEN | |
36 | +static inline size_t strnlen(const char *s, size_t count) | |
55 | 37 | { |
56 | - char *tmp = dest; | |
38 | + const char *sc = s; | |
57 | 39 | |
58 | - if (count) { | |
59 | - while (*dest) | |
60 | - dest++; | |
61 | - while ((*dest++ = *src++)) { | |
62 | - if (--count == 0) { | |
63 | - *dest++='\0'; | |
64 | - break; | |
65 | - } | |
66 | - } | |
67 | - } | |
68 | - | |
69 | - return tmp; | |
40 | + asm volatile ("\n" | |
41 | + "1: subq.l #1,%1\n" | |
42 | + " jcs 2f\n" | |
43 | + " tst.b (%0)+\n" | |
44 | + " jne 1b\n" | |
45 | + " subq.l #1,%0\n" | |
46 | + "2:" | |
47 | + : "+a" (sc), "+d" (count)); | |
48 | + return sc - s; | |
70 | 49 | } |
71 | 50 | |
72 | -#define __HAVE_ARCH_STRCHR | |
73 | -static inline char * strchr(const char * s, int c) | |
51 | +#define __HAVE_ARCH_STRCPY | |
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) | |
78 | - if (*s == '\0') | |
79 | - return( NULL ); | |
80 | - return( (char *) s); | |
66 | + asm volatile ("\n" | |
67 | + " jra 2f\n" | |
68 | + "1: move.b (%1),(%0)+\n" | |
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 | |
86 | -static inline size_t strlen(const char * s) | |
84 | +#define __HAVE_ARCH_STRCHR | |
85 | +static inline char *strchr(const char *s, int c) | |
87 | 86 | { |
88 | - const char *sc; | |
89 | - for (sc = s; *sc != '\0'; ++sc) ; | |
90 | - return(sc - s); | |
87 | + char sc, ch = c; | |
88 | + | |
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 | 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 | - ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ | |
102 | - "cmpb %1@+,%2\n\t" /* compare a byte */ | |
103 | - "jne 2f\n\t" /* not equal, break out */ | |
104 | - "tstb %2\n\t" /* at end of cs? */ | |
105 | - "jne 1b\n\t" /* no, keep going */ | |
106 | - "jra 3f\n\t" /* strings are equal */ | |
107 | - "2:\tsubb %1@-,%2\n\t" /* *cs - *ct */ | |
108 | - "3:" | |
109 | - : "=a" (cs), "=a" (ct), "=d" (__res) | |
110 | - : "0" (cs), "1" (ct)); | |
111 | - return __res; | |
101 | + asm ("\n" | |
102 | + "1: move.b (%0)+,%2\n" /* get *cs */ | |
103 | + " cmp.b (%1)+,%2\n" /* compare a byte */ | |
104 | + " jne 2f\n" /* not equal, break out */ | |
105 | + " tst.b %2\n" /* at end of cs? */ | |
106 | + " jne 1b\n" /* no, keep going */ | |
107 | + " jra 3f\n" /* strings are equal */ | |
108 | + "2: sub.b -(%1),%2\n" /* *cs - *ct */ | |
109 | + "3:" | |
110 | + : "+a" (cs), "+a" (ct), "=d" (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" | |
131 | - "3:\tsubb %1@-,%3\n\t" /* *cs - *ct */ | |
132 | - "4:" | |
133 | - : "=a" (cs), "=a" (ct), "=d" (count), "=d" (__res) | |
134 | - : "0" (cs), "1" (ct), "2" (count)); | |
135 | - return __res; | |
136 | -} | |
137 | - | |
138 | 114 | #define __HAVE_ARCH_MEMSET |
139 | 115 | extern void *memset(void *, int, __kernel_size_t); |
140 | 116 | #define memset(d, c, n) __builtin_memset(d, c, n) |
... | ... | @@ -149,6 +125,8 @@ |
149 | 125 | #define __HAVE_ARCH_MEMCMP |
150 | 126 | extern int memcmp(const void *, const void *, __kernel_size_t); |
151 | 127 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) |
128 | + | |
129 | +#endif | |
152 | 130 | |
153 | 131 | #endif /* _M68K_STRING_H_ */ |