]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/s390/bits/string.h
2.5-18.1
[thirdparty/glibc.git] / sysdeps / s390 / bits / string.h
CommitLineData
0a51f0ac
UD
1/* Optimized, inlined string functions. S/390 version.
2 Copyright (C) 2000, 2001 Free Software Foundation, Inc.
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
AJ
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
0a51f0ac
UD
20
21#ifndef _STRING_H
22# error "Never use <bits/string.h> directly; include <string.h> instead."
23#endif
24
25/* The s390 processors can access unaligned multi-byte variables. */
26#define _STRING_ARCH_unaligned 1
27
28/* We only provide optimizations if the user selects them and if
29 GNU CC is used. */
30#if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
31 && defined __GNUC__ && __GNUC__ >= 2
32
33#ifndef __STRING_INLINE
34# ifdef __cplusplus
35# define __STRING_INLINE inline
36# else
37# define __STRING_INLINE extern __inline
38# endif
39#endif
40
41#define _HAVE_STRING_ARCH_strlen 1
42#ifndef _FORCE_INLINES
43__STRING_INLINE size_t
44strlen (__const char *__str)
45{
46 char *__ptr, *__tmp;
47
48 __ptr = (char *) 0;
49 __tmp = (char *) __str;
50 __asm__ __volatile__ (" la 0,0\n"
51 "0: srst %0,%1\n"
52 " jo 0b\n"
53 : "+&a" (__ptr), "+&a" (__tmp) :
0ecb606c 54 : "cc", "memory", "0" );
0a51f0ac
UD
55 return (size_t) (__ptr - __str);
56}
57#endif
58
59/* Copy SRC to DEST. */
60#define _HAVE_STRING_ARCH_strcpy 1
61#ifndef _FORCE_INLINES
62__STRING_INLINE char *
63strcpy (char *__dest, __const char *__src)
64{
65 char *tmp = __dest;
66
67 __asm__ __volatile__ (" la 0,0\n"
68 "0: mvst %0,%1\n"
69 " jo 0b"
70 : "+&a" (__dest), "+&a" (__src) :
71 : "cc", "memory", "0" );
72 return tmp;
73}
74#endif
75
76#define _HAVE_STRING_ARCH_strncpy 1
77#ifndef _FORCE_INLINES
78__STRING_INLINE char *
79strncpy (char *__dest, __const char *__src, size_t __n)
80{
81 char *__ret = __dest;
82 char *__ptr;
83 size_t __diff;
84
85 if (__n > 0) {
86 __diff = (size_t) (__dest - __src);
87 __ptr = (char *) __src;
88 __asm__ __volatile__ (" j 1f\n"
89 "0: la %0,1(%0)\n"
90 "1: icm 0,1,0(%0)\n"
91 " stc 0,0(%2,%0)\n"
92 " jz 3f\n"
93#if defined(__s390x__)
94 " brctg %1,0b\n"
95#else
96 " brct %1,0b\n"
97#endif
98 " j 4f\n"
99 "2: la %0,1(%0)\n"
100 " stc 0,0(%2,%0)\n"
101#if defined(__s390x__)
102 "3: brctg %1,2b\n"
103#else
104 "3: brct %1,2b\n"
105#endif
106 "4:"
107 : "+&a" (__ptr), "+&a" (__n) : "a" (__diff)
0ecb606c 108 : "cc", "memory", "0" );
0a51f0ac
UD
109 }
110 return __ret;
111}
112#endif
113
114/* Append SRC onto DEST. */
115#define _HAVE_STRING_ARCH_strcat 1
116#ifndef _FORCE_INLINES
117__STRING_INLINE char *
118strcat(char *__dest, const char *__src)
119{
120 char *__ret = __dest;
121 char *__ptr, *__tmp;
122
123 /* Move __ptr to the end of __dest. */
124 __ptr = (char *) 0;
125 __tmp = __dest;
126 __asm__ __volatile__ (" la 0,0\n"
127 "0: srst %0,%1\n"
128 " jo 0b\n"
129 : "+&a" (__ptr), "+&a" (__tmp) :
130 : "cc", "0" );
131
132 /* Now do the copy. */
133 __asm__ __volatile__ (" la 0,0\n"
134 "0: mvst %0,%1\n"
135 " jo 0b"
136 : "+&a" (__ptr), "+&a" (__src) :
0ecb606c 137 : "cc", "memory", "0" );
0a51f0ac
UD
138 return __ret;
139}
140#endif
141
142/* Append no more than N characters from SRC onto DEST. */
143#define _HAVE_STRING_ARCH_strncat 1
144#ifndef _FORCE_INLINES
145__STRING_INLINE char *
146strncat (char *__dest, __const char *__src, size_t __n)
147{
148 char *__ret = __dest;
149 char *__ptr, *__tmp;
150 size_t __diff;
151
152 if (__n > 0) {
153 /* Move __ptr to the end of __dest. */
154 __ptr = (char *) 0;
155 __tmp = __dest;
156 __asm__ __volatile__ (" la 0,0\n"
157 "0: srst %0,%1\n"
158 " jo 0b\n"
159 : "+&a" (__ptr), "+&a" (__tmp) :
0ecb606c 160 : "cc", "memory", "0" );
0a51f0ac
UD
161
162 __diff = (size_t) (__ptr - __src);
163 __tmp = (char *) __src;
164 __asm__ __volatile__ (" j 1f\n"
165 "0: la %0,1(%0)\n"
166 "1: icm 0,1,0(%0)\n"
167 " stc 0,0(%2,%0)\n"
168 " jz 2f\n"
169#if defined(__s390x__)
170 " brctg %1,0b\n"
171#else
172 " brct %1,0b\n"
173#endif
174 " slr 0,0\n"
175 " stc 0,1(%2,%0)\n"
176 "2:"
177 : "+&a" (__tmp), "+&a" (__n) : "a" (__diff)
0ecb606c 178 : "cc", "memory", "0" );
0a51f0ac
UD
179
180 }
181 return __ret;
182}
183#endif
184
185/* Search N bytes of S for C. */
186#define _HAVE_STRING_ARCH_memchr 1
187#ifndef _FORCE_INLINES
188__STRING_INLINE void *
189memchr (__const void *__str, int __c, size_t __n)
190{
191 char *__ptr, *__tmp;
192
193 __tmp = (char *) __str;
194 __ptr = (char *) __tmp + __n;
195 __asm__ __volatile__ (" lhi 0,0xff\n"
196 " nr 0,%2\n"
197 "0: srst %0,%1\n"
198 " jo 0b\n"
199 " brc 13,1f\n"
200 " la %0,0\n"
201 "1:"
202 : "+&a" (__ptr), "+&a" (__tmp) : "d" (__c)
0ecb606c 203 : "cc", "memory", "0" );
0a51f0ac
UD
204 return __ptr;
205}
206#endif
207
208/* Search N bytes of S for C. */
209#define _HAVE_STRING_ARCH_memchr 1
210#ifndef _FORCE_INLINES
211__STRING_INLINE int
212strcmp (__const char *__s1, __const char *__s2)
213{
214 char *__p1, *__p2;
215 int __ret;
216
217 __p1 = (char *) __s1;
218 __p2 = (char *) __s2;
219 __asm__ __volatile__ (" slr 0,0\n"
220 "0: clst %1,%2\n"
221 " jo 0b\n"
222 " ipm %0\n"
223 " srl %0,28"
224 : "=d" (__ret), "+&a" (__p1), "+&a" (__p2) :
0ecb606c 225 : "cc", "memory", "0" );
0a51f0ac
UD
226 __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
227 return __ret;
228}
229#endif
230
231#endif /* Use string inlines && GNU CC. */