]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/i386/bits/string.h
Test for stack alignment.
[thirdparty/glibc.git] / sysdeps / i386 / bits / string.h
CommitLineData
92f1da4d 1/* Optimized, inlined string functions. i386 version.
b7f75e24 2 Copyright (C) 1997,1998,1999,2000,2003 Free Software Foundation, Inc.
92f1da4d
UD
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
92f1da4d
UD
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
92f1da4d 14
41bdb6e2
AJ
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
92f1da4d
UD
19
20#ifndef _STRING_H
61eb22d3 21# error "Never use <bits/string.h> directly; include <string.h> instead."
92f1da4d
UD
22#endif
23
61eb22d3
UD
24/* The ix86 processors can access unaligned multi-byte variables. */
25#define _STRING_ARCH_unaligned 1
26
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 \
2ed5fd9a 31 && defined __GNUC__ && __GNUC__ >= 2 && !__BOUNDED_POINTERS__
92f1da4d 32
9bbd7837
UD
33#ifndef __STRING_INLINE
34# ifdef __cplusplus
35# define __STRING_INLINE inline
36# else
37# define __STRING_INLINE extern __inline
38# endif
92f1da4d
UD
39#endif
40
41
42/* Copy N bytes of SRC to DEST. */
74015205 43#define _HAVE_STRING_ARCH_memcpy 1
92f1da4d
UD
44#define memcpy(dest, src, n) \
45 (__extension__ (__builtin_constant_p (n) \
5b2892d5
RM
46 ? __memcpy_c ((dest), (src), (n)) \
47 : memcpy ((dest), (src), (n))))
92f1da4d
UD
48/* This looks horribly ugly, but the compiler can optimize it totally,
49 as the count is constant. */
348ed515
UD
50__STRING_INLINE void *__memcpy_c (void *__dest, __const void *__src,
51 size_t __n);
52
92f1da4d
UD
53__STRING_INLINE void *
54__memcpy_c (void *__dest, __const void *__src, size_t __n)
55{
a44d2393 56 register unsigned long int __d0, __d1, __d2;
722c33bb
UD
57 union {
58 unsigned int __ui;
59 unsigned short int __usi;
60 unsigned char __uc;
61 } *__u = __dest;
9a0a462c 62 switch (__n)
92f1da4d
UD
63 {
64 case 0:
65 return __dest;
66 case 1:
722c33bb 67 __u->__uc = *(const unsigned char *) __src;
92f1da4d
UD
68 return __dest;
69 case 2:
722c33bb 70 __u->__usi = *(const unsigned short int *) __src;
92f1da4d
UD
71 return __dest;
72 case 3:
722c33bb
UD
73 __u->__usi = *(const unsigned short int *) __src;
74 __u = (void *) __u + 2;
75 __u->__uc = *(2 + (const unsigned char *) __src);
92f1da4d
UD
76 return __dest;
77 case 4:
722c33bb 78 __u->__ui = *(const unsigned int *) __src;
92f1da4d 79 return __dest;
722c33bb
UD
80 case 6:
81 __u->__ui = *(const unsigned int *) __src;
82 __u = (void *) __u + 4;
83 __u->__usi = *(2 + (const unsigned short int *) __src);
92f1da4d
UD
84 return __dest;
85 case 8:
722c33bb
UD
86 __u->__ui = *(const unsigned int *) __src;
87 __u = (void *) __u + 4;
88 __u->__ui = *(1 + (const unsigned int *) __src);
92f1da4d
UD
89 return __dest;
90 case 12:
722c33bb
UD
91 __u->__ui = *(const unsigned int *) __src;
92 __u = (void *) __u + 4;
93 __u->__ui = *(1 + (const unsigned int *) __src);
94 __u = (void *) __u + 4;
95 __u->__ui = *(2 + (const unsigned int *) __src);
92f1da4d
UD
96 return __dest;
97 case 16:
722c33bb
UD
98 __u->__ui = *(const unsigned int *) __src;
99 __u = (void *) __u + 4;
100 __u->__ui = *(1 + (const unsigned int *) __src);
101 __u = (void *) __u + 4;
102 __u->__ui = *(2 + (const unsigned int *) __src);
103 __u = (void *) __u + 4;
104 __u->__ui = *(3 + (const unsigned int *) __src);
92f1da4d
UD
105 return __dest;
106 case 20:
722c33bb
UD
107 __u->__ui = *(const unsigned int *) __src;
108 __u = (void *) __u + 4;
109 __u->__ui = *(1 + (const unsigned int *) __src);
110 __u = (void *) __u + 4;
111 __u->__ui = *(2 + (const unsigned int *) __src);
112 __u = (void *) __u + 4;
113 __u->__ui = *(3 + (const unsigned int *) __src);
114 __u = (void *) __u + 4;
115 __u->__ui = *(4 + (const unsigned int *) __src);
92f1da4d
UD
116 return __dest;
117 }
118#define __COMMON_CODE(x) \
119 __asm__ __volatile__ \
120 ("cld\n\t" \
121 "rep; movsl" \
122 x \
68b50604 123 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
722c33bb 124 : "0" (__n / 4), "1" (&__u->__uc), "2" (__src) \
68b50604 125 : "memory");
92f1da4d 126
9a0a462c 127 switch (__n % 4)
92f1da4d
UD
128 {
129 case 0:
130 __COMMON_CODE ("");
c2fa5b5a 131 break;
92f1da4d
UD
132 case 1:
133 __COMMON_CODE ("\n\tmovsb");
c2fa5b5a 134 break;
92f1da4d
UD
135 case 2:
136 __COMMON_CODE ("\n\tmovsw");
c2fa5b5a 137 break;
92f1da4d
UD
138 case 3:
139 __COMMON_CODE ("\n\tmovsw\n\tmovsb");
c2fa5b5a
UD
140 break;
141 }
142 return __dest;
92f1da4d
UD
143#undef __COMMON_CODE
144}
145
146
147/* Copy N bytes of SRC to DEST, guaranteeing
148 correct behavior for overlapping strings. */
74015205 149#define _HAVE_STRING_ARCH_memmove 1
9bbd7837 150#ifndef _FORCE_INLINES
92f1da4d
UD
151__STRING_INLINE void *
152memmove (void *__dest, __const void *__src, size_t __n)
153{
a44d2393 154 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
155 if (__dest < __src)
156 __asm__ __volatile__
157 ("cld\n\t"
158 "rep\n\t"
159 "movsb"
68b50604
UD
160 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
161 : "0" (__n), "1" (__src), "2" (__dest)
162 : "memory");
92f1da4d
UD
163 else
164 __asm__ __volatile__
165 ("std\n\t"
166 "rep\n\t"
167 "movsb\n\t"
168 "cld"
68b50604
UD
169 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
170 : "0" (__n), "1" (__n - 1 + (const char *) __src),
171 "2" (__n - 1 + (char *) __dest)
172 : "memory");
92f1da4d
UD
173 return __dest;
174}
9bbd7837 175#endif
92f1da4d
UD
176
177/* Set N bytes of S to C. */
74015205 178#define _HAVE_STRING_ARCH_memset 1
d3d99893 179#define _USE_STRING_ARCH_memset 1
92f1da4d
UD
180#define memset(s, c, n) \
181 (__extension__ (__builtin_constant_p (c) \
182 ? (__builtin_constant_p (n) \
183 ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
184 : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
185 : __memset_gg (s, c, n)))
186
348ed515
UD
187__STRING_INLINE void *__memset_cc (void *__s, unsigned long int __pattern,
188 size_t __n);
189
92f1da4d
UD
190__STRING_INLINE void *
191__memset_cc (void *__s, unsigned long int __pattern, size_t __n)
192{
a44d2393 193 register unsigned long int __d0, __d1;
722c33bb
UD
194 union {
195 unsigned int __ui;
196 unsigned short int __usi;
197 unsigned char __uc;
198 } *__u = __s;
92f1da4d
UD
199 switch (__n)
200 {
201 case 0:
63bda0c1 202 return __s;
92f1da4d 203 case 1:
722c33bb 204 __u->__uc = __pattern;
92f1da4d
UD
205 return __s;
206 case 2:
722c33bb 207 __u->__usi = __pattern;
63bda0c1 208 return __s;
92f1da4d 209 case 3:
722c33bb 210 __u->__usi = __pattern;
9031847d 211 __u = __extension__ ((void *) __u + 2);
722c33bb 212 __u->__uc = __pattern;
92f1da4d
UD
213 return __s;
214 case 4:
722c33bb 215 __u->__ui = __pattern;
92f1da4d
UD
216 return __s;
217 }
218#define __COMMON_CODE(x) \
219 __asm__ __volatile__ \
220 ("cld\n\t" \
221 "rep; stosl" \
222 x \
68b50604 223 : "=&c" (__d0), "=&D" (__d1) \
722c33bb 224 : "a" (__pattern), "0" (__n / 4), "1" (&__u->__uc) \
68b50604 225 : "memory")
92f1da4d
UD
226
227 switch (__n % 4)
228 {
229 case 0:
230 __COMMON_CODE ("");
c2fa5b5a 231 break;
92f1da4d
UD
232 case 1:
233 __COMMON_CODE ("\n\tstosb");
c2fa5b5a 234 break;
92f1da4d 235 case 2:
63bda0c1 236 __COMMON_CODE ("\n\tstosw");
c2fa5b5a 237 break;
92f1da4d
UD
238 case 3:
239 __COMMON_CODE ("\n\tstosw\n\tstosb");
c2fa5b5a 240 break;
92f1da4d 241 }
c2fa5b5a 242 return __s;
92f1da4d
UD
243#undef __COMMON_CODE
244}
245
348ed515
UD
246__STRING_INLINE void *__memset_cg (void *__s, unsigned long __c, size_t __n);
247
92f1da4d
UD
248__STRING_INLINE void *
249__memset_cg (void *__s, unsigned long __c, size_t __n)
250{
a44d2393 251 register unsigned long int __d0, __d1;
92f1da4d
UD
252 __asm__ __volatile__
253 ("cld\n\t"
254 "rep; stosl\n\t"
68b50604 255 "testb $2,%b3\n\t"
92f1da4d
UD
256 "je 1f\n\t"
257 "stosw\n"
258 "1:\n\t"
68b50604 259 "testb $1,%b3\n\t"
92f1da4d
UD
260 "je 2f\n\t"
261 "stosb\n"
262 "2:"
68b50604
UD
263 : "=&c" (__d0), "=&D" (__d1)
264 : "a" (__c), "q" (__n), "0" (__n / 4), "1" (__s)
265 : "memory");
92f1da4d
UD
266 return __s;
267}
268
348ed515
UD
269__STRING_INLINE void *__memset_gg (void *__s, char __c, size_t __n);
270
92f1da4d
UD
271__STRING_INLINE void *
272__memset_gg (void *__s, char __c, size_t __n)
273{
a44d2393 274 register unsigned long int __d0, __d1;
92f1da4d
UD
275 __asm__ __volatile__
276 ("cld\n\t"
9a0a462c 277 "rep; stosb"
68b50604
UD
278 : "=&D" (__d0), "=&c" (__d1)
279 : "a" (__c), "0" (__s), "1" (__n)
280 : "memory");
92f1da4d
UD
281 return __s;
282}
283
284
285
286
287/* Search N bytes of S for C. */
74015205 288#define _HAVE_STRING_ARCH_memchr 1
9bbd7837 289#ifndef _FORCE_INLINES
92f1da4d
UD
290__STRING_INLINE void *
291memchr (__const void *__s, int __c, size_t __n)
292{
a44d2393 293 register unsigned long int __d0;
92f1da4d 294 register void *__res;
a44d2393 295 if (__n == 0)
92f1da4d
UD
296 return NULL;
297 __asm__ __volatile__
298 ("cld\n\t"
a44d2393
UD
299 "repne; scasb\n\t"
300 "je 1f\n\t"
301 "movl $1,%0\n"
92f1da4d 302 "1:"
68b50604 303 : "=D" (__res), "=&c" (__d0)
5b2892d5
RM
304 : "a" (__c), "0" (__s), "1" (__n),
305 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
22baad3c 306 : "cc");
92f1da4d
UD
307 return __res - 1;
308}
9bbd7837 309#endif
92f1da4d 310
ca747856
RM
311#define _HAVE_STRING_ARCH_memrchr 1
312#ifndef _FORCE_INLINES
313__STRING_INLINE void *
314__memrchr (__const void *__s, int __c, size_t __n)
315{
316 register unsigned long int __d0;
317 register void *__res;
318 if (__n == 0)
319 return NULL;
320 __asm__ __volatile__
321 ("std\n\t"
322 "repne; scasb\n\t"
323 "je 1f\n\t"
fbda91b1 324 "orl $-1,%0\n"
b7f75e24
AJ
325 "1:\tcld\n\t"
326 "incl %0"
ca747856 327 : "=D" (__res), "=&c" (__d0)
5b2892d5
RM
328 : "a" (__c), "0" (__s + __n - 1), "1" (__n),
329 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
22baad3c 330 : "cc");
b7f75e24 331 return __res;
ca747856 332}
fbda91b1
UD
333# ifdef __USE_GNU
334# define memrchr(s, c, n) __memrchr (s, c, n)
335# endif
ca747856
RM
336#endif
337
92f1da4d 338/* Return the length of S. */
74015205 339#define _HAVE_STRING_ARCH_strlen 1
9bbd7837 340#ifndef _FORCE_INLINES
92f1da4d
UD
341__STRING_INLINE size_t
342strlen (__const char *__str)
343{
a44d2393 344 register unsigned long int __d0;
92f1da4d
UD
345 register size_t __res;
346 __asm__ __volatile__
347 ("cld\n\t"
348 "repne; scasb\n\t"
349 "notl %0"
68b50604 350 : "=c" (__res), "=&D" (__d0)
5b2892d5
RM
351 : "1" (__str), "a" (0), "0" (0xffffffff),
352 "m" ( *(struct { char __x[0xfffffff]; } *)__str)
68b50604 353 : "cc");
92f1da4d
UD
354 return __res - 1;
355}
9bbd7837 356#endif
92f1da4d
UD
357
358/* Copy SRC to DEST. */
74015205 359#define _HAVE_STRING_ARCH_strcpy 1
9bbd7837 360#ifndef _FORCE_INLINES
92f1da4d
UD
361__STRING_INLINE char *
362strcpy (char *__dest, __const char *__src)
363{
a44d2393 364 register unsigned long int __d0, __d1;
92f1da4d
UD
365 __asm__ __volatile__
366 ("cld\n"
367 "1:\n\t"
368 "lodsb\n\t"
369 "stosb\n\t"
370 "testb %%al,%%al\n\t"
371 "jne 1b"
68b50604
UD
372 : "=&S" (__d0), "=&D" (__d1)
373 : "0" (__src), "1" (__dest)
374 : "ax", "memory", "cc");
92f1da4d
UD
375 return __dest;
376}
9bbd7837 377#endif
92f1da4d
UD
378
379/* Copy no more than N characters of SRC to DEST. */
74015205 380#define _HAVE_STRING_ARCH_strncpy 1
9bbd7837 381#ifndef _FORCE_INLINES
92f1da4d
UD
382__STRING_INLINE char *
383strncpy (char *__dest, __const char *__src, size_t __n)
384{
a44d2393 385 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
386 __asm__ __volatile__
387 ("cld\n"
388 "1:\n\t"
389 "decl %2\n\t"
390 "js 2f\n\t"
391 "lodsb\n\t"
392 "stosb\n\t"
393 "testb %%al,%%al\n\t"
394 "jne 1b\n\t"
395 "rep; stosb\n"
396 "2:"
68b50604
UD
397 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
398 : "0" (__src), "1" (__dest), "2" (__n)
399 : "ax", "memory", "cc");
92f1da4d
UD
400 return __dest;
401}
9bbd7837 402#endif
92f1da4d
UD
403
404/* Append SRC onto DEST. */
74015205 405#define _HAVE_STRING_ARCH_strcat 1
9bbd7837 406#ifndef _FORCE_INLINES
92f1da4d
UD
407__STRING_INLINE char *
408strcat (char *__dest, __const char *__src)
409{
a44d2393 410 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
411 __asm__ __volatile__
412 ("cld\n\t"
413 "repne; scasb\n\t"
414 "decl %1\n"
415 "1:\n\t"
416 "lodsb\n\t"
417 "stosb\n\t"
418 "testb %%al,%%al\n\t"
419 "jne 1b"
68b50604
UD
420 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
421 : "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
422 : "memory", "cc");
92f1da4d
UD
423 return __dest;
424}
9bbd7837 425#endif
92f1da4d
UD
426
427/* Append no more than N characters from SRC onto DEST. */
74015205 428#define _HAVE_STRING_ARCH_strncat 1
9bbd7837 429#ifndef _FORCE_INLINES
92f1da4d
UD
430__STRING_INLINE char *
431strncat (char *__dest, __const char *__src, size_t __n)
432{
a44d2393 433 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
434 __asm__ __volatile__
435 ("cld\n\t"
436 "repne; scasb\n\t"
437 "decl %1\n\t"
7c97addd 438 "movl %4,%2\n"
92f1da4d 439 "1:\n\t"
7c97addd 440 "decl %2\n\t"
92f1da4d
UD
441 "js 2f\n\t"
442 "lodsb\n\t"
443 "stosb\n\t"
444 "testb %%al,%%al\n\t"
7c97addd
UD
445 "jne 1b\n\t"
446 "jmp 3f\n"
92f1da4d 447 "2:\n\t"
7c97addd
UD
448 "xorl %3,%3\n\t"
449 "stosb\n"
450 "3:"
68b50604
UD
451 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
452 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
453 : "memory", "cc");
92f1da4d
UD
454 return __dest;
455}
9bbd7837 456#endif
92f1da4d
UD
457
458/* Compare S1 and S2. */
74015205 459#define _HAVE_STRING_ARCH_strcmp 1
9bbd7837 460#ifndef _FORCE_INLINES
92f1da4d
UD
461__STRING_INLINE int
462strcmp (__const char *__s1, __const char *__s2)
463{
a44d2393 464 register unsigned long int __d0, __d1;
92f1da4d
UD
465 register int __res;
466 __asm__ __volatile__
467 ("cld\n"
468 "1:\n\t"
469 "lodsb\n\t"
470 "scasb\n\t"
471 "jne 2f\n\t"
472 "testb %%al,%%al\n\t"
473 "jne 1b\n\t"
474 "xorl %%eax,%%eax\n\t"
475 "jmp 3f\n"
476 "2:\n\t"
477 "sbbl %%eax,%%eax\n\t"
99707e81 478 "orb $1,%%al\n"
92f1da4d 479 "3:"
68b50604 480 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
5b2892d5
RM
481 : "1" (__s1), "2" (__s2),
482 "m" ( *(struct { char __x[0xfffffff]; } *)__s1),
483 "m" ( *(struct { char __x[0xfffffff]; } *)__s2)
68b50604 484 : "cc");
92f1da4d
UD
485 return __res;
486}
9bbd7837 487#endif
92f1da4d
UD
488
489/* Compare N characters of S1 and S2. */
74015205 490#define _HAVE_STRING_ARCH_strncmp 1
9bbd7837 491#ifndef _FORCE_INLINES
92f1da4d
UD
492__STRING_INLINE int
493strncmp (__const char *__s1, __const char *__s2, size_t __n)
494{
a44d2393 495 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
496 register int __res;
497 __asm__ __volatile__
498 ("cld\n"
499 "1:\n\t"
500 "decl %3\n\t"
501 "js 2f\n\t"
502 "lodsb\n\t"
503 "scasb\n\t"
504 "jne 3f\n\t"
505 "testb %%al,%%al\n\t"
506 "jne 1b\n"
507 "2:\n\t"
508 "xorl %%eax,%%eax\n\t"
509 "jmp 4f\n"
510 "3:\n\t"
511 "sbbl %%eax,%%eax\n\t"
512 "orb $1,%%al\n"
513 "4:"
68b50604 514 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
5b2892d5
RM
515 : "1" (__s1), "2" (__s2), "3" (__n),
516 "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
517 "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
68b50604 518 : "cc");
92f1da4d
UD
519 return __res;
520}
9bbd7837 521#endif
92f1da4d
UD
522
523/* Find the first occurrence of C in S. */
74015205 524#define _HAVE_STRING_ARCH_strchr 1
d3d99893 525#define _USE_STRING_ARCH_strchr 1
92f1da4d
UD
526#define strchr(s, c) \
527 (__extension__ (__builtin_constant_p (c) \
528 ? __strchr_c (s, ((c) & 0xff) << 8) \
529 : __strchr_g (s, c)))
530
348ed515
UD
531__STRING_INLINE char *__strchr_g (__const char *__s, int __c);
532
92f1da4d
UD
533__STRING_INLINE char *
534__strchr_g (__const char *__s, int __c)
535{
a44d2393 536 register unsigned long int __d0;
92f1da4d
UD
537 register char *__res;
538 __asm__ __volatile__
539 ("cld\n\t"
540 "movb %%al,%%ah\n"
541 "1:\n\t"
542 "lodsb\n\t"
543 "cmpb %%ah,%%al\n\t"
544 "je 2f\n\t"
545 "testb %%al,%%al\n\t"
546 "jne 1b\n\t"
547 "movl $1,%1\n"
548 "2:\n\t"
549 "movl %1,%0"
68b50604 550 : "=a" (__res), "=&S" (__d0)
5b2892d5
RM
551 : "0" (__c), "1" (__s),
552 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 553 : "cc");
92f1da4d
UD
554 return __res - 1;
555}
556
348ed515
UD
557__STRING_INLINE char *__strchr_c (__const char *__s, int __c);
558
92f1da4d
UD
559__STRING_INLINE char *
560__strchr_c (__const char *__s, int __c)
561{
a44d2393 562 register unsigned long int __d0;
92f1da4d
UD
563 register char *__res;
564 __asm__ __volatile__
565 ("cld\n\t"
566 "1:\n\t"
567 "lodsb\n\t"
568 "cmpb %%ah,%%al\n\t"
569 "je 2f\n\t"
570 "testb %%al,%%al\n\t"
571 "jne 1b\n\t"
572 "movl $1,%1\n"
573 "2:\n\t"
574 "movl %1,%0"
68b50604 575 : "=a" (__res), "=&S" (__d0)
5b2892d5
RM
576 : "0" (__c), "1" (__s),
577 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 578 : "cc");
92f1da4d
UD
579 return __res - 1;
580}
581
582
c4563d2d
UD
583/* Find the first occurrence of C in S or the final NUL byte. */
584#define _HAVE_STRING_ARCH_strchrnul 1
585#define __strchrnul(s, c) \
586 (__extension__ (__builtin_constant_p (c) \
587 ? ((c) == '\0' \
588 ? (char *) __rawmemchr (s, c) \
589 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
590 : __strchrnul_g (s, c)))
591
592__STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
593
594__STRING_INLINE char *
595__strchrnul_g (__const char *__s, int __c)
596{
597 register unsigned long int __d0;
598 register char *__res;
599 __asm__ __volatile__
600 ("cld\n\t"
601 "movb %%al,%%ah\n"
602 "1:\n\t"
603 "lodsb\n\t"
604 "cmpb %%ah,%%al\n\t"
605 "je 2f\n\t"
606 "testb %%al,%%al\n\t"
607 "jne 1b\n\t"
608 "2:\n\t"
609 "movl %1,%0"
610 : "=a" (__res), "=&S" (__d0)
5b2892d5
RM
611 : "0" (__c), "1" (__s),
612 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
c4563d2d
UD
613 : "cc");
614 return __res - 1;
615}
616
617__STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
618
619__STRING_INLINE char *
620__strchrnul_c (__const char *__s, int __c)
621{
622 register unsigned long int __d0;
623 register char *__res;
624 __asm__ __volatile__
625 ("cld\n\t"
626 "1:\n\t"
627 "lodsb\n\t"
628 "cmpb %%ah,%%al\n\t"
629 "je 2f\n\t"
630 "testb %%al,%%al\n\t"
631 "jne 1b\n\t"
632 "2:\n\t"
633 "movl %1,%0"
634 : "=a" (__res), "=&S" (__d0)
5b2892d5
RM
635 : "0" (__c), "1" (__s),
636 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
c4563d2d
UD
637 : "cc");
638 return __res - 1;
639}
640#ifdef __USE_GNU
641# define strchrnul(s, c) __strchrnul (s, c)
642#endif
643
644
92f1da4d
UD
645/* Return the length of the initial segment of S which
646 consists entirely of characters not in REJECT. */
74015205 647#define _HAVE_STRING_ARCH_strcspn 1
9bbd7837
UD
648#ifndef _FORCE_INLINES
649# ifdef __PIC__
92f1da4d
UD
650__STRING_INLINE size_t
651strcspn (__const char *__s, __const char *__reject)
652{
a44d2393 653 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
654 register char *__res;
655 __asm__ __volatile__
656 ("pushl %%ebx\n\t"
657 "cld\n\t"
658 "movl %4,%%edi\n\t"
659 "repne; scasb\n\t"
660 "notl %%ecx\n\t"
661 "decl %%ecx\n\t"
662 "movl %%ecx,%%ebx\n"
663 "1:\n\t"
664 "lodsb\n\t"
665 "testb %%al,%%al\n\t"
666 "je 2f\n\t"
667 "movl %4,%%edi\n\t"
668 "movl %%ebx,%%ecx\n\t"
669 "repne; scasb\n\t"
670 "jne 1b\n"
671 "2:\n\t"
672 "popl %%ebx"
68b50604 673 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
5b2892d5
RM
674 : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
675 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 676 : "cc");
92f1da4d
UD
677 return (__res - 1) - __s;
678}
9bbd7837 679# else
92f1da4d
UD
680__STRING_INLINE size_t
681strcspn (__const char *__s, __const char *__reject)
682{
a44d2393 683 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
684 register char *__res;
685 __asm__ __volatile__
686 ("cld\n\t"
68b50604 687 "movl %5,%%edi\n\t"
92f1da4d
UD
688 "repne; scasb\n\t"
689 "notl %%ecx\n\t"
690 "decl %%ecx\n\t"
691 "movl %%ecx,%%edx\n"
692 "1:\n\t"
693 "lodsb\n\t"
694 "testb %%al,%%al\n\t"
695 "je 2f\n\t"
68b50604 696 "movl %5,%%edi\n\t"
92f1da4d
UD
697 "movl %%edx,%%ecx\n\t"
698 "repne; scasb\n\t"
699 "jne 1b\n"
700 "2:"
68b50604 701 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
5b2892d5
RM
702 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
703 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 704 : "cc");
92f1da4d
UD
705 return (__res - 1) - __s;
706}
9bbd7837 707# endif
92f1da4d
UD
708#endif
709
710
711/* Return the length of the initial segment of S which
712 consists entirely of characters in ACCEPT. */
74015205 713#define _HAVE_STRING_ARCH_strspn 1
9bbd7837
UD
714#ifndef _FORCE_INLINES
715# ifdef __PIC__
92f1da4d
UD
716__STRING_INLINE size_t
717strspn (__const char *__s, __const char *__accept)
718{
a44d2393 719 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
720 register char *__res;
721 __asm__ __volatile__
722 ("pushl %%ebx\n\t"
723 "cld\n\t"
724 "movl %4,%%edi\n\t"
725 "repne; scasb\n\t"
726 "notl %%ecx\n\t"
727 "decl %%ecx\n\t"
728 "movl %%ecx,%%ebx\n"
729 "1:\n\t"
730 "lodsb\n\t"
731 "testb %%al,%%al\n\t"
732 "je 2f\n\t"
733 "movl %4,%%edi\n\t"
734 "movl %%ebx,%%ecx\n\t"
735 "repne; scasb\n\t"
736 "je 1b\n"
737 "2:\n\t"
738 "popl %%ebx"
68b50604 739 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
5b2892d5
RM
740 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
741 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 742 : "cc");
92f1da4d
UD
743 return (__res - 1) - __s;
744}
9bbd7837 745# else
92f1da4d
UD
746__STRING_INLINE size_t
747strspn (__const char *__s, __const char *__accept)
748{
a44d2393 749 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
750 register char *__res;
751 __asm__ __volatile__
752 ("cld\n\t"
68b50604 753 "movl %5,%%edi\n\t"
92f1da4d
UD
754 "repne; scasb\n\t"
755 "notl %%ecx\n\t"
756 "decl %%ecx\n\t"
757 "movl %%ecx,%%edx\n"
758 "1:\n\t"
759 "lodsb\n\t"
760 "testb %%al,%%al\n\t"
761 "je 2f\n\t"
68b50604 762 "movl %5,%%edi\n\t"
92f1da4d
UD
763 "movl %%edx,%%ecx\n\t"
764 "repne; scasb\n\t"
765 "je 1b\n"
766 "2:"
68b50604 767 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
5b2892d5
RM
768 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
769 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 770 : "cc");
92f1da4d
UD
771 return (__res - 1) - __s;
772}
9bbd7837 773# endif
92f1da4d
UD
774#endif
775
776
777/* Find the first occurrence in S of any character in ACCEPT. */
74015205 778#define _HAVE_STRING_ARCH_strpbrk 1
9bbd7837
UD
779#ifndef _FORCE_INLINES
780# ifdef __PIC__
92f1da4d
UD
781__STRING_INLINE char *
782strpbrk (__const char *__s, __const char *__accept)
783{
68b50604 784 unsigned long int __d0, __d1, __d2;
92f1da4d
UD
785 register char *__res;
786 __asm__ __volatile__
787 ("pushl %%ebx\n\t"
788 "cld\n\t"
789 "movl %4,%%edi\n\t"
790 "repne; scasb\n\t"
791 "notl %%ecx\n\t"
792 "decl %%ecx\n\t"
793 "movl %%ecx,%%ebx\n"
794 "1:\n\t"
795 "lodsb\n\t"
796 "testb %%al,%%al\n\t"
797 "je 2f\n\t"
798 "movl %4,%%edi\n\t"
799 "movl %%ebx,%%ecx\n\t"
800 "repne; scasb\n\t"
801 "jne 1b\n\t"
802 "decl %0\n\t"
803 "jmp 3f\n"
804 "2:\n\t"
805 "xorl %0,%0\n"
806 "3:\n\t"
807 "popl %%ebx"
68b50604 808 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
5b2892d5
RM
809 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
810 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 811 : "cc");
92f1da4d
UD
812 return __res;
813}
9bbd7837 814# else
92f1da4d
UD
815__STRING_INLINE char *
816strpbrk (__const char *__s, __const char *__accept)
817{
a44d2393 818 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
819 register char *__res;
820 __asm__ __volatile__
821 ("cld\n\t"
7c97addd 822 "movl %5,%%edi\n\t"
92f1da4d
UD
823 "repne; scasb\n\t"
824 "notl %%ecx\n\t"
825 "decl %%ecx\n\t"
826 "movl %%ecx,%%edx\n"
827 "1:\n\t"
828 "lodsb\n\t"
829 "testb %%al,%%al\n\t"
830 "je 2f\n\t"
7c97addd 831 "movl %5,%%edi\n\t"
92f1da4d
UD
832 "movl %%edx,%%ecx\n\t"
833 "repne; scasb\n\t"
834 "jne 1b\n\t"
835 "decl %0\n\t"
836 "jmp 3f\n"
837 "2:\n\t"
838 "xorl %0,%0\n"
839 "3:"
68b50604 840 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
5b2892d5
RM
841 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
842 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
68b50604 843 : "cc");
92f1da4d
UD
844 return __res;
845}
9bbd7837 846# endif
92f1da4d
UD
847#endif
848
849
850/* Find the first occurrence of NEEDLE in HAYSTACK. */
74015205 851#define _HAVE_STRING_ARCH_strstr 1
9bbd7837
UD
852#ifndef _FORCE_INLINES
853# ifdef __PIC__
92f1da4d
UD
854__STRING_INLINE char *
855strstr (__const char *__haystack, __const char *__needle)
856{
7c97addd 857 register unsigned long int __d0, __d1, __d2;
92f1da4d
UD
858 register char *__res;
859 __asm__ __volatile__
860 ("pushl %%ebx\n\t"
861 "cld\n\t" \
862 "movl %4,%%edi\n\t"
863 "repne; scasb\n\t"
864 "notl %%ecx\n\t"
865 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
866 "movl %%ecx,%%ebx\n"
867 "1:\n\t"
868 "movl %4,%%edi\n\t"
869 "movl %%esi,%%eax\n\t"
870 "movl %%ebx,%%ecx\n\t"
871 "repe; cmpsb\n\t"
872 "je 2f\n\t" /* also works for empty string, see above */
873 "xchgl %%eax,%%esi\n\t"
874 "incl %%esi\n\t"
875 "cmpb $0,-1(%%eax)\n\t"
876 "jne 1b\n\t"
877 "xorl %%eax,%%eax\n\t"
878 "2:\n\t"
879 "popl %%ebx"
68b50604
UD
880 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
881 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
5b2892d5 882 : "memory", "cc");
92f1da4d
UD
883 return __res;
884}
9bbd7837 885# else
92f1da4d
UD
886__STRING_INLINE char *
887strstr (__const char *__haystack, __const char *__needle)
888{
a44d2393 889 register unsigned long int __d0, __d1, __d2, __d3;
92f1da4d
UD
890 register char *__res;
891 __asm__ __volatile__
892 ("cld\n\t" \
68b50604 893 "movl %5,%%edi\n\t"
92f1da4d
UD
894 "repne; scasb\n\t"
895 "notl %%ecx\n\t"
896 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
897 "movl %%ecx,%%edx\n"
898 "1:\n\t"
68b50604 899 "movl %5,%%edi\n\t"
92f1da4d
UD
900 "movl %%esi,%%eax\n\t"
901 "movl %%edx,%%ecx\n\t"
902 "repe; cmpsb\n\t"
903 "je 2f\n\t" /* also works for empty string, see above */
904 "xchgl %%eax,%%esi\n\t"
905 "incl %%esi\n\t"
906 "cmpb $0,-1(%%eax)\n\t"
907 "jne 1b\n\t"
908 "xorl %%eax,%%eax\n\t"
909 "2:"
68b50604
UD
910 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
911 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
5b2892d5 912 : "memory", "cc");
92f1da4d
UD
913 return __res;
914}
9bbd7837 915# endif
92f1da4d
UD
916#endif
917
9bbd7837
UD
918#ifndef _FORCE_INLINES
919# undef __STRING_INLINE
920#endif
92f1da4d 921
61eb22d3 922#endif /* use string inlines && GNU CC */