1 /* Optimized, inlined string functions. S/390 version.
2 Copyright (C) 2000-2014 Free Software Foundation, Inc.
3 Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
4 This file is part of the GNU C Library.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
24 /* The s390 processors can access unaligned multi-byte variables. */
25 #define _STRING_ARCH_unaligned 1
27 /* We only provide optimizations if the user selects them and if
29 #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
30 && defined __GNUC__ && __GNUC__ >= 2
32 #ifndef __STRING_INLINE
33 # ifndef __extern_inline
34 # define __STRING_INLINE inline
36 # define __STRING_INLINE __extern_inline
40 #define _HAVE_STRING_ARCH_strlen 1
41 #ifndef _FORCE_INLINES
42 #define strlen(str) __strlen_g ((str))
44 __STRING_INLINE
size_t __strlen_g (const char *) __asm__ ("strlen");
46 __STRING_INLINE
size_t
47 __strlen_g (const char *__str
)
52 __tmp
= (char *) __str
;
53 __asm__
__volatile__ (" la 0,0\n"
56 : "+&a" (__ptr
), "+&a" (__tmp
) :
57 : "cc", "memory", "0" );
58 return (size_t) (__ptr
- __str
);
62 /* Copy SRC to DEST. */
63 #define _HAVE_STRING_ARCH_strcpy 1
64 #ifndef _FORCE_INLINES
65 #define strcpy(dest, src) __strcpy_g ((dest), (src))
67 __STRING_INLINE
char *__strcpy_g (char *, const char *) __asm ("strcpy");
69 __STRING_INLINE
char *
70 __strcpy_g (char *__dest
, const char *__src
)
74 __asm__
__volatile__ (" la 0,0\n"
77 : "+&a" (__dest
), "+&a" (__src
) :
78 : "cc", "memory", "0" );
83 #define _HAVE_STRING_ARCH_strncpy 1
84 #ifndef _FORCE_INLINES
85 #define strncpy(dest, src, n) __strncpy_g ((dest), (src), (n))
87 __STRING_INLINE
char *__strncpy_g (char *, const char *, size_t)
90 __STRING_INLINE
char *
91 __strncpy_g (char *__dest
, const char *__src
, size_t __n
)
98 __diff
= (size_t) (__dest
- __src
);
99 __ptr
= (char *) __src
;
100 __asm__
__volatile__ (" j 1f\n"
105 #if defined(__s390x__)
113 #if defined(__s390x__)
119 : "+&a" (__ptr
), "+&a" (__n
) : "a" (__diff
)
120 : "cc", "memory", "0" );
126 /* Append SRC onto DEST. */
127 #define _HAVE_STRING_ARCH_strcat 1
128 #ifndef _FORCE_INLINES
129 #define strcat(dest, src) __strcat_g ((dest), (src))
131 __STRING_INLINE
char *__strcat_g (char *, const char *) __asm__ ("strcat");
133 __STRING_INLINE
char *
134 __strcat_g (char *__dest
, const char *__src
)
136 char *__ret
= __dest
;
139 /* Move __ptr to the end of __dest. */
142 __asm__
__volatile__ (" la 0,0\n"
145 : "+&a" (__ptr
), "+&a" (__tmp
) :
148 /* Now do the copy. */
149 __asm__
__volatile__ (" la 0,0\n"
152 : "+&a" (__ptr
), "+&a" (__src
) :
153 : "cc", "memory", "0" );
158 /* Append no more than N characters from SRC onto DEST. */
159 #define _HAVE_STRING_ARCH_strncat 1
160 #ifndef _FORCE_INLINES
161 #define strncat(dest, src, n) __strncat_g ((dest), (src), (n))
163 __STRING_INLINE
char *__strncat_g (char *, const char *, size_t)
166 __STRING_INLINE
char *
167 __strncat_g (char *__dest
, const char *__src
, size_t __n
)
169 char *__ret
= __dest
;
174 /* Move __ptr to the end of __dest. */
177 __asm__
__volatile__ (" la 0,0\n"
180 : "+&a" (__ptr
), "+&a" (__tmp
) :
181 : "cc", "memory", "0" );
183 __diff
= (size_t) (__ptr
- __src
);
184 __tmp
= (char *) __src
;
185 __asm__
__volatile__ (" j 1f\n"
190 #if defined(__s390x__)
198 : "+&a" (__tmp
), "+&a" (__n
) : "a" (__diff
)
199 : "cc", "memory", "0" );
206 /* Search N bytes of S for C. */
207 #define _HAVE_STRING_ARCH_memchr 1
208 #ifndef _FORCE_INLINES
209 __STRING_INLINE
void *
210 memchr (const void *__str
, int __c
, size_t __n
)
214 __tmp
= (char *) __str
;
215 __ptr
= (char *) __tmp
+ __n
;
216 __asm__
__volatile__ (" lhi 0,0xff\n"
223 : "+&a" (__ptr
), "+&a" (__tmp
) : "d" (__c
)
224 : "cc", "memory", "0" );
229 /* Search N bytes of S for C. */
230 #define _HAVE_STRING_ARCH_memchr 1
231 #ifndef _FORCE_INLINES
233 strcmp (const char *__s1
, const char *__s2
)
238 __p1
= (char *) __s1
;
239 __p2
= (char *) __s2
;
240 __asm__
__volatile__ (" slr 0,0\n"
245 : "=d" (__ret
), "+&a" (__p1
), "+&a" (__p2
) :
246 : "cc", "memory", "0" );
247 __ret
= (__ret
== 0) ? 0 : (__ret
== 1) ? -1 : 1;
252 #endif /* Use string inlines && GNU CC. */