diff options
Diffstat (limited to 'arch/m68k/include/asm/string.h')
-rw-r--r-- | arch/m68k/include/asm/string.h | 134 |
1 files changed, 131 insertions, 3 deletions
diff --git a/arch/m68k/include/asm/string.h b/arch/m68k/include/asm/string.h index 2c356f90f171..2936dda938d7 100644 --- a/arch/m68k/include/asm/string.h +++ b/arch/m68k/include/asm/string.h @@ -1,5 +1,133 @@ -#ifdef __uClinux__ -#include "string_no.h" +#ifndef _M68K_STRING_H_ +#define _M68K_STRING_H_ + +#include <linux/types.h> +#include <linux/compiler.h> + +static inline size_t __kernel_strlen(const char *s) +{ + const char *sc; + + for (sc = s; *sc++; ) + ; + return sc - s - 1; +} + +static inline char *__kernel_strcpy(char *dest, const char *src) +{ + char *xdest = dest; + + asm volatile ("\n" + "1: move.b (%1)+,(%0)+\n" + " jne 1b" + : "+a" (dest), "+a" (src) + : : "memory"); + return xdest; +} + +#ifndef __IN_STRING_C + +#define __HAVE_ARCH_STRLEN +#define strlen(s) (__builtin_constant_p(s) ? \ + __builtin_strlen(s) : \ + __kernel_strlen(s)) + +#define __HAVE_ARCH_STRNLEN +static inline size_t strnlen(const char *s, size_t count) +{ + const char *sc = s; + + asm volatile ("\n" + "1: subq.l #1,%1\n" + " jcs 2f\n" + " tst.b (%0)+\n" + " jne 1b\n" + " subq.l #1,%0\n" + "2:" + : "+a" (sc), "+d" (count)); + return sc - s; +} + +#define __HAVE_ARCH_STRCPY +#if __GNUC__ >= 4 +#define strcpy(d, s) (__builtin_constant_p(s) && \ + __builtin_strlen(s) <= 32 ? \ + __builtin_strcpy(d, s) : \ + __kernel_strcpy(d, s)) #else -#include "string_mm.h" +#define strcpy(d, s) __kernel_strcpy(d, s) #endif + +#define __HAVE_ARCH_STRNCPY +static inline char *strncpy(char *dest, const char *src, size_t n) +{ + char *xdest = dest; + + asm volatile ("\n" + " jra 2f\n" + "1: move.b (%1),(%0)+\n" + " jeq 2f\n" + " addq.l #1,%1\n" + "2: subq.l #1,%2\n" + " jcc 1b\n" + : "+a" (dest), "+a" (src), "+d" (n) + : : "memory"); + return xdest; +} + +#define __HAVE_ARCH_STRCAT +#define strcat(d, s) ({ \ + char *__d = (d); \ + strcpy(__d + strlen(__d), (s)); \ +}) + +#define __HAVE_ARCH_STRCHR +static inline char *strchr(const char *s, int c) +{ + char sc, ch = c; + + for (; (sc = *s++) != ch; ) { + if (!sc) + return NULL; + } + return (char *)s - 1; +} + +#ifndef CONFIG_COLDFIRE +#define __HAVE_ARCH_STRCMP +static inline int strcmp(const char *cs, const char *ct) +{ + char res; + + asm ("\n" + "1: move.b (%0)+,%2\n" /* get *cs */ + " cmp.b (%1)+,%2\n" /* compare a byte */ + " jne 2f\n" /* not equal, break out */ + " tst.b %2\n" /* at end of cs? */ + " jne 1b\n" /* no, keep going */ + " jra 3f\n" /* strings are equal */ + "2: sub.b -(%1),%2\n" /* *cs - *ct */ + "3:" + : "+a" (cs), "+a" (ct), "=d" (res)); + return res; +} + +#define __HAVE_ARCH_MEMMOVE +extern void *memmove(void *, const void *, __kernel_size_t); + +#define __HAVE_ARCH_MEMCMP +extern int memcmp(const void *, const void *, __kernel_size_t); +#define memcmp(d, s, n) __builtin_memcmp(d, s, n) +#endif /* CONFIG_COLDFIRE */ + +#define __HAVE_ARCH_MEMSET +extern void *memset(void *, int, __kernel_size_t); +#define memset(d, c, n) __builtin_memset(d, c, n) + +#define __HAVE_ARCH_MEMCPY +extern void *memcpy(void *, const void *, __kernel_size_t); +#define memcpy(d, s, n) __builtin_memcpy(d, s, n) + +#endif + +#endif /* _M68K_STRING_H_ */ |