diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2006-10-06 03:43:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-06 11:53:40 -0400 |
commit | d6359fd783251238dbbf70b7c2fc745db25cf51f (patch) | |
tree | 8f11ac5e1770546be6ee56c344c3cff19fe58c5f /include | |
parent | 7236e978a3883406ca06ee79e0739743c7c92a85 (diff) |
[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>
Diffstat (limited to 'include')
-rw-r--r-- | include/asm-m68k/string.h | 198 |
1 files changed, 88 insertions, 110 deletions
diff --git a/include/asm-m68k/string.h b/include/asm-m68k/string.h index 6c59215b285e..2eb7df1e0f5d 100644 --- a/include/asm-m68k/string.h +++ b/include/asm-m68k/string.h | |||
@@ -1,138 +1,114 @@ | |||
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 | |||
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; | ||
18 | } | ||
19 | 10 | ||
20 | #define __HAVE_ARCH_STRNCPY | 11 | for (sc = s; *sc++; ) |
21 | static inline char * strncpy(char *dest, const char *src, size_t n) | 12 | ; |
22 | { | 13 | return sc - s - 1; |
23 | char *xdest = dest; | ||
24 | |||
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; | ||
38 | } | 14 | } |
39 | 15 | ||
40 | #define __HAVE_ARCH_STRCAT | 16 | static inline char *__kernel_strcpy(char *dest, const char *src) |
41 | static inline char * strcat(char * dest, const char * src) | ||
42 | { | 17 | { |
43 | char *tmp = dest; | 18 | char *xdest = dest; |
44 | 19 | ||
45 | while (*dest) | 20 | asm volatile ("\n" |
46 | dest++; | 21 | "1: move.b (%1)+,(%0)+\n" |
47 | while ((*dest++ = *src++)) | 22 | " jne 1b" |
48 | ; | 23 | : "+a" (dest), "+a" (src) |
49 | 24 | : : "memory"); | |
50 | return tmp; | 25 | return xdest; |
51 | } | 26 | } |
52 | 27 | ||
53 | #define __HAVE_ARCH_STRNCAT | 28 | #ifndef __IN_STRING_C |
54 | static inline char * strncat(char *dest, const char *src, size_t count) | ||
55 | { | ||
56 | char *tmp = dest; | ||
57 | |||
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 | 29 | ||
69 | return tmp; | 30 | #define __HAVE_ARCH_STRLEN |
70 | } | 31 | #define strlen(s) (__builtin_constant_p(s) ? \ |
32 | __builtin_strlen(s) : \ | ||
33 | __kernel_strlen(s)) | ||
71 | 34 | ||
72 | #define __HAVE_ARCH_STRCHR | 35 | #define __HAVE_ARCH_STRNLEN |
73 | static inline char * strchr(const char * s, int c) | 36 | static inline size_t strnlen(const char *s, size_t count) |
74 | { | 37 | { |
75 | const char ch = c; | 38 | const char *sc = s; |
76 | 39 | ||
77 | for(; *s != ch; ++s) | 40 | asm volatile ("\n" |
78 | if (*s == '\0') | 41 | "1: subq.l #1,%1\n" |
79 | return( NULL ); | 42 | " jcs 2f\n" |
80 | return( (char *) s); | 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; | ||
81 | } | 49 | } |
82 | 50 | ||
83 | /* strstr !! */ | 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 | ||
84 | 60 | ||
85 | #define __HAVE_ARCH_STRLEN | 61 | #define __HAVE_ARCH_STRNCPY |
86 | static inline size_t strlen(const char * s) | 62 | static inline char *strncpy(char *dest, const char *src, size_t n) |
87 | { | 63 | { |
88 | const char *sc; | 64 | char *xdest = dest; |
89 | for (sc = s; *sc != '\0'; ++sc) ; | 65 | |
90 | return(sc - 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; | ||
91 | } | 76 | } |
92 | 77 | ||
93 | /* strnlen !! */ | 78 | #define __HAVE_ARCH_STRCAT |
79 | #define strcat(d, s) ({ \ | ||
80 | char *__d = (d); \ | ||
81 | strcpy(__d + strlen(__d), (s)); \ | ||
82 | }) | ||
94 | 83 | ||
95 | #define __HAVE_ARCH_STRCMP | 84 | #define __HAVE_ARCH_STRCHR |
96 | static inline int strcmp(const char * cs,const char * ct) | 85 | static inline char *strchr(const char *s, int c) |
97 | { | 86 | { |
98 | char __res; | 87 | char sc, ch = c; |
99 | 88 | ||
100 | __asm__ | 89 | for (; (sc = *s++) != ch; ) { |
101 | ("1:\tmoveb %0@+,%2\n\t" /* get *cs */ | 90 | if (!sc) |
102 | "cmpb %1@+,%2\n\t" /* compare a byte */ | 91 | return NULL; |
103 | "jne 2f\n\t" /* not equal, break out */ | 92 | } |
104 | "tstb %2\n\t" /* at end of cs? */ | 93 | return (char *)s - 1; |
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; | ||
112 | } | 94 | } |
113 | 95 | ||
114 | #define __HAVE_ARCH_STRNCMP | 96 | #define __HAVE_ARCH_STRCMP |
115 | static inline int strncmp(const char * cs,const char * ct,size_t count) | 97 | static inline int strcmp(const char *cs, const char *ct) |
116 | { | 98 | { |
117 | char __res; | 99 | char res; |
118 | 100 | ||
119 | if (!count) | 101 | asm ("\n" |
120 | return 0; | 102 | "1: move.b (%0)+,%2\n" /* get *cs */ |
121 | __asm__ | 103 | " cmp.b (%1)+,%2\n" /* compare a byte */ |
122 | ("1:\tmovb %0@+,%3\n\t" /* get *cs */ | 104 | " jne 2f\n" /* not equal, break out */ |
123 | "cmpb %1@+,%3\n\t" /* compare a byte */ | 105 | " tst.b %2\n" /* at end of cs? */ |
124 | "jne 3f\n\t" /* not equal, break out */ | 106 | " jne 1b\n" /* no, keep going */ |
125 | "tstb %3\n\t" /* at end of cs? */ | 107 | " jra 3f\n" /* strings are equal */ |
126 | "jeq 4f\n\t" /* yes, all done */ | 108 | "2: sub.b -(%1),%2\n" /* *cs - *ct */ |
127 | "subql #1,%2\n\t" /* no, adjust count */ | 109 | "3:" |
128 | "jne 1b\n\t" /* more to do, keep going */ | 110 | : "+a" (cs), "+a" (ct), "=d" (res)); |
129 | "2:\tmoveq #0,%3\n\t" /* strings are equal */ | 111 | return res; |
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 | } | 112 | } |
137 | 113 | ||
138 | #define __HAVE_ARCH_MEMSET | 114 | #define __HAVE_ARCH_MEMSET |
@@ -150,4 +126,6 @@ extern void *memmove(void *, const void *, __kernel_size_t); | |||
150 | extern int memcmp(const void *, const void *, __kernel_size_t); | 126 | extern int memcmp(const void *, const void *, __kernel_size_t); |
151 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) | 127 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) |
152 | 128 | ||
129 | #endif | ||
130 | |||
153 | #endif /* _M68K_STRING_H_ */ | 131 | #endif /* _M68K_STRING_H_ */ |