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