Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[S390] use compiler builtin versions of strlen/strcpy/strcat

Use builtin variants if gcc 4 or newer is used to compile the kernel.
Generates better code than the asm variants.

Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Heiko Carstens and committed by
Martin Schwidefsky
1edad85b 504665a9

+16
+8
arch/s390/include/asm/string.h
··· 100 100 101 101 static inline char *strcpy(char *dst, const char *src) 102 102 { 103 + #if __GNUC__ < 4 103 104 register int r0 asm("0") = 0; 104 105 char *ret = dst; 105 106 ··· 110 109 : "+&a" (dst), "+&a" (src) : "d" (r0) 111 110 : "cc", "memory"); 112 111 return ret; 112 + #else 113 + return __builtin_strcpy(dst, src); 114 + #endif 113 115 } 114 116 115 117 static inline size_t strlen(const char *s) 116 118 { 119 + #if __GNUC__ < 4 117 120 register unsigned long r0 asm("0") = 0; 118 121 const char *tmp = s; 119 122 ··· 126 121 " jo 0b" 127 122 : "+d" (r0), "+a" (tmp) : : "cc"); 128 123 return r0 - (unsigned long) s; 124 + #else 125 + return __builtin_strlen(s); 126 + #endif 129 127 } 130 128 131 129 static inline size_t strnlen(const char * s, size_t n)
+8
arch/s390/lib/string.c
··· 44 44 */ 45 45 size_t strlen(const char *s) 46 46 { 47 + #if __GNUC__ < 4 47 48 return __strend(s) - s; 49 + #else 50 + return __builtin_strlen(s); 51 + #endif 48 52 } 49 53 EXPORT_SYMBOL(strlen); 50 54 ··· 74 70 */ 75 71 char *strcpy(char *dest, const char *src) 76 72 { 73 + #if __GNUC__ < 4 77 74 register int r0 asm("0") = 0; 78 75 char *ret = dest; 79 76 ··· 83 78 : "+&a" (dest), "+&a" (src) : "d" (r0) 84 79 : "cc", "memory" ); 85 80 return ret; 81 + #else 82 + return __builtin_strcpy(dest, src); 83 + #endif 86 84 } 87 85 EXPORT_SYMBOL(strcpy); 88 86