1 #ifndef _M68K_STRING_H_
2 #define _M68K_STRING_H_
3 
4 #include <linux/types.h>
5 #include <linux/compiler.h>
6 
__kernel_strlen(const char * s)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 
__kernel_strcpy(char * dest,const char * src)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
strnlen(const char * s,size_t count)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
strncpy(char * dest,const char * src,size_t n)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 #ifndef CONFIG_COLDFIRE
85 #define __HAVE_ARCH_STRCMP
strcmp(const char * cs,const char * ct)86 static inline int strcmp(const char *cs, const char *ct)
87 {
88 	char res;
89 
90 	asm ("\n"
91 		"1:	move.b	(%0)+,%2\n"	/* get *cs */
92 		"	cmp.b	(%1)+,%2\n"	/* compare a byte */
93 		"	jne	2f\n"		/* not equal, break out */
94 		"	tst.b	%2\n"		/* at end of cs? */
95 		"	jne	1b\n"		/* no, keep going */
96 		"	jra	3f\n"		/* strings are equal */
97 		"2:	sub.b	-(%1),%2\n"	/* *cs - *ct */
98 		"3:"
99 		: "+a" (cs), "+a" (ct), "=d" (res));
100 	return res;
101 }
102 #endif /* CONFIG_COLDFIRE */
103 
104 #define __HAVE_ARCH_MEMMOVE
105 extern void *memmove(void *, const void *, __kernel_size_t);
106 
107 #define memcmp(d, s, n) __builtin_memcmp(d, s, n)
108 
109 #define __HAVE_ARCH_MEMSET
110 extern void *memset(void *, int, __kernel_size_t);
111 #define memset(d, c, n) __builtin_memset(d, c, n)
112 
113 #define __HAVE_ARCH_MEMCPY
114 extern void *memcpy(void *, const void *, __kernel_size_t);
115 #define memcpy(d, s, n) __builtin_memcpy(d, s, n)
116 
117 #endif
118 
119 #endif /* _M68K_STRING_H_ */
120