| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | #ifndef _M68K_STRING_H_ | 
 | 2 | #define _M68K_STRING_H_ | 
 | 3 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 4 | #include <linux/types.h> | 
 | 5 | #include <linux/compiler.h> | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 6 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 7 | static inline size_t __kernel_strlen(const char *s) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 8 | { | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 9 | 	const char *sc; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 10 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 11 | 	for (sc = s; *sc++; ) | 
 | 12 | 		; | 
 | 13 | 	return sc - s - 1; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 14 | } | 
 | 15 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 16 | static inline char *__kernel_strcpy(char *dest, const char *src) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 17 | { | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 18 | 	char *xdest = dest; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 19 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 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 | } | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 27 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 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; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 76 | } | 
 | 77 |  | 
 | 78 | #define __HAVE_ARCH_STRCAT | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 79 | #define strcat(d, s)	({			\ | 
 | 80 | 	char *__d = (d);			\ | 
 | 81 | 	strcpy(__d + strlen(__d), (s));		\ | 
 | 82 | }) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 83 |  | 
 | 84 | #define __HAVE_ARCH_STRCHR | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 85 | static inline char *strchr(const char *s, int c) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 86 | { | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 87 | 	char sc, ch = c; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 88 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 89 | 	for (; (sc = *s++) != ch; ) { | 
 | 90 | 		if (!sc) | 
 | 91 | 			return NULL; | 
 | 92 | 	} | 
 | 93 | 	return (char *)s - 1; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 94 | } | 
 | 95 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 96 | #define __HAVE_ARCH_STRCMP | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 97 | static inline int strcmp(const char *cs, const char *ct) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 98 | { | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 99 | 	char res; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 100 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 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; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 112 | } | 
 | 113 |  | 
 | 114 | #define __HAVE_ARCH_MEMSET | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 115 | extern void *memset(void *, int, __kernel_size_t); | 
 | 116 | #define memset(d, c, n) __builtin_memset(d, c, n) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 117 |  | 
 | 118 | #define __HAVE_ARCH_MEMCPY | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 119 | extern void *memcpy(void *, const void *, __kernel_size_t); | 
 | 120 | #define memcpy(d, s, n) __builtin_memcpy(d, s, n) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 121 |  | 
 | 122 | #define __HAVE_ARCH_MEMMOVE | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 123 | extern void *memmove(void *, const void *, __kernel_size_t); | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 124 |  | 
 | 125 | #define __HAVE_ARCH_MEMCMP | 
| Roman Zippel | 072dffd | 2005-09-03 15:57:10 -0700 | [diff] [blame] | 126 | extern int memcmp(const void *, const void *, __kernel_size_t); | 
 | 127 | #define memcmp(d, s, n) __builtin_memcmp(d, s, n) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 128 |  | 
| Roman Zippel | d6359fd | 2006-10-06 00:43:55 -0700 | [diff] [blame] | 129 | #endif | 
 | 130 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 131 | #endif /* _M68K_STRING_H_ */ |