aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2016-06-20 07:07:42 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2016-06-28 03:32:28 -0400
commitdb7f5eef3dc0866320a4a92c38c58d6fb8dfdd34 (patch)
tree577dc19dc3530b3bd0d9df2f057975bdf3b00b45
parentdc4aace160165bd15400a79f9f5ab97405278f48 (diff)
s390/lib: use basic blocks for inline assemblies
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>
-rw-r--r--arch/s390/lib/string.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c
index b647d5ff0ad9..e390bbb16443 100644
--- a/arch/s390/lib/string.c
+++ b/arch/s390/lib/string.c
@@ -236,6 +236,26 @@ char * strrchr(const char * s, int c)
236} 236}
237EXPORT_SYMBOL(strrchr); 237EXPORT_SYMBOL(strrchr);
238 238
239static inline int clcle(const char *s1, unsigned long l1,
240 const char *s2, unsigned long l2,
241 int *diff)
242{
243 register unsigned long r2 asm("2") = (unsigned long) s1;
244 register unsigned long r3 asm("3") = (unsigned long) l2;
245 register unsigned long r4 asm("4") = (unsigned long) s2;
246 register unsigned long r5 asm("5") = (unsigned long) l2;
247 int cc;
248
249 asm volatile ("0: clcle %1,%3,0\n"
250 " jo 0b\n"
251 " ipm %0\n"
252 " srl %0,28"
253 : "=&d" (cc), "+a" (r2), "+a" (r3),
254 "+a" (r4), "+a" (r5) : : "cc");
255 *diff = *(char *)r2 - *(char *)r4;
256 return cc;
257}
258
239/** 259/**
240 * strstr - Find the first substring in a %NUL terminated string 260 * strstr - Find the first substring in a %NUL terminated string
241 * @s1: The string to be searched 261 * @s1: The string to be searched
@@ -250,18 +270,9 @@ char * strstr(const char * s1,const char * s2)
250 return (char *) s1; 270 return (char *) s1;
251 l1 = __strend(s1) - s1; 271 l1 = __strend(s1) - s1;
252 while (l1-- >= l2) { 272 while (l1-- >= l2) {
253 register unsigned long r2 asm("2") = (unsigned long) s1; 273 int cc, dummy;
254 register unsigned long r3 asm("3") = (unsigned long) l2; 274
255 register unsigned long r4 asm("4") = (unsigned long) s2; 275 cc = clcle(s1, l1, s2, l2, &dummy);
256 register unsigned long r5 asm("5") = (unsigned long) l2;
257 int cc;
258
259 asm volatile ("0: clcle %1,%3,0\n"
260 " jo 0b\n"
261 " ipm %0\n"
262 " srl %0,28"
263 : "=&d" (cc), "+a" (r2), "+a" (r3),
264 "+a" (r4), "+a" (r5) : : "cc" );
265 if (!cc) 276 if (!cc)
266 return (char *) s1; 277 return (char *) s1;
267 s1++; 278 s1++;
@@ -302,20 +313,11 @@ EXPORT_SYMBOL(memchr);
302 */ 313 */
303int memcmp(const void *cs, const void *ct, size_t n) 314int memcmp(const void *cs, const void *ct, size_t n)
304{ 315{
305 register unsigned long r2 asm("2") = (unsigned long) cs; 316 int ret, diff;
306 register unsigned long r3 asm("3") = (unsigned long) n;
307 register unsigned long r4 asm("4") = (unsigned long) ct;
308 register unsigned long r5 asm("5") = (unsigned long) n;
309 int ret;
310 317
311 asm volatile ("0: clcle %1,%3,0\n" 318 ret = clcle(cs, n, ct, n, &diff);
312 " jo 0b\n"
313 " ipm %0\n"
314 " srl %0,28"
315 : "=&d" (ret), "+a" (r2), "+a" (r3), "+a" (r4), "+a" (r5)
316 : : "cc" );
317 if (ret) 319 if (ret)
318 ret = *(char *) r2 - *(char *) r4; 320 ret = diff;
319 return ret; 321 return ret;
320} 322}
321EXPORT_SYMBOL(memcmp); 323EXPORT_SYMBOL(memcmp);