]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/s390/bits/string.h
Update copyright dates with scripts/update-copyrights.
[thirdparty/glibc.git] / sysdeps / s390 / bits / string.h
CommitLineData
0a51f0ac 1/* Optimized, inlined string functions. S/390 version.
bfff8b1b 2 Copyright (C) 2000-2017 Free Software Foundation, Inc.
0a51f0ac
UD
3 Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
4 This file is part of the GNU C Library.
5
6 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
0a51f0ac
UD
10
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
41bdb6e2
AJ
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
0a51f0ac 15
41bdb6e2 16 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
0a51f0ac
UD
19
20#ifndef _STRING_H
21# error "Never use <bits/string.h> directly; include <string.h> instead."
22#endif
23
16396c41
L
24/* Use the unaligned string inline ABI. */
25#define _STRING_INLINE_unaligned 1
0a51f0ac
UD
26
27/* We only provide optimizations if the user selects them and if
28 GNU CC is used. */
29#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
30 && defined __GNUC__ && __GNUC__ >= 2
31
32#ifndef __STRING_INLINE
de1c3ebb 33# ifndef __extern_inline
0a51f0ac
UD
34# define __STRING_INLINE inline
35# else
b037a293 36# define __STRING_INLINE __extern_inline
0a51f0ac
UD
37# endif
38#endif
39
40#define _HAVE_STRING_ARCH_strlen 1
41#ifndef _FORCE_INLINES
37143323
UD
42#define strlen(str) __strlen_g ((str))
43
a784e502 44__STRING_INLINE size_t __strlen_g (const char *) __asm__ ("strlen");
a78814a9 45
0a51f0ac 46__STRING_INLINE size_t
a784e502 47__strlen_g (const char *__str)
0a51f0ac
UD
48{
49 char *__ptr, *__tmp;
50
51 __ptr = (char *) 0;
52 __tmp = (char *) __str;
53 __asm__ __volatile__ (" la 0,0\n"
54 "0: srst %0,%1\n"
55 " jo 0b\n"
a784e502 56 : "+&a" (__ptr), "+&a" (__tmp) :
1bc97733 57 : "cc", "memory", "0" );
0a51f0ac
UD
58 return (size_t) (__ptr - __str);
59}
60#endif
61
62/* Copy SRC to DEST. */
63#define _HAVE_STRING_ARCH_strcpy 1
64#ifndef _FORCE_INLINES
37143323
UD
65#define strcpy(dest, src) __strcpy_g ((dest), (src))
66
31cf3942 67__STRING_INLINE char *__strcpy_g (char *, const char *) __asm__ ("strcpy");
a78814a9 68
0a51f0ac 69__STRING_INLINE char *
a784e502 70__strcpy_g (char *__dest, const char *__src)
0a51f0ac
UD
71{
72 char *tmp = __dest;
73
74 __asm__ __volatile__ (" la 0,0\n"
75 "0: mvst %0,%1\n"
76 " jo 0b"
77 : "+&a" (__dest), "+&a" (__src) :
78 : "cc", "memory", "0" );
79 return tmp;
80}
81#endif
82
83#define _HAVE_STRING_ARCH_strncpy 1
84#ifndef _FORCE_INLINES
37143323
UD
85#define strncpy(dest, src, n) __strncpy_g ((dest), (src), (n))
86
a784e502 87__STRING_INLINE char *__strncpy_g (char *, const char *, size_t)
a78814a9
UD
88 __asm__ ("strncpy");
89
0a51f0ac 90__STRING_INLINE char *
a784e502 91__strncpy_g (char *__dest, const char *__src, size_t __n)
0a51f0ac
UD
92{
93 char *__ret = __dest;
94 char *__ptr;
95 size_t __diff;
96
97 if (__n > 0) {
98 __diff = (size_t) (__dest - __src);
99 __ptr = (char *) __src;
100 __asm__ __volatile__ (" j 1f\n"
a784e502
UD
101 "0: la %0,1(%0)\n"
102 "1: icm 0,1,0(%0)\n"
103 " stc 0,0(%2,%0)\n"
104 " jz 3f\n"
0a51f0ac 105#if defined(__s390x__)
a784e502 106 " brctg %1,0b\n"
0a51f0ac 107#else
a784e502 108 " brct %1,0b\n"
0a51f0ac 109#endif
a784e502
UD
110 " j 4f\n"
111 "2: la %0,1(%0)\n"
112 " stc 0,0(%2,%0)\n"
0a51f0ac 113#if defined(__s390x__)
a784e502 114 "3: brctg %1,2b\n"
0a51f0ac 115#else
a784e502 116 "3: brct %1,2b\n"
0a51f0ac 117#endif
a784e502
UD
118 "4:"
119 : "+&a" (__ptr), "+&a" (__n) : "a" (__diff)
120 : "cc", "memory", "0" );
0a51f0ac
UD
121 }
122 return __ret;
123}
124#endif
125
126/* Append SRC onto DEST. */
127#define _HAVE_STRING_ARCH_strcat 1
128#ifndef _FORCE_INLINES
37143323
UD
129#define strcat(dest, src) __strcat_g ((dest), (src))
130
a784e502 131__STRING_INLINE char *__strcat_g (char *, const char *) __asm__ ("strcat");
a78814a9 132
0a51f0ac 133__STRING_INLINE char *
a784e502 134__strcat_g (char *__dest, const char *__src)
0a51f0ac
UD
135{
136 char *__ret = __dest;
137 char *__ptr, *__tmp;
138
139 /* Move __ptr to the end of __dest. */
140 __ptr = (char *) 0;
141 __tmp = __dest;
142 __asm__ __volatile__ (" la 0,0\n"
143 "0: srst %0,%1\n"
144 " jo 0b\n"
145 : "+&a" (__ptr), "+&a" (__tmp) :
146 : "cc", "0" );
147
148 /* Now do the copy. */
149 __asm__ __volatile__ (" la 0,0\n"
150 "0: mvst %0,%1\n"
151 " jo 0b"
152 : "+&a" (__ptr), "+&a" (__src) :
1bc97733 153 : "cc", "memory", "0" );
0a51f0ac
UD
154 return __ret;
155}
156#endif
157
158/* Append no more than N characters from SRC onto DEST. */
159#define _HAVE_STRING_ARCH_strncat 1
160#ifndef _FORCE_INLINES
37143323
UD
161#define strncat(dest, src, n) __strncat_g ((dest), (src), (n))
162
a784e502 163__STRING_INLINE char *__strncat_g (char *, const char *, size_t)
a78814a9
UD
164 __asm__ ("strncat");
165
0a51f0ac 166__STRING_INLINE char *
a784e502 167__strncat_g (char *__dest, const char *__src, size_t __n)
0a51f0ac
UD
168{
169 char *__ret = __dest;
170 char *__ptr, *__tmp;
171 size_t __diff;
172
173 if (__n > 0) {
174 /* Move __ptr to the end of __dest. */
175 __ptr = (char *) 0;
176 __tmp = __dest;
177 __asm__ __volatile__ (" la 0,0\n"
178 "0: srst %0,%1\n"
179 " jo 0b\n"
180 : "+&a" (__ptr), "+&a" (__tmp) :
1bc97733 181 : "cc", "memory", "0" );
0a51f0ac
UD
182
183 __diff = (size_t) (__ptr - __src);
184 __tmp = (char *) __src;
185 __asm__ __volatile__ (" j 1f\n"
a784e502
UD
186 "0: la %0,1(%0)\n"
187 "1: icm 0,1,0(%0)\n"
188 " stc 0,0(%2,%0)\n"
189 " jz 2f\n"
0a51f0ac 190#if defined(__s390x__)
a784e502 191 " brctg %1,0b\n"
0a51f0ac 192#else
a784e502 193 " brct %1,0b\n"
0a51f0ac
UD
194#endif
195 " slr 0,0\n"
a784e502 196 " stc 0,1(%2,%0)\n"
0a51f0ac 197 "2:"
a784e502
UD
198 : "+&a" (__tmp), "+&a" (__n) : "a" (__diff)
199 : "cc", "memory", "0" );
0a51f0ac
UD
200
201 }
202 return __ret;
203}
204#endif
205
206/* Search N bytes of S for C. */
207#define _HAVE_STRING_ARCH_memchr 1
208#ifndef _FORCE_INLINES
209__STRING_INLINE void *
a784e502 210memchr (const void *__str, int __c, size_t __n)
0a51f0ac
UD
211{
212 char *__ptr, *__tmp;
213
214 __tmp = (char *) __str;
215 __ptr = (char *) __tmp + __n;
216 __asm__ __volatile__ (" lhi 0,0xff\n"
217 " nr 0,%2\n"
218 "0: srst %0,%1\n"
219 " jo 0b\n"
a784e502
UD
220 " brc 13,1f\n"
221 " la %0,0\n"
222 "1:"
0a51f0ac 223 : "+&a" (__ptr), "+&a" (__tmp) : "d" (__c)
1bc97733 224 : "cc", "memory", "0" );
0a51f0ac
UD
225 return __ptr;
226}
227#endif
228
63724a6d
SL
229/* Compare S1 and S2. */
230#define _HAVE_STRING_ARCH_strcmp 1
0a51f0ac
UD
231#ifndef _FORCE_INLINES
232__STRING_INLINE int
a784e502 233strcmp (const char *__s1, const char *__s2)
0a51f0ac
UD
234{
235 char *__p1, *__p2;
236 int __ret;
237
238 __p1 = (char *) __s1;
239 __p2 = (char *) __s2;
240 __asm__ __volatile__ (" slr 0,0\n"
a784e502 241 "0: clst %1,%2\n"
0a51f0ac
UD
242 " jo 0b\n"
243 " ipm %0\n"
244 " srl %0,28"
a784e502 245 : "=d" (__ret), "+&a" (__p1), "+&a" (__p2) :
1bc97733 246 : "cc", "memory", "0" );
0a51f0ac
UD
247 __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
248 return __ret;
249}
250#endif
251
252#endif /* Use string inlines && GNU CC. */