#include <linux/types.h>
#endif
-#define __HAVE_ARCH_MEMCHR
-#define __HAVE_ARCH_MEMCPY
-#define __HAVE_ARCH_MEMSET
-#define __HAVE_ARCH_STRCAT
-#define __HAVE_ARCH_STRCMP
-#define __HAVE_ARCH_STRCPY
-#define __HAVE_ARCH_STRLEN
-#define __HAVE_ARCH_STRNCPY
+#define __HAVE_ARCH_BCOPY /* arch function */
+#define __HAVE_ARCH_MEMCHR /* inline & arch function */
+#define __HAVE_ARCH_MEMCMP /* arch function */
+#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
+#define __HAVE_ARCH_MEMSCAN /* inline & arch function */
+#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
+#define __HAVE_ARCH_STRCAT /* inline & arch function */
+#define __HAVE_ARCH_STRCMP /* arch function */
+#define __HAVE_ARCH_STRCPY /* inline & arch function */
+#define __HAVE_ARCH_STRLCAT /* arch function */
+#define __HAVE_ARCH_STRLCPY /* arch function */
+#define __HAVE_ARCH_STRLEN /* inline & arch function */
+#define __HAVE_ARCH_STRNCAT /* arch function */
+#define __HAVE_ARCH_STRNCPY /* arch function */
+#define __HAVE_ARCH_STRNLEN /* inline & arch function */
+#define __HAVE_ARCH_STRRCHR /* arch function */
+#define __HAVE_ARCH_STRSTR /* arch function */
+
+/* Prototypes for non-inlined arch strings functions. */
+extern int memcmp(const void *, const void *, size_t);
+extern void *memcpy(void *, const void *, size_t);
+extern void *memset(void *, int, size_t);
+extern int strcmp(const char *,const char *);
+extern size_t strlcat(char *, const char *, size_t);
+extern size_t strlcpy(char *, const char *, size_t);
+extern char *strncat(char *, const char *, size_t);
+extern char *strncpy(char *, const char *, size_t);
+extern char *strrchr(const char *, int);
+extern char *strstr(const char *, const char *);
#undef __HAVE_ARCH_MEMMOVE
-#undef __HAVE_ARCH_STRNICMP
-#undef __HAVE_ARCH_STRNCAT
-#undef __HAVE_ARCH_STRNCMP
#undef __HAVE_ARCH_STRCHR
-#undef __HAVE_ARCH_STRRCHR
-#undef __HAVE_ARCH_STRNLEN
-#undef __HAVE_ARCH_STRSPN
+#undef __HAVE_ARCH_STRNCHR
+#undef __HAVE_ARCH_STRNCMP
+#undef __HAVE_ARCH_STRNICMP
#undef __HAVE_ARCH_STRPBRK
-#undef __HAVE_ARCH_STRTOK
-#undef __HAVE_ARCH_BCOPY
-#undef __HAVE_ARCH_MEMCMP
-#undef __HAVE_ARCH_MEMSCAN
-#undef __HAVE_ARCH_STRSTR
+#undef __HAVE_ARCH_STRSEP
+#undef __HAVE_ARCH_STRSPN
-extern void *memset(void *, int, size_t);
-extern void *memcpy(void *, const void *, size_t);
-extern void *memmove(void *, const void *, size_t);
-extern char *strncpy(char *, const char *, size_t);
-extern int strcmp(const char *,const char *);
+#if !defined(IN_ARCH_STRING_C)
-static inline void * memchr(const void * cs,int c,size_t count)
+static inline void *memchr(const void * s, int c, size_t n)
{
- void *ptr;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " lr 0,%2\n"
- " lr 1,%1\n"
- " la %0,0(%3,%1)\n"
- "0: srst %0,1\n"
- " jo 0b\n"
- " brc 13,1f\n"
- " slr %0,%0\n"
-#else /* __s390x__ */
- " lgr 0,%2\n"
- " lgr 1,%1\n"
- " la %0,0(%3,%1)\n"
- "0: srst %0,1\n"
- " jo 0b\n"
- " brc 13,1f\n"
- " slgr %0,%0\n"
-#endif /* __s390x__ */
- "1:"
- : "=&a" (ptr) : "a" (cs), "d" (c), "d" (count)
- : "cc", "0", "1" );
- return ptr;
+ register int r0 asm("0") = (char) c;
+ const void *ret = s + n;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b\n"
+ " jl 1f\n"
+ " la %0,0\n"
+ "1:"
+ : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+ return (void *) ret;
}
-static __inline__ char *strcpy(char *dest, const char *src)
+static inline void *memscan(void *s, int c, size_t n)
{
- char *tmp = dest;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " sr 0,0\n"
- "0: mvst %0,%1\n"
- " jo 0b"
-#else /* __s390x__ */
- " slgr 0,0\n"
- "0: mvst %0,%1\n"
- " jo 0b"
-#endif /* __s390x__ */
- : "+&a" (dest), "+&a" (src) :
- : "cc", "memory", "0" );
- return tmp;
+ register int r0 asm("0") = (char) c;
+ const void *ret = s + n;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b\n"
+ : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" );
+ return (void *) ret;
}
-static __inline__ size_t strlen(const char *s)
+static inline char *strcat(char *dst, const char *src)
{
- size_t len;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " sr 0,0\n"
- " lr %0,%1\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lr %0,0\n"
- " sr %0,%1"
-#else /* __s390x__ */
- " slgr 0,0\n"
- " lgr %0,%1\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lgr %0,0\n"
- " sgr %0,%1"
-#endif /* __s390x__ */
- : "=&a" (len) : "a" (s)
- : "cc", "0" );
- return len;
+ register int r0 asm("0") = 0;
+ unsigned long dummy;
+ char *ret = dst;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b\n"
+ "1: mvst %0,%2\n"
+ " jo 1b"
+ : "=&a" (dummy), "+a" (dst), "+a" (src)
+ : "d" (r0), "0" (0) : "cc", "memory" );
+ return ret;
}
-static __inline__ char *strcat(char *dest, const char *src)
+static inline char *strcpy(char *dst, const char *src)
{
- char *tmp = dest;
-
- __asm__ __volatile__ (
-#ifndef __s390x__
- " sr 0,0\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lr %0,0\n"
- " sr 0,0\n"
- "1: mvst %0,%1\n"
- " jo 1b"
-#else /* __s390x__ */
- " slgr 0,0\n"
- "0: srst 0,%0\n"
- " jo 0b\n"
- " lgr %0,0\n"
- " slgr 0,0\n"
- "1: mvst %0,%1\n"
- " jo 1b"
-#endif /* __s390x__ */
- : "+&a" (dest), "+&a" (src) :
- : "cc", "memory", "0" );
- return tmp;
+ register int r0 asm("0") = 0;
+ char *ret = dst;
+
+ asm volatile ("0: mvst %0,%1\n"
+ " jo 0b"
+ : "+&a" (dst), "+&a" (src) : "d" (r0)
+ : "cc", "memory" );
+ return ret;
}
-extern void *alloca(size_t);
+static inline size_t strlen(const char *s)
+{
+ register unsigned long r0 asm("0") = 0;
+ const char *tmp = s;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b"
+ : "+d" (r0), "+a" (tmp) : : "cc" );
+ return r0 - (unsigned long) s;
+}
+
+static inline size_t strnlen(const char * s, size_t n)
+{
+ register int r0 asm("0") = 0;
+ const char *tmp = s;
+ const char *end = s + n;
+
+ asm volatile ("0: srst %0,%1\n"
+ " jo 0b"
+ : "+a" (end), "+a" (tmp) : "d" (r0) : "cc" );
+ return end - s;
+}
+
+#endif /* !IN_ARCH_STRING_C */
+
#endif /* __KERNEL__ */
#endif /* __S390_STRING_H_ */