s390/lib: use basic blocks for inline assemblies
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Mon, 20 Jun 2016 11:07:42 +0000 (13:07 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 28 Jun 2016 07:32:28 +0000 (09:32 +0200)
Use only simple inline assemblies which consist of a single basic
block if the register asm construct is being used.

Otherwise gcc would generate broken code if the compiler option
--sanitize-coverage=trace-pc would be used.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/lib/string.c

index b647d5ff0ad9cc2de23491c185b6e30481f28a6b..e390bbb16443db59d8a3551b2bdb633ae25c8d83 100644 (file)
@@ -236,6 +236,26 @@ char * strrchr(const char * s, int c)
 }
 EXPORT_SYMBOL(strrchr);
 
+static inline int clcle(const char *s1, unsigned long l1,
+                       const char *s2, unsigned long l2,
+                       int *diff)
+{
+       register unsigned long r2 asm("2") = (unsigned long) s1;
+       register unsigned long r3 asm("3") = (unsigned long) l2;
+       register unsigned long r4 asm("4") = (unsigned long) s2;
+       register unsigned long r5 asm("5") = (unsigned long) l2;
+       int cc;
+
+       asm volatile ("0: clcle %1,%3,0\n"
+                     "   jo    0b\n"
+                     "   ipm   %0\n"
+                     "   srl   %0,28"
+                     : "=&d" (cc), "+a" (r2), "+a" (r3),
+                       "+a" (r4), "+a" (r5) : : "cc");
+       *diff = *(char *)r2 - *(char *)r4;
+       return cc;
+}
+
 /**
  * strstr - Find the first substring in a %NUL terminated string
  * @s1: The string to be searched
@@ -250,18 +270,9 @@ char * strstr(const char * s1,const char * s2)
                return (char *) s1;
        l1 = __strend(s1) - s1;
        while (l1-- >= l2) {
-               register unsigned long r2 asm("2") = (unsigned long) s1;
-               register unsigned long r3 asm("3") = (unsigned long) l2;
-               register unsigned long r4 asm("4") = (unsigned long) s2;
-               register unsigned long r5 asm("5") = (unsigned long) l2;
-               int cc;
-
-               asm volatile ("0: clcle %1,%3,0\n"
-                             "   jo    0b\n"
-                             "   ipm   %0\n"
-                             "   srl   %0,28"
-                             : "=&d" (cc), "+a" (r2), "+a" (r3),
-                               "+a" (r4), "+a" (r5) : : "cc" );
+               int cc, dummy;
+
+               cc = clcle(s1, l1, s2, l2, &dummy);
                if (!cc)
                        return (char *) s1;
                s1++;
@@ -302,20 +313,11 @@ EXPORT_SYMBOL(memchr);
  */
 int memcmp(const void *cs, const void *ct, size_t n)
 {
-       register unsigned long r2 asm("2") = (unsigned long) cs;
-       register unsigned long r3 asm("3") = (unsigned long) n;
-       register unsigned long r4 asm("4") = (unsigned long) ct;
-       register unsigned long r5 asm("5") = (unsigned long) n;
-       int ret;
+       int ret, diff;
 
-       asm volatile ("0: clcle %1,%3,0\n"
-                     "   jo    0b\n"
-                     "   ipm   %0\n"
-                     "   srl   %0,28"
-                     : "=&d" (ret), "+a" (r2), "+a" (r3), "+a" (r4), "+a" (r5)
-                     : : "cc" );
+       ret = clcle(cs, n, ct, n, &diff);
        if (ret)
-               ret = *(char *) r2 - *(char *) r4;
+               ret = diff;
        return ret;
 }
 EXPORT_SYMBOL(memcmp);