(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
[glibc.git] / sysdeps / s390 / bits / string.h
blob7134827eb025a7de55d0c66f9f99c5d272a92c2d
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.
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, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #ifndef _STRING_H
22 # error "Never use <bits/string.h> directly; include <string.h> instead."
23 #endif
25 /* The s390 processors can access unaligned multi-byte variables. */
26 #define _STRING_ARCH_unaligned 1
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
33 #ifndef __STRING_INLINE
34 # ifdef __cplusplus
35 # define __STRING_INLINE inline
36 # else
37 # define __STRING_INLINE extern __inline
38 # endif
39 #endif
41 #define _HAVE_STRING_ARCH_strlen 1
42 #ifndef _FORCE_INLINES
43 __STRING_INLINE size_t
44 strlen (__const char *__str)
46 char *__ptr, *__tmp;
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) :
54 : "cc", "0" );
55 return (size_t) (__ptr - __str);
57 #endif
59 /* Copy SRC to DEST. */
60 #define _HAVE_STRING_ARCH_strcpy 1
61 #ifndef _FORCE_INLINES
62 __STRING_INLINE char *
63 strcpy (char *__dest, __const char *__src)
65 char *tmp = __dest;
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;
74 #endif
76 #define _HAVE_STRING_ARCH_strncpy 1
77 #ifndef _FORCE_INLINES
78 __STRING_INLINE char *
79 strncpy (char *__dest, __const char *__src, size_t __n)
81 char *__ret = __dest;
82 char *__ptr;
83 size_t __diff;
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)
108 : "cc", "0" );
110 return __ret;
112 #endif
114 /* Append SRC onto DEST. */
115 #define _HAVE_STRING_ARCH_strcat 1
116 #ifndef _FORCE_INLINES
117 __STRING_INLINE char *
118 strcat(char *__dest, const char *__src)
120 char *__ret = __dest;
121 char *__ptr, *__tmp;
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" );
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) :
137 : "cc", "0" );
138 return __ret;
140 #endif
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 *
146 strncat (char *__dest, __const char *__src, size_t __n)
148 char *__ret = __dest;
149 char *__ptr, *__tmp;
150 size_t __diff;
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) :
160 : "cc", "0" );
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)
178 : "cc", "0" );
181 return __ret;
183 #endif
185 /* Search N bytes of S for C. */
186 #define _HAVE_STRING_ARCH_memchr 1
187 #ifndef _FORCE_INLINES
188 __STRING_INLINE void *
189 memchr (__const void *__str, int __c, size_t __n)
191 char *__ptr, *__tmp;
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)
203 : "cc", "0" );
204 return __ptr;
206 #endif
208 /* Search N bytes of S for C. */
209 #define _HAVE_STRING_ARCH_memchr 1
210 #ifndef _FORCE_INLINES
211 __STRING_INLINE int
212 strcmp (__const char *__s1, __const char *__s2)
214 char *__p1, *__p2;
215 int __ret;
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) :
225 : "cc", "0" );
226 __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
227 return __ret;
229 #endif
231 #endif /* Use string inlines && GNU CC. */