Merge branch 'for-linus' of git://git.open-osd.org/linux-open-osd
[pandora-kernel.git] / arch / m68k / include / asm / string.h
1 #ifndef _M68K_STRING_H_
2 #define _M68K_STRING_H_
3
4 #include <linux/types.h>
5 #include <linux/compiler.h>
6
7 static inline size_t __kernel_strlen(const char *s)
8 {
9         const char *sc;
10
11         for (sc = s; *sc++; )
12                 ;
13         return sc - s - 1;
14 }
15
16 static inline char *__kernel_strcpy(char *dest, const char *src)
17 {
18         char *xdest = dest;
19
20         asm volatile ("\n"
21                 "1:     move.b  (%1)+,(%0)+\n"
22                 "       jne     1b"
23                 : "+a" (dest), "+a" (src)
24                 : : "memory");
25         return xdest;
26 }
27
28 #ifndef __IN_STRING_C
29
30 #define __HAVE_ARCH_STRLEN
31 #define strlen(s)       (__builtin_constant_p(s) ?      \
32                          __builtin_strlen(s) :          \
33                          __kernel_strlen(s))
34
35 #define __HAVE_ARCH_STRNLEN
36 static inline size_t strnlen(const char *s, size_t count)
37 {
38         const char *sc = s;
39
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;
49 }
50
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)
63 {
64         char *xdest = dest;
65
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;
76 }
77
78 #define __HAVE_ARCH_STRCAT
79 #define strcat(d, s)    ({                      \
80         char *__d = (d);                        \
81         strcpy(__d + strlen(__d), (s));         \
82 })
83
84 #define __HAVE_ARCH_STRCHR
85 static inline char *strchr(const char *s, int c)
86 {
87         char sc, ch = c;
88
89         for (; (sc = *s++) != ch; ) {
90                 if (!sc)
91                         return NULL;
92         }
93         return (char *)s - 1;
94 }
95
96 #ifndef CONFIG_COLDFIRE
97 #define __HAVE_ARCH_STRCMP
98 static inline int strcmp(const char *cs, const char *ct)
99 {
100         char res;
101
102         asm ("\n"
103                 "1:     move.b  (%0)+,%2\n"     /* get *cs */
104                 "       cmp.b   (%1)+,%2\n"     /* compare a byte */
105                 "       jne     2f\n"           /* not equal, break out */
106                 "       tst.b   %2\n"           /* at end of cs? */
107                 "       jne     1b\n"           /* no, keep going */
108                 "       jra     3f\n"           /* strings are equal */
109                 "2:     sub.b   -(%1),%2\n"     /* *cs - *ct */
110                 "3:"
111                 : "+a" (cs), "+a" (ct), "=d" (res));
112         return res;
113 }
114
115 #define __HAVE_ARCH_MEMMOVE
116 extern void *memmove(void *, const void *, __kernel_size_t);
117
118 #define __HAVE_ARCH_MEMCMP
119 extern int memcmp(const void *, const void *, __kernel_size_t);
120 #define memcmp(d, s, n) __builtin_memcmp(d, s, n)
121 #endif /* CONFIG_COLDFIRE */
122
123 #define __HAVE_ARCH_MEMSET
124 extern void *memset(void *, int, __kernel_size_t);
125 #define memset(d, c, n) __builtin_memset(d, c, n)
126
127 #define __HAVE_ARCH_MEMCPY
128 extern void *memcpy(void *, const void *, __kernel_size_t);
129 #define memcpy(d, s, n) __builtin_memcpy(d, s, n)
130
131 #endif
132
133 #endif /* _M68K_STRING_H_ */