diff options
author | Heiko Carstens <heiko.carstens@de.ibm.com> | 2016-06-20 07:07:42 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2016-06-28 03:32:28 -0400 |
commit | db7f5eef3dc0866320a4a92c38c58d6fb8dfdd34 (patch) | |
tree | 577dc19dc3530b3bd0d9df2f057975bdf3b00b45 | |
parent | dc4aace160165bd15400a79f9f5ab97405278f48 (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.c | 50 |
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 | } |
237 | EXPORT_SYMBOL(strrchr); | 237 | EXPORT_SYMBOL(strrchr); |
238 | 238 | ||
239 | static 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 | */ |
303 | int memcmp(const void *cs, const void *ct, size_t n) | 314 | int 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 | } |
321 | EXPORT_SYMBOL(memcmp); | 323 | EXPORT_SYMBOL(memcmp); |