fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / sysdeps / s390 / bits / string.h
1 /* Optimized, inlined string functions.  S/390 version.
2    Copyright (C) 2000, 2001, 2007 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
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.
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
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
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.  */
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 # ifndef __extern_inline
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
44 strlen (__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) : 
54                           : "cc", "memory", "0" );
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 *
63 strcpy (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 *
79 strncpy (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)
108                             : "cc", "memory", "0" );
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 *
118 strcat(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) :
137                           : "cc", "memory", "0" );
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 *
146 strncat (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) :
160                             : "cc", "memory", "0" );
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)
178                             : "cc", "memory", "0" );
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 *
189 memchr (__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)
203                           : "cc", "memory", "0" );
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
212 strcmp (__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) : 
225                           : "cc", "memory", "0" );
226     __ret = (__ret == 0) ? 0 : (__ret == 1) ? -1 : 1;
227     return __ret;
228 }
229 #endif
230
231 #endif  /* Use string inlines && GNU CC.  */