Loading arch/s390/lib/string.c +75 −56 Original line number Original line Diff line number Diff line Loading @@ -18,22 +18,29 @@ */ */ static inline char *__strend(const char *s) static inline char *__strend(const char *s) { { register unsigned long r0 asm("0") = 0; unsigned long e = 0; asm volatile ("0: srst %0,%1\n" asm volatile( " jo 0b" " lghi 0,0\n" : "+d" (r0), "+a" (s) : : "cc", "memory"); "0: srst %[e],%[s]\n" return (char *) r0; " jo 0b\n" : [e] "+&a" (e), [s] "+&a" (s) : : "cc", "memory", "0"); return (char *)e; } } static inline char *__strnend(const char *s, size_t n) static inline char *__strnend(const char *s, size_t n) { { register unsigned long r0 asm("0") = 0; const char *p = s + n; const char *p = s + n; asm volatile ("0: srst %0,%1\n" asm volatile( " jo 0b" " lghi 0,0\n" : "+d" (p), "+a" (s) : "d" (r0) : "cc", "memory"); "0: srst %[p],%[s]\n" " jo 0b\n" : [p] "+&d" (p), [s] "+&a" (s) : : "cc", "memory", "0"); return (char *)p; return (char *)p; } } Loading Loading @@ -76,13 +83,15 @@ EXPORT_SYMBOL(strnlen); #ifdef __HAVE_ARCH_STRCPY #ifdef __HAVE_ARCH_STRCPY char *strcpy(char *dest, const char *src) char *strcpy(char *dest, const char *src) { { register int r0 asm("0") = 0; char *ret = dest; char *ret = dest; asm volatile ("0: mvst %0,%1\n" asm volatile( " jo 0b" " lghi 0,0\n" : "+&a" (dest), "+&a" (src) : "d" (r0) "0: mvst %[dest],%[src]\n" : "cc", "memory" ); " jo 0b\n" : [dest] "+&a" (dest), [src] "+&a" (src) : : "cc", "memory", "0"); return ret; return ret; } } EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strcpy); Loading Loading @@ -144,16 +153,18 @@ EXPORT_SYMBOL(strncpy); #ifdef __HAVE_ARCH_STRCAT #ifdef __HAVE_ARCH_STRCAT char *strcat(char *dest, const char *src) char *strcat(char *dest, const char *src) { { register int r0 asm("0") = 0; unsigned long dummy = 0; unsigned long dummy; char *ret = dest; char *ret = dest; asm volatile ("0: srst %0,%1\n" asm volatile( " lghi 0,0\n" "0: srst %[dummy],%[dest]\n" " jo 0b\n" " jo 0b\n" "1: mvst %0,%2\n" "1: mvst %[dummy],%[src]\n" " jo 1b" " jo 1b\n" : "=&a" (dummy), "+a" (dest), "+a" (src) : [dummy] "=&a" (dummy), [dest] "+&a" (dest), [src] "+&a" (src) : "d" (r0), "0" (0UL) : "cc", "memory" ); : : "cc", "memory", "0"); return ret; return ret; } } EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strcat); Loading Loading @@ -221,18 +232,20 @@ EXPORT_SYMBOL(strncat); #ifdef __HAVE_ARCH_STRCMP #ifdef __HAVE_ARCH_STRCMP int strcmp(const char *s1, const char *s2) int strcmp(const char *s1, const char *s2) { { register int r0 asm("0") = 0; int ret = 0; int ret = 0; asm volatile ("0: clst %2,%3\n" asm volatile( " lghi 0,0\n" "0: clst %[s1],%[s2]\n" " jo 0b\n" " jo 0b\n" " je 1f\n" " je 1f\n" " ic %0,0(%2)\n" " ic %[ret],0(%[s1])\n" " ic %1,0(%3)\n" " ic 0,0(%[s2])\n" " sr %0,%1\n" " sr %[ret],0\n" "1:" "1:" : "+d" (ret), "+d" (r0), "+a" (s1), "+a" (s2) : [ret] "+&d" (ret), [s1] "+&a" (s1), [s2] "+&a" (s2) : : "cc", "memory"); : : "cc", "memory", "0"); return ret; return ret; } } EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strcmp); Loading Loading @@ -261,18 +274,18 @@ EXPORT_SYMBOL(strrchr); static inline int clcle(const char *s1, unsigned long l1, static inline int clcle(const char *s1, unsigned long l1, const char *s2, unsigned long l2) const char *s2, unsigned long l2) { { register unsigned long r2 asm("2") = (unsigned long) s1; union register_pair r1 = { .even = (unsigned long)s1, .odd = l1, }; register unsigned long r3 asm("3") = (unsigned long) l1; union register_pair r3 = { .even = (unsigned long)s2, .odd = l2, }; register unsigned long r4 asm("4") = (unsigned long) s2; register unsigned long r5 asm("5") = (unsigned long) l2; int cc; int cc; asm volatile ("0: clcle %1,%3,0\n" asm volatile( "0: clcle %[r1],%[r3],0\n" " jo 0b\n" " jo 0b\n" " ipm %0\n" " ipm %[cc]\n" " srl %0,28" " srl %[cc],28\n" : "=&d" (cc), "+a" (r2), "+a" (r3), : [cc] "=&d" (cc), [r1] "+&d" (r1.pair), [r3] "+&d" (r3.pair) "+a" (r4), "+a" (r5) : : "cc", "memory"); : : "cc", "memory"); return cc; return cc; } } Loading Loading @@ -315,15 +328,18 @@ EXPORT_SYMBOL(strstr); #ifdef __HAVE_ARCH_MEMCHR #ifdef __HAVE_ARCH_MEMCHR void *memchr(const void *s, int c, size_t n) void *memchr(const void *s, int c, size_t n) { { register int r0 asm("0") = (char) c; const void *ret = s + n; const void *ret = s + n; asm volatile ("0: srst %0,%1\n" asm volatile( " lgr 0,%[c]\n" "0: srst %[ret],%[s]\n" " jo 0b\n" " jo 0b\n" " jl 1f\n" " jl 1f\n" " la %0,0\n" " la %[ret],0\n" "1:" "1:" : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); : [ret] "+&a" (ret), [s] "+&a" (s) : [c] "d" (c) : "cc", "memory", "0"); return (void *) ret; return (void *) ret; } } EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memchr); Loading Loading @@ -360,12 +376,15 @@ EXPORT_SYMBOL(memcmp); #ifdef __HAVE_ARCH_MEMSCAN #ifdef __HAVE_ARCH_MEMSCAN void *memscan(void *s, int c, size_t n) void *memscan(void *s, int c, size_t n) { { register int r0 asm("0") = (char) c; const void *ret = s + n; const void *ret = s + n; asm volatile ("0: srst %0,%1\n" asm volatile( " lgr 0,%[c]\n" "0: srst %[ret],%[s]\n" " jo 0b\n" " jo 0b\n" : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); : [ret] "+&a" (ret), [s] "+&a" (s) : [c] "d" (c) : "cc", "memory", "0"); return (void *)ret; return (void *)ret; } } EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memscan); Loading Loading
arch/s390/lib/string.c +75 −56 Original line number Original line Diff line number Diff line Loading @@ -18,22 +18,29 @@ */ */ static inline char *__strend(const char *s) static inline char *__strend(const char *s) { { register unsigned long r0 asm("0") = 0; unsigned long e = 0; asm volatile ("0: srst %0,%1\n" asm volatile( " jo 0b" " lghi 0,0\n" : "+d" (r0), "+a" (s) : : "cc", "memory"); "0: srst %[e],%[s]\n" return (char *) r0; " jo 0b\n" : [e] "+&a" (e), [s] "+&a" (s) : : "cc", "memory", "0"); return (char *)e; } } static inline char *__strnend(const char *s, size_t n) static inline char *__strnend(const char *s, size_t n) { { register unsigned long r0 asm("0") = 0; const char *p = s + n; const char *p = s + n; asm volatile ("0: srst %0,%1\n" asm volatile( " jo 0b" " lghi 0,0\n" : "+d" (p), "+a" (s) : "d" (r0) : "cc", "memory"); "0: srst %[p],%[s]\n" " jo 0b\n" : [p] "+&d" (p), [s] "+&a" (s) : : "cc", "memory", "0"); return (char *)p; return (char *)p; } } Loading Loading @@ -76,13 +83,15 @@ EXPORT_SYMBOL(strnlen); #ifdef __HAVE_ARCH_STRCPY #ifdef __HAVE_ARCH_STRCPY char *strcpy(char *dest, const char *src) char *strcpy(char *dest, const char *src) { { register int r0 asm("0") = 0; char *ret = dest; char *ret = dest; asm volatile ("0: mvst %0,%1\n" asm volatile( " jo 0b" " lghi 0,0\n" : "+&a" (dest), "+&a" (src) : "d" (r0) "0: mvst %[dest],%[src]\n" : "cc", "memory" ); " jo 0b\n" : [dest] "+&a" (dest), [src] "+&a" (src) : : "cc", "memory", "0"); return ret; return ret; } } EXPORT_SYMBOL(strcpy); EXPORT_SYMBOL(strcpy); Loading Loading @@ -144,16 +153,18 @@ EXPORT_SYMBOL(strncpy); #ifdef __HAVE_ARCH_STRCAT #ifdef __HAVE_ARCH_STRCAT char *strcat(char *dest, const char *src) char *strcat(char *dest, const char *src) { { register int r0 asm("0") = 0; unsigned long dummy = 0; unsigned long dummy; char *ret = dest; char *ret = dest; asm volatile ("0: srst %0,%1\n" asm volatile( " lghi 0,0\n" "0: srst %[dummy],%[dest]\n" " jo 0b\n" " jo 0b\n" "1: mvst %0,%2\n" "1: mvst %[dummy],%[src]\n" " jo 1b" " jo 1b\n" : "=&a" (dummy), "+a" (dest), "+a" (src) : [dummy] "=&a" (dummy), [dest] "+&a" (dest), [src] "+&a" (src) : "d" (r0), "0" (0UL) : "cc", "memory" ); : : "cc", "memory", "0"); return ret; return ret; } } EXPORT_SYMBOL(strcat); EXPORT_SYMBOL(strcat); Loading Loading @@ -221,18 +232,20 @@ EXPORT_SYMBOL(strncat); #ifdef __HAVE_ARCH_STRCMP #ifdef __HAVE_ARCH_STRCMP int strcmp(const char *s1, const char *s2) int strcmp(const char *s1, const char *s2) { { register int r0 asm("0") = 0; int ret = 0; int ret = 0; asm volatile ("0: clst %2,%3\n" asm volatile( " lghi 0,0\n" "0: clst %[s1],%[s2]\n" " jo 0b\n" " jo 0b\n" " je 1f\n" " je 1f\n" " ic %0,0(%2)\n" " ic %[ret],0(%[s1])\n" " ic %1,0(%3)\n" " ic 0,0(%[s2])\n" " sr %0,%1\n" " sr %[ret],0\n" "1:" "1:" : "+d" (ret), "+d" (r0), "+a" (s1), "+a" (s2) : [ret] "+&d" (ret), [s1] "+&a" (s1), [s2] "+&a" (s2) : : "cc", "memory"); : : "cc", "memory", "0"); return ret; return ret; } } EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strcmp); Loading Loading @@ -261,18 +274,18 @@ EXPORT_SYMBOL(strrchr); static inline int clcle(const char *s1, unsigned long l1, static inline int clcle(const char *s1, unsigned long l1, const char *s2, unsigned long l2) const char *s2, unsigned long l2) { { register unsigned long r2 asm("2") = (unsigned long) s1; union register_pair r1 = { .even = (unsigned long)s1, .odd = l1, }; register unsigned long r3 asm("3") = (unsigned long) l1; union register_pair r3 = { .even = (unsigned long)s2, .odd = l2, }; register unsigned long r4 asm("4") = (unsigned long) s2; register unsigned long r5 asm("5") = (unsigned long) l2; int cc; int cc; asm volatile ("0: clcle %1,%3,0\n" asm volatile( "0: clcle %[r1],%[r3],0\n" " jo 0b\n" " jo 0b\n" " ipm %0\n" " ipm %[cc]\n" " srl %0,28" " srl %[cc],28\n" : "=&d" (cc), "+a" (r2), "+a" (r3), : [cc] "=&d" (cc), [r1] "+&d" (r1.pair), [r3] "+&d" (r3.pair) "+a" (r4), "+a" (r5) : : "cc", "memory"); : : "cc", "memory"); return cc; return cc; } } Loading Loading @@ -315,15 +328,18 @@ EXPORT_SYMBOL(strstr); #ifdef __HAVE_ARCH_MEMCHR #ifdef __HAVE_ARCH_MEMCHR void *memchr(const void *s, int c, size_t n) void *memchr(const void *s, int c, size_t n) { { register int r0 asm("0") = (char) c; const void *ret = s + n; const void *ret = s + n; asm volatile ("0: srst %0,%1\n" asm volatile( " lgr 0,%[c]\n" "0: srst %[ret],%[s]\n" " jo 0b\n" " jo 0b\n" " jl 1f\n" " jl 1f\n" " la %0,0\n" " la %[ret],0\n" "1:" "1:" : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); : [ret] "+&a" (ret), [s] "+&a" (s) : [c] "d" (c) : "cc", "memory", "0"); return (void *) ret; return (void *) ret; } } EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(memchr); Loading Loading @@ -360,12 +376,15 @@ EXPORT_SYMBOL(memcmp); #ifdef __HAVE_ARCH_MEMSCAN #ifdef __HAVE_ARCH_MEMSCAN void *memscan(void *s, int c, size_t n) void *memscan(void *s, int c, size_t n) { { register int r0 asm("0") = (char) c; const void *ret = s + n; const void *ret = s + n; asm volatile ("0: srst %0,%1\n" asm volatile( " lgr 0,%[c]\n" "0: srst %[ret],%[s]\n" " jo 0b\n" " jo 0b\n" : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); : [ret] "+&a" (ret), [s] "+&a" (s) : [c] "d" (c) : "cc", "memory", "0"); return (void *)ret; return (void *)ret; } } EXPORT_SYMBOL(memscan); EXPORT_SYMBOL(memscan); Loading