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_ */ 134