| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 1 | #ifndef _M68K_STRING_H_ | 
 | 2 | #define _M68K_STRING_H_ | 
 | 3 |  | 
 | 4 | #include <linux/types.h> | 
 | 5 | #include <linux/compiler.h> | 
 | 6 |  | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 7 | static inline char *__kernel_strcpy(char *dest, const char *src) | 
 | 8 | { | 
 | 9 | 	char *xdest = dest; | 
 | 10 |  | 
 | 11 | 	asm volatile ("\n" | 
 | 12 | 		"1:	move.b	(%1)+,(%0)+\n" | 
 | 13 | 		"	jne	1b" | 
 | 14 | 		: "+a" (dest), "+a" (src) | 
 | 15 | 		: : "memory"); | 
 | 16 | 	return xdest; | 
 | 17 | } | 
 | 18 |  | 
 | 19 | #ifndef __IN_STRING_C | 
 | 20 |  | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 21 | #define __HAVE_ARCH_STRNLEN | 
 | 22 | static inline size_t strnlen(const char *s, size_t count) | 
 | 23 | { | 
 | 24 | 	const char *sc = s; | 
 | 25 |  | 
 | 26 | 	asm volatile ("\n" | 
 | 27 | 		"1:     subq.l  #1,%1\n" | 
 | 28 | 		"       jcs     2f\n" | 
 | 29 | 		"       tst.b   (%0)+\n" | 
 | 30 | 		"       jne     1b\n" | 
 | 31 | 		"       subq.l  #1,%0\n" | 
 | 32 | 		"2:" | 
 | 33 | 		: "+a" (sc), "+d" (count)); | 
 | 34 | 	return sc - s; | 
 | 35 | } | 
 | 36 |  | 
 | 37 | #define __HAVE_ARCH_STRCPY | 
 | 38 | #if __GNUC__ >= 4 | 
 | 39 | #define strcpy(d, s)	(__builtin_constant_p(s) &&	\ | 
 | 40 | 			 __builtin_strlen(s) <= 32 ?	\ | 
 | 41 | 			 __builtin_strcpy(d, s) :	\ | 
 | 42 | 			 __kernel_strcpy(d, s)) | 
| Sam Ravnborg | 4914802 | 2009-01-16 21:58:10 +1000 | [diff] [blame] | 43 | #else | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 44 | #define strcpy(d, s)	__kernel_strcpy(d, s) | 
| Sam Ravnborg | 4914802 | 2009-01-16 21:58:10 +1000 | [diff] [blame] | 45 | #endif | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 46 |  | 
 | 47 | #define __HAVE_ARCH_STRNCPY | 
 | 48 | static inline char *strncpy(char *dest, const char *src, size_t n) | 
 | 49 | { | 
 | 50 | 	char *xdest = dest; | 
 | 51 |  | 
 | 52 | 	asm volatile ("\n" | 
 | 53 | 		"	jra	2f\n" | 
 | 54 | 		"1:	move.b	(%1),(%0)+\n" | 
 | 55 | 		"	jeq	2f\n" | 
 | 56 | 		"	addq.l	#1,%1\n" | 
 | 57 | 		"2:	subq.l	#1,%2\n" | 
 | 58 | 		"	jcc	1b\n" | 
 | 59 | 		: "+a" (dest), "+a" (src), "+d" (n) | 
 | 60 | 		: : "memory"); | 
 | 61 | 	return xdest; | 
 | 62 | } | 
 | 63 |  | 
 | 64 | #define __HAVE_ARCH_STRCAT | 
 | 65 | #define strcat(d, s)	({			\ | 
 | 66 | 	char *__d = (d);			\ | 
 | 67 | 	strcpy(__d + strlen(__d), (s));		\ | 
 | 68 | }) | 
 | 69 |  | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 70 | #ifndef CONFIG_COLDFIRE | 
 | 71 | #define __HAVE_ARCH_STRCMP | 
 | 72 | static inline int strcmp(const char *cs, const char *ct) | 
 | 73 | { | 
 | 74 | 	char res; | 
 | 75 |  | 
 | 76 | 	asm ("\n" | 
 | 77 | 		"1:	move.b	(%0)+,%2\n"	/* get *cs */ | 
 | 78 | 		"	cmp.b	(%1)+,%2\n"	/* compare a byte */ | 
 | 79 | 		"	jne	2f\n"		/* not equal, break out */ | 
 | 80 | 		"	tst.b	%2\n"		/* at end of cs? */ | 
 | 81 | 		"	jne	1b\n"		/* no, keep going */ | 
 | 82 | 		"	jra	3f\n"		/* strings are equal */ | 
 | 83 | 		"2:	sub.b	-(%1),%2\n"	/* *cs - *ct */ | 
 | 84 | 		"3:" | 
 | 85 | 		: "+a" (cs), "+a" (ct), "=d" (res)); | 
 | 86 | 	return res; | 
 | 87 | } | 
| Greg Ungerer | 982cd25 | 2011-02-03 21:58:39 +1000 | [diff] [blame] | 88 | #endif /* CONFIG_COLDFIRE */ | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 89 |  | 
 | 90 | #define __HAVE_ARCH_MEMMOVE | 
 | 91 | extern void *memmove(void *, const void *, __kernel_size_t); | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 92 |  | 
| Greg Ungerer | f9d693d | 2011-02-03 21:31:20 +1000 | [diff] [blame] | 93 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) | 
 | 94 |  | 
| Greg Ungerer | ea61bc4 | 2010-09-07 14:52:52 +1000 | [diff] [blame] | 95 | #define __HAVE_ARCH_MEMSET | 
 | 96 | extern void *memset(void *, int, __kernel_size_t); | 
 | 97 | #define memset(d, c, n) __builtin_memset(d, c, n) | 
 | 98 |  | 
 | 99 | #define __HAVE_ARCH_MEMCPY | 
 | 100 | extern void *memcpy(void *, const void *, __kernel_size_t); | 
 | 101 | #define memcpy(d, s, n) __builtin_memcpy(d, s, n) | 
 | 102 |  | 
 | 103 | #endif | 
 | 104 |  | 
 | 105 | #endif /* _M68K_STRING_H_ */ |