Update.
[platform/upstream/glibc.git] / sysdeps / i386 / i486 / bits / string.h
1 /* Optimized, inlined string functions.  i486 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 /* The macros are used in some of the optimized implementations below.  */
42 #define __STRING_SMALL_GET16(src, idx) \
43   (((src)[idx + 1] << 8) | (src)[idx])
44 #define __STRING_SMALL_GET32(src, idx) \
45   ((((src)[idx + 3] << 8 | (src)[idx + 2]) << 8                               \
46     | (src)[idx + 1]) << 8 | (src)[idx])
47
48
49 /* Copy N bytes of SRC to DEST.  */
50 #define _HAVE_STRING_ARCH_memcpy 1
51 #define memcpy(dest, src, n) \
52   (__extension__ (__builtin_constant_p (n)                                    \
53                   ? __memcpy_c (dest, src, n)                                 \
54                   : __memcpy_g (dest, src, n)))
55 #define __memcpy_c(dest, src, n) \
56   ((n) == 0                                                                   \
57    ? (dest)                                                                   \
58    : (((n) % 4 == 0)                                                          \
59       ? __memcpy_by4 (dest, src, n)                                           \
60       : (((n) % 2 == 0)                                                       \
61          ? __memcpy_by2 (dest, src, n)                                        \
62          : __memcpy_g (dest, src, n))))
63
64 __STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src,
65                                     size_t __n);
66
67 __STRING_INLINE void *
68 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
69 {
70   register unsigned long int __d0, __d1;
71   register void *__tmp = __dest;
72   __asm__ __volatile__
73     ("1:\n\t"
74      "movl      (%2),%0\n\t"
75      "leal      4(%2),%2\n\t"
76      "movl      %0,(%1)\n\t"
77      "leal      4(%1),%1\n\t"
78      "decl      %3\n\t"
79      "jnz       1b"
80      : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
81      : "1" (__tmp), "2" (__src), "3" (__n / 4)
82      : "memory", "cc");
83   return __dest;
84 }
85
86 __STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src,
87                                     size_t __n);
88
89 __STRING_INLINE void *
90 __memcpy_by2 (void *__dest, __const void *__src, size_t __n)
91 {
92   register unsigned long int __d0, __d1;
93   register void *__tmp = __dest;
94   __asm__ __volatile__
95     ("shrl      $1,%3\n\t"
96      "jz        2f\n"                 /* only a word */
97      "1:\n\t"
98      "movl      (%2),%0\n\t"
99      "leal      4(%2),%2\n\t"
100      "movl      %0,(%1)\n\t"
101      "leal      4(%1),%1\n\t"
102      "decl      %3\n\t"
103      "jnz       1b\n"
104      "2:\n\t"
105      "movw      (%2),%w0\n\t"
106      "movw      %w0,(%1)"
107      : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
108      : "1" (__tmp), "2" (__src), "3" (__n / 2)
109      : "memory", "cc");
110   return __dest;
111 }
112
113 __STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src,
114                                   size_t __n);
115
116      __STRING_INLINE void *
117 __memcpy_g (void *__dest, __const void *__src, size_t __n)
118 {
119   register unsigned long int __d0, __d1, __d2;
120   register void *__tmp = __dest;
121   __asm__ __volatile__
122     ("cld\n\t"
123      "shrl      $1,%%ecx\n\t"
124      "jnc       1f\n\t"
125      "movsb\n"
126      "1:\n\t"
127      "shrl      $1,%%ecx\n\t"
128      "jnc       2f\n\t"
129      "movsw\n"
130      "2:\n\t"
131      "rep; movsl"
132      : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
133      : "0" (__n), "1" (__tmp), "2" (__src)
134      : "memory", "cc");
135   return __dest;
136 }
137
138 #define _HAVE_STRING_ARCH_memmove 1
139 #ifndef _FORCE_INLINES
140 /* Copy N bytes of SRC to DEST, guaranteeing
141    correct behavior for overlapping strings.  */
142 __STRING_INLINE void *
143 memmove (void *__dest, __const void *__src, size_t __n)
144 {
145   register unsigned long int __d0, __d1, __d2;
146   register void *__tmp = __dest;
147   if (__dest < __src)
148     __asm__ __volatile__
149       ("cld\n\t"
150        "rep; movsb"
151        : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
152        : "0" (__n), "1" (__src), "2" (__tmp)
153        : "memory");
154   else
155     __asm__ __volatile__
156       ("std\n\t"
157        "rep; movsb\n\t"
158        "cld"
159        : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
160        : "0" (__n), "1" (__n - 1 + (__const char *) __src),
161          "2" (__n - 1 + (char *) __tmp)
162        : "memory");
163   return __dest;
164 }
165 #endif
166
167 /* Compare N bytes of S1 and S2.  */
168 #define _HAVE_STRING_ARCH_memcmp 1
169 #ifndef _FORCE_INLINES
170 # ifndef __PIC__
171 /* gcc has problems to spill registers when using PIC.  */
172 __STRING_INLINE int
173 memcmp (__const void *__s1, __const void *__s2, size_t __n)
174 {
175   register unsigned long int __d0, __d1, __d2;
176   register int __res;
177   __asm__ __volatile__
178     ("cld\n\t"
179      "testl %3,%3\n\t"
180      "repe; cmpsb\n\t"
181      "je        1f\n\t"
182      "sbbl      %0,%0\n\t"
183      "orl       $1,%0\n"
184      "1:"
185      : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
186      : "0" (0), "1" (__s1), "2" (__s2), "3" (__n)
187      : "cc");
188   return __res;
189 }
190 # endif
191 #endif
192
193 /* Set N bytes of S to C.  */
194 #define _HAVE_STRING_ARCH_memset 1
195 #define memset(s, c, n) \
196   (__extension__ (__builtin_constant_p (n) && (n) <= 16                       \
197                   ? ((n) == 1                                                 \
198                      ? __memset_c1 (s, c)                                     \
199                      : __memset_gc (s, c, n))                                 \
200                   : (__builtin_constant_p (c)                                 \
201                      ? (__builtin_constant_p (n)                              \
202                         ? __memset_ccn (s, c, n)                              \
203                         : memset (s, c, n))                                   \
204                      : (__builtin_constant_p (n)                              \
205                         ? __memset_gcn (s, c, n)                              \
206                         : memset (s, c, n)))))
207
208 #define __memset_c1(s, c) ({ void *__s = (s);                                 \
209                              *((unsigned char *) __s) = (unsigned char) (c);  \
210                              __s; })
211
212 #define __memset_gc(s, c, n) \
213   ({ void *__s = (s);                                                         \
214      union {                                                                  \
215        unsigned int __ui;                                                     \
216        unsigned short int __usi;                                              \
217        unsigned char __uc;                                                    \
218      } *__u = __s;                                                            \
219      unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101;  \
220                                                                               \
221      /* We apply a trick here.  `gcc' would implement the following           \
222         assignments using immediate operands.  But this uses to much          \
223         memory (7, instead of 4 bytes).  So we force the value in a           \
224         registers.  */                                                        \
225      if (n == 3 || n >= 5)                                                    \
226        __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c));                    \
227                                                                               \
228      /* This `switch' statement will be removed at compile-time.  */          \
229      switch (n)                                                               \
230        {                                                                      \
231        case 15:                                                               \
232          __u->__ui = __c;                                                     \
233          __u = __extension__ ((void *) __u + 4);                              \
234        case 11:                                                               \
235          __u->__ui = __c;                                                     \
236          __u = __extension__ ((void *) __u + 4);                              \
237        case 7:                                                                \
238          __u->__ui = __c;                                                     \
239          __u = __extension__ ((void *) __u + 4);                              \
240        case 3:                                                                \
241          __u->__usi = (unsigned short int) __c;                               \
242          __u = __extension__ ((void *) __u + 2);                              \
243          __u->__uc = (unsigned char) __c;                                     \
244          break;                                                               \
245                                                                               \
246        case 14:                                                               \
247          __u->__ui = __c;                                                     \
248          __u = __extension__ ((void *) __u + 4);                              \
249        case 10:                                                               \
250          __u->__ui = __c;                                                     \
251          __u = __extension__ ((void *) __u + 4);                              \
252        case 6:                                                                \
253          __u->__ui = __c;                                                     \
254          __u = __extension__ ((void *) __u + 4);                              \
255        case 2:                                                                \
256          __u->__usi = (unsigned short int) __c;                               \
257          break;                                                               \
258                                                                               \
259        case 13:                                                               \
260          __u->__ui = __c;                                                     \
261          __u = __extension__ ((void *) __u + 4);                              \
262        case 9:                                                                \
263          __u->__ui = __c;                                                     \
264          __u = __extension__ ((void *) __u + 4);                              \
265        case 5:                                                                \
266          __u->__ui = __c;                                                     \
267          __u = __extension__ ((void *) __u + 4);                              \
268        case 1:                                                                \
269          __u->__uc = (unsigned char) __c;                                     \
270          break;                                                               \
271                                                                               \
272        case 16:                                                               \
273          __u->__ui = __c;                                                     \
274          __u = __extension__ ((void *) __u + 4);                              \
275        case 12:                                                               \
276          __u->__ui = __c;                                                     \
277          __u = __extension__ ((void *) __u + 4);                              \
278        case 8:                                                                \
279          __u->__ui = __c;                                                     \
280          __u = __extension__ ((void *) __u + 4);                              \
281        case 4:                                                                \
282          __u->__ui = __c;                                                     \
283        case 0:                                                                \
284          break;                                                               \
285        }                                                                      \
286                                                                               \
287      __s; })
288
289 #define __memset_ccn(s, c, n) \
290   (((n) % 4 == 0)                                                             \
291    ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
292                        n)                                                     \
293    : (((n) % 2 == 0)                                                          \
294       ? __memset_ccn_by2 (s,                                                  \
295                           ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
296                            n)                                                 \
297       : memset (s, c, n)))
298
299 __STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
300                                         size_t __n);
301
302 __STRING_INLINE void *
303 __memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
304 {
305   register void *__tmp = __s;
306   register unsigned long int __d0;
307 #ifdef __i686__
308   __asm__ __volatile__
309     ("cld\n\t"
310      "rep; stosl"
311      : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0)
312      : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
313      : "memory", "cc");
314 #else
315   __asm__ __volatile__
316     ("1:\n\t"
317      "movl      %0,(%1)\n\t"
318      "addl      $4,%1\n\t"
319      "decl      %2\n\t"
320      "jnz       1b\n"
321      : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0)
322      : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
323      : "memory", "cc");
324 #endif
325   return __s;
326 }
327
328 __STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
329                                         size_t __n);
330
331 __STRING_INLINE void *
332 __memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
333 {
334   register unsigned long int __d0, __d1;
335   register void *__tmp = __s;
336 #ifdef __i686__
337   __asm__ __volatile__
338     ("cld\n\t"
339      "rep; stosl\n"
340      "stosw"
341     : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1)
342      : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
343      : "memory", "cc");
344 #else
345   __asm__ __volatile__
346     ("1:\tmovl  %0,(%1)\n\t"
347      "leal      4(%1),%1\n\t"
348      "decl      %2\n\t"
349      "jnz       1b\n"
350      "movw      %w0,(%1)"
351      : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
352      : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
353      : "memory", "cc");
354 #endif
355   return __s;
356 }
357
358 #define __memset_gcn(s, c, n) \
359   (((n) % 4 == 0)                                                             \
360    ? __memset_gcn_by4 (s, c, n)                                               \
361    : (((n) % 2 == 0)                                                          \
362       ? __memset_gcn_by2 (s, c, n)                                            \
363       : memset (s, c, n)))
364
365 __STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
366
367 __STRING_INLINE void *
368 __memset_gcn_by4 (void *__s, int __c, size_t __n)
369 {
370   register void *__tmp = __s;
371   register unsigned long int __d0;
372   __asm__ __volatile__
373     ("movb      %b0,%h0\n"
374      "pushw     %w0\n\t"
375      "shll      $16,%0\n\t"
376      "popw      %w0\n"
377      "1:\n\t"
378      "movl      %0,(%1)\n\t"
379      "addl      $4,%1\n\t"
380      "decl      %2\n\t"
381      "jnz       1b\n"
382      : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0)
383      : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
384      : "memory", "cc");
385   return __s;
386 }
387
388 __STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
389
390 __STRING_INLINE void *
391 __memset_gcn_by2 (void *__s, int __c, size_t __n)
392 {
393   register unsigned long int __d0, __d1;
394   register void *__tmp = __s;
395   __asm__ __volatile__
396     ("movb      %b0,%h0\n\t"
397      "pushw     %w0\n\t"
398      "shll      $16,%0\n\t"
399      "popw      %w0\n"
400      "1:\n\t"
401      "movl      %0,(%1)\n\t"
402      "leal      4(%1),%1\n\t"
403      "decl      %2\n\t"
404      "jnz       1b\n"
405      "movw      %w0,(%1)"
406      : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
407      : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
408      : "memory", "cc");
409   return __s;
410 }
411
412
413 /* Search N bytes of S for C.  */
414 #define _HAVE_STRING_ARCH_memchr 1
415 #ifndef _FORCE_INLINES
416 __STRING_INLINE void *
417 memchr (__const void *__s, int __c, size_t __n)
418 {
419   register unsigned long int __d0;
420 #ifdef __i686__
421   register unsigned long int __d1;
422 #endif
423   register unsigned char *__res;
424   if (__n == 0)
425     return NULL;
426 #ifdef __i686__
427   __asm__ __volatile__
428     ("cld\n\t"
429      "repne; scasb\n\t"
430      "cmovne %2,%0"
431      : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
432      : "a" (__c), "0" (__s), "1" (__n), "2" (1)
433      : "cc");
434 #else
435   __asm__ __volatile__
436     ("cld\n\t"
437      "repne; scasb\n\t"
438      "je        1f\n\t"
439      "movl      $1,%0\n"
440      "1:"
441      : "=D" (__res), "=&c" (__d0)
442      : "a" (__c), "0" (__s), "1" (__n)
443      : "cc");
444 #endif
445   return __res - 1;
446 }
447 #endif
448
449 /* Return pointer to C in S.  */
450 #define _HAVE_STRING_ARCH_rawmemchr 1
451 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
452
453 #ifndef _FORCE_INLINES
454 __STRING_INLINE void *
455 __rawmemchr (const void *__s, int __c)
456 {
457   register unsigned long int __d0;
458   register unsigned char *__res;
459   __asm__ __volatile__
460     ("cld\n\t"
461      "repne; scasb\n\t"
462      : "=D" (__res), "=&c" (__d0)
463      : "a" (__c), "0" (__s), "1" (0xffffffff)
464      : "cc");
465   return __res - 1;
466 }
467 # ifdef __USE_GNU
468 __STRING_INLINE void *
469 rawmemchr (const void *__s, int __c)
470 {
471   return __rawmemchr (__s, __c);
472 }
473 # endif /* use GNU */
474 #endif
475
476
477 /* Return the length of S.  */
478 #define _HAVE_STRING_ARCH_strlen 1
479 #define strlen(str) \
480   (__extension__ (__builtin_constant_p (str)                                  \
481                   ? __builtin_strlen (str)                                    \
482                   : __strlen_g (str)))
483 __STRING_INLINE size_t __strlen_g (__const char *__str);
484
485 __STRING_INLINE size_t
486 __strlen_g (__const char *__str)
487 {
488   register char __dummy;
489   register __const char *__tmp = __str;
490   __asm__ __volatile__
491     ("1:\n\t"
492      "movb      (%0),%b1\n\t"
493      "leal      1(%0),%0\n\t"
494      "testb     %b1,%b1\n\t"
495      "jne       1b"
496      : "=r" (__tmp), "=&q" (__dummy)
497      : "0" (__str)
498      : "memory", "cc" );
499   return __tmp - __str - 1;
500 }
501
502
503 /* Copy SRC to DEST.  */
504 #define _HAVE_STRING_ARCH_strcpy 1
505 #define strcpy(dest, src) \
506   (__extension__ (__builtin_constant_p (src)                                  \
507                   ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8          \
508                      ? __strcpy_small (dest, src, strlen (src) + 1)           \
509                      : (char *) memcpy ((char *) dest,                        \
510                                         (__const char *) src,                 \
511                                         strlen (src) + 1))                    \
512                   : __strcpy_g (dest, src)))
513
514 #define __strcpy_small(dest, src, srclen) \
515   (__extension__ ({ char *__dest = (dest);                                    \
516                     union {                                                   \
517                       unsigned int __ui;                                      \
518                       unsigned short int __usi;                               \
519                       unsigned char __uc;                                     \
520                       char __c;                                               \
521                     } *__u = (void *) __dest;                                 \
522                     switch (srclen)                                           \
523                       {                                                       \
524                       case 1:                                                 \
525                         __u->__uc = '\0';                                     \
526                         break;                                                \
527                       case 2:                                                 \
528                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
529                         break;                                                \
530                       case 3:                                                 \
531                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
532                         __u = __extension__ ((void *) __u + 2);               \
533                         __u->__uc = '\0';                                     \
534                         break;                                                \
535                       case 4:                                                 \
536                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
537                         break;                                                \
538                       case 5:                                                 \
539                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
540                         __u = __extension__ ((void *) __u + 4);               \
541                         __u->__uc = '\0';                                     \
542                         break;                                                \
543                       case 6:                                                 \
544                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
545                         __u = __extension__ ((void *) __u + 4);               \
546                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
547                         break;                                                \
548                       case 7:                                                 \
549                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
550                         __u = __extension__ ((void *) __u + 4);               \
551                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
552                         __u = __extension__ ((void *) __u + 2);               \
553                         __u->__uc = '\0';                                     \
554                         break;                                                \
555                       case 8:                                                 \
556                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
557                         __u = __extension__ ((void *) __u + 4);               \
558                         __u->__ui = __STRING_SMALL_GET32 (src, 4);            \
559                         break;                                                \
560                       }                                                       \
561                     (char *) __dest; }))
562
563 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
564
565 __STRING_INLINE char *
566 __strcpy_g (char *__dest, __const char *__src)
567 {
568   register char *__tmp = __dest;
569   register char __dummy;
570   __asm__ __volatile__
571     (
572      "1:\n\t"
573      "movb      (%0),%b2\n\t"
574      "leal      1(%0),%0\n\t"
575      "movb      %b2,(%1)\n\t"
576      "leal      1(%1),%1\n\t"
577      "testb     %b2,%b2\n\t"
578      "jne       1b"
579      : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
580      : "0" (__src), "1" (__tmp)
581      : "memory", "cc");
582   return __dest;
583 }
584
585
586 #ifdef __USE_GNU
587 # define _HAVE_STRING_ARCH_stpcpy 1
588 /* Copy SRC to DEST.  */
589 # define __stpcpy(dest, src) \
590   (__extension__ (__builtin_constant_p (src)                                  \
591                   ? (strlen (src) + 1 <= 8                                    \
592                      ? __stpcpy_small (dest, src, strlen (src) + 1)           \
593                      : __stpcpy_c (dest, src, strlen (src) + 1))              \
594                   : __stpcpy_g (dest, src)))
595 # define __stpcpy_c(dest, src, srclen) \
596   ((srclen) % 4 == 0                                                          \
597    ? __mempcpy_by4 (dest, src, srclen) - 1                                    \
598    : ((srclen) % 2 == 0                                                       \
599       ? __mempcpy_by2 (dest, src, srclen) - 1                                 \
600       : __mempcpy_byn (dest, src, srclen) - 1))
601
602 /* In glibc itself we use this symbol for namespace reasons.  */
603 # define stpcpy(dest, src) __stpcpy (dest, src)
604
605 # define __stpcpy_small(dest, src, srclen) \
606   (__extension__ ({ union {                                                   \
607                       unsigned int __ui;                                      \
608                       unsigned short int __usi;                               \
609                       unsigned char __uc;                                     \
610                       char __c;                                               \
611                     } *__u = (void *) (dest);                                 \
612                     switch (srclen)                                           \
613                       {                                                       \
614                       case 1:                                                 \
615                         __u->__uc = '\0';                                     \
616                         break;                                                \
617                       case 2:                                                 \
618                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
619                         __u = __extension__ ((void *) __u + 1);               \
620                         break;                                                \
621                       case 3:                                                 \
622                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
623                         __u = __extension__ ((void *) __u + 2);               \
624                         __u->__uc = '\0';                                     \
625                         break;                                                \
626                       case 4:                                                 \
627                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
628                         __u = __extension__ ((void *) __u + 3);               \
629                         break;                                                \
630                       case 5:                                                 \
631                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
632                         __u = __extension__ ((void *) __u + 4);               \
633                         __u->__uc = '\0';                                     \
634                         break;                                                \
635                       case 6:                                                 \
636                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
637                         __u = __extension__ ((void *) __u + 4);               \
638                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
639                         __u = __extension__ ((void *) __u + 1);               \
640                         break;                                                \
641                       case 7:                                                 \
642                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
643                         __u = __extension__ ((void *) __u + 4);               \
644                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
645                         __u = __extension__ ((void *) __u + 2);               \
646                         __u->__uc = '\0';                                     \
647                         break;                                                \
648                       case 8:                                                 \
649                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
650                         __u = __extension__ ((void *) __u + 4);               \
651                         __u->__ui = __STRING_SMALL_GET32 (src, 4);            \
652                         __u = __extension__ ((void *) __u + 3);               \
653                         break;                                                \
654                       }                                                       \
655                     (char *) __u; }))
656
657 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
658                                      size_t __srclen);
659
660 __STRING_INLINE char *
661 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
662 {
663   register char *__tmp = __dest;
664   register unsigned long int __d0, __d1;
665   __asm__ __volatile__
666     ("1:\n\t"
667      "movl      (%2),%0\n\t"
668      "leal      4(%2),%2\n\t"
669      "movl      %0,(%1)\n\t"
670      "leal      4(%1),%1\n\t"
671      "decl      %3\n\t"
672      "jnz       1b"
673      : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
674      : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
675      : "memory", "cc");
676   return __tmp;
677 }
678
679 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
680                                      size_t __srclen);
681
682 __STRING_INLINE char *
683 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
684 {
685   register char *__tmp = __dest;
686   register unsigned long int __d0, __d1;
687   __asm__ __volatile__
688     ("shrl      $1,%3\n\t"
689      "jz        2f\n"                 /* only a word */
690      "1:\n\t"
691      "movl      (%2),%0\n\t"
692      "leal      4(%2),%2\n\t"
693      "movl      %0,(%1)\n\t"
694      "leal      4(%1),%1\n\t"
695      "decl      %3\n\t"
696      "jnz       1b\n"
697      "2:\n\t"
698      "movw      (%2),%w0\n\t"
699      "movw      %w0,(%1)"
700      : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
701      : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
702      : "memory", "cc");
703   return __tmp + 2;
704 }
705
706 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
707                                      size_t __srclen);
708
709 __STRING_INLINE char *
710 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
711 {
712   register unsigned long __d0, __d1;
713   register char *__tmp = __dest;
714   __asm__ __volatile__
715     ("cld\n\t"
716      "shrl      $1,%%ecx\n\t"
717      "jnc       1f\n\t"
718      "movsb\n"
719      "1:\n\t"
720      "shrl      $1,%%ecx\n\t"
721      "jnc       2f\n\t"
722      "movsw\n"
723      "2:\n\t"
724      "rep; movsl"
725      : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
726      : "0" (__tmp), "1" (__srclen), "2" (__src)
727      : "memory", "cc");
728   return __tmp;
729 }
730
731 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
732
733 __STRING_INLINE char *
734 __stpcpy_g (char *__dest, __const char *__src)
735 {
736   register char *__tmp = __dest;
737   register char __dummy;
738   __asm__ __volatile__
739     (
740      "1:\n\t"
741      "movb      (%0),%b2\n\t"
742      "leal      1(%0),%0\n\t"
743      "movb      %b2,(%1)\n\t"
744      "leal      1(%1),%1\n\t"
745      "testb     %b2,%b2\n\t"
746      "jne       1b"
747      : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
748      : "0" (__src), "1" (__tmp)
749      : "memory", "cc");
750   return __tmp - 1;
751 }
752 #endif
753
754
755 /* Copy no more than N characters of SRC to DEST.  */
756 #define _HAVE_STRING_ARCH_strncpy 1
757 #define strncpy(dest, src, n) \
758   (__extension__ (__builtin_constant_p (src)                                  \
759                   ? ((strlen (src) + 1 >= ((size_t) (n))                      \
760                       ? (char *) memcpy ((char *) dest,                       \
761                                          (__const char *) src, n)             \
762                       : __strncpy_cg (dest, src, strlen (src) + 1, n)))       \
763                   : __strncpy_gg (dest, src, n)))
764 #define __strncpy_cg(dest, src, srclen, n) \
765   (((srclen) % 4 == 0)                                                        \
766    ? __strncpy_by4 (dest, src, srclen, n)                                     \
767    : (((srclen) % 2 == 0)                                                     \
768       ? __strncpy_by2 (dest, src, srclen, n)                                  \
769       : __strncpy_byn (dest, src, srclen, n)))
770
771 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
772                                      size_t __srclen, size_t __n);
773
774 __STRING_INLINE char *
775 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
776 {
777   register char *__tmp = __dest;
778   register int __dummy1, __dummy2;
779   __asm__ __volatile__
780     ("1:\n\t"
781      "movl      (%2),%0\n\t"
782      "leal      4(%2),%2\n\t"
783      "movl      %0,(%1)\n\t"
784      "leal      4(%1),%1\n\t"
785      "decl      %3\n\t"
786      "jnz       1b"
787      : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
788      : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
789      : "memory", "cc");
790   (void) memset (__tmp, '\0', __n - __srclen);
791   return __dest;
792 }
793
794 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
795                                      size_t __srclen, size_t __n);
796
797 __STRING_INLINE char *
798 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
799 {
800   register char *__tmp = __dest;
801   register int __dummy1, __dummy2;
802   __asm__ __volatile__
803     ("shrl      $1,%3\n\t"
804      "jz        2f\n"                 /* only a word */
805      "1:\n\t"
806      "movl      (%2),%0\n\t"
807      "leal      4(%2),%2\n\t"
808      "movl      %0,(%1)\n\t"
809      "leal      4(%1),%1\n\t"
810      "decl      %3\n\t"
811      "jnz       1b\n"
812      "2:\n\t"
813      "movw      (%2),%w0\n\t"
814      "movw      %w0,(%1)\n\t"
815      : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
816      : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
817      : "memory", "cc");
818   (void) memset (__tmp + 2, '\0', __n - __srclen);
819   return __dest;
820 }
821
822 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
823                                      size_t __srclen, size_t __n);
824
825 __STRING_INLINE char *
826 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
827 {
828   register unsigned long int __d0, __d1;
829   register char *__tmp = __dest;
830   __asm__ __volatile__
831     ("cld\n\t"
832      "shrl      $1,%1\n\t"
833      "jnc       1f\n\t"
834      "movsb\n"
835      "1:\n\t"
836      "shrl      $1,%1\n\t"
837      "jnc       2f\n\t"
838      "movsw\n"
839      "2:\n\t"
840      "rep; movsl"
841      : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
842      : "1" (__srclen), "0" (__tmp),"2" (__src)
843      : "memory", "cc");
844   (void) memset (__tmp, '\0', __n - __srclen);
845   return __dest;
846 }
847
848 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
849                                     size_t __n);
850
851 __STRING_INLINE char *
852 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
853 {
854   register char *__tmp = __dest;
855   register char __dummy;
856   if (__n > 0)
857     __asm__ __volatile__
858       ("1:\n\t"
859        "movb    (%0),%2\n\t"
860        "incl    %0\n\t"
861        "movb    %2,(%1)\n\t"
862        "incl    %1\n\t"
863        "decl    %3\n\t"
864        "je      3f\n\t"
865        "testb   %2,%2\n\t"
866        "jne     1b\n\t"
867        "2:\n\t"
868        "movb    %2,(%1)\n\t"
869        "incl    %1\n\t"
870        "decl    %3\n\t"
871        "jne     2b\n\t"
872        "3:"
873        : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
874        : "0" (__src), "1" (__tmp), "3" (__n)
875        : "memory", "cc");
876
877   return __dest;
878 }
879
880
881 /* Append SRC onto DEST.  */
882 #define _HAVE_STRING_ARCH_strcat 1
883 #define strcat(dest, src) \
884   (__extension__ (__builtin_constant_p (src)                                  \
885                   ? __strcat_c (dest, src, strlen (src) + 1)                  \
886                   : __strcat_g (dest, src)))
887
888 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
889                                   size_t __srclen);
890
891 __STRING_INLINE char *
892 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
893 {
894 #ifdef __i686__
895   register unsigned long int __d0;
896   register char *__tmp;
897   __asm__ __volatile__
898     ("repne; scasb"
899      : "=D" (__tmp), "=&c" (__d0)
900      : "0" (__dest), "1" (0xffffffff), "a" (0)
901      : "cc");
902   --__tmp;
903 #else
904   register char *__tmp = __dest - 1;
905   __asm__ __volatile__
906     ("1:\n\t"
907      "incl      %0\n\t"
908      "cmpb      $0,(%0)\n\t"
909      "jne       1b\n"
910      : "=r" (__tmp)
911      : "0" (__tmp)
912      : "cc");
913 #endif
914   (void) memcpy (__tmp, __src, __srclen);
915   return __dest;
916 }
917
918 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
919
920 __STRING_INLINE char *
921 __strcat_g (char *__dest, __const char *__src)
922 {
923   register char *__tmp = __dest - 1;
924   register char __dummy;
925   __asm__ __volatile__
926     ("1:\n\t"
927      "incl      %1\n\t"
928      "cmpb      $0,(%1)\n\t"
929      "jne       1b\n"
930      "2:\n\t"
931      "movb      (%2),%b0\n\t"
932      "incl      %2\n\t"
933      "movb      %b0,(%1)\n\t"
934      "incl      %1\n\t"
935      "testb     %b0,%b0\n\t"
936      "jne       2b\n"
937      : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
938      : "1"  (__tmp), "2"  (__src)
939      : "memory", "cc");
940   return __dest;
941 }
942
943
944 /* Append no more than N characters from SRC onto DEST.  */
945 #define _HAVE_STRING_ARCH_strncat 1
946 #define strncat(dest, src, n) \
947   (__extension__ ({ char *__dest = (dest);                                    \
948                     __builtin_constant_p (src) && __builtin_constant_p (n)    \
949                     ? (strlen (src) < ((size_t) (n))                          \
950                        ? strcat (__dest, src)                                 \
951                        : (memcpy (strchr (__dest, '\0'),                      \
952                                   (__const char *) src, n), __dest))          \
953                     : __strncat_g (__dest, src, n); }))
954
955 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
956                                    size_t __n);
957
958 __STRING_INLINE char *
959 __strncat_g (char *__dest, __const char __src[], size_t __n)
960 {
961   register char *__tmp = __dest;
962   register char __dummy;
963 #ifdef __i686__
964   __asm__ __volatile__
965     ("repne; scasb\n"
966      "decl %1\n\t"
967      "1:\n\t"
968      "decl      %3\n\t"
969      "js        2f\n\t"
970      "movb      (%2),%b0\n\t"
971      "movsb\n\t"
972      "testb     %b0,%b0\n\t"
973      "jne       1b\n\t"
974      "decl      %1\n"
975      "2:\n\t"
976      "movb      $0,(%1)"
977      : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
978      : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
979      : "memory", "cc");
980 #else
981   --__tmp;
982   __asm__ __volatile__
983     ("1:\n\t"
984      "cmpb      $0,1(%1)\n\t"
985      "leal      1(%1),%1\n\t"
986      "jne       1b\n"
987      "2:\n\t"
988      "decl      %3\n\t"
989      "js        3f\n\t"
990      "movb      (%2),%b0\n\t"
991      "leal      1(%2),%2\n\t"
992      "movb      %b0,(%1)\n\t"
993      "leal      1(%1),%1\n\t"
994      "testb     %b0,%b0\n\t"
995      "jne       2b\n\t"
996      "decl      %1\n"
997      "3:\n\t"
998      "movb      $0,(%1)"
999      : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1000      : "1" (__tmp), "2" (__src), "3" (__n)
1001      : "memory", "cc");
1002 #endif
1003   return __dest;
1004 }
1005
1006
1007 /* Compare S1 and S2.  */
1008 #define _HAVE_STRING_ARCH_strcmp 1
1009 #define strcmp(s1, s2) \
1010   (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2)      \
1011                   && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4)              \
1012                   && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4)              \
1013                   ? memcmp ((__const char *) s1, (__const char *) s2,         \
1014                             (strlen (s1) < strlen (s2)                        \
1015                              ? strlen (s1) : strlen (s2)) + 1)                \
1016                   : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1       \
1017                      && sizeof ((s2)[0]) == 1 && strlen (s1) < 4              \
1018                      ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1    \
1019                         ? __strcmp_cc (s1, s2, strlen (s1))                   \
1020                         : __strcmp_cg (s1, s2, strlen (s1)))                  \
1021                      : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1    \
1022                         && sizeof ((s2)[0]) == 1 && strlen (s2) < 4           \
1023                         ? (__builtin_constant_p (s1)                          \
1024                            ? __strcmp_cc (s1, s2, strlen (s2))                \
1025                            : __strcmp_gc (s1, s2, strlen (s2)))               \
1026                         : __strcmp_gg (s1, s2)))))
1027
1028 #define __strcmp_cc(s1, s2, l) \
1029   (__extension__ ({ register int __result = ((unsigned char) (s1)[0]          \
1030                                              - (unsigned char) (s2)[0]);      \
1031                     if (l > 0 && __result == 0)                               \
1032                       {                                                       \
1033                         __result = ((unsigned char) (s1)[1]                   \
1034                                     - (unsigned char) (s2)[1]);               \
1035                         if (l > 1 && __result == 0)                           \
1036                           {                                                   \
1037                             __result = ((unsigned char) (s1)[2]               \
1038                                         - (unsigned char) (s2)[2]);           \
1039                             if (l > 2 && __result == 0)                       \
1040                               __result = ((unsigned char) (s1)[3]             \
1041                                           - (unsigned char) (s2)[3]);         \
1042                           }                                                   \
1043                       }                                                       \
1044                     __result; }))
1045
1046 #define __strcmp_cg(s1, s2, l1) \
1047   (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2);     \
1048                     register int __result = (unsigned char) (s1)[0] - __s2[0];\
1049                     if (l1 > 0 && __result == 0)                              \
1050                       {                                                       \
1051                         __result = (unsigned char) (s1)[1] - __s2[1];         \
1052                         if (l1 > 1 && __result == 0)                          \
1053                           {                                                   \
1054                             __result = (unsigned char) (s1)[2] - __s2[2];     \
1055                             if (l1 > 2 && __result == 0)                      \
1056                               __result = (unsigned char) (s1)[3] - __s2[3];   \
1057                           }                                                   \
1058                       }                                                       \
1059                     __result; }))
1060
1061 #define __strcmp_gc(s1, s2, l2) \
1062   (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1);     \
1063                     register int __result = __s1[0] - (unsigned char) (s2)[0];\
1064                     if (l2 > 0 && __result == 0)                              \
1065                       {                                                       \
1066                         __result = __s1[1] - (unsigned char) (s2)[1];         \
1067                         if (l2 > 1 && __result == 0)                          \
1068                           {                                                   \
1069                             __result = __s1[2] - (unsigned char) (s2)[2];     \
1070                             if (l2 > 2 && __result == 0)                      \
1071                               __result = __s1[3] - (unsigned char) (s2)[3];   \
1072                           }                                                   \
1073                       }                                                       \
1074                     __result; }))
1075
1076 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
1077
1078 __STRING_INLINE int
1079 __strcmp_gg (__const char *__s1, __const char *__s2)
1080 {
1081   register int __res;
1082   __asm__ __volatile__
1083     ("1:\n\t"
1084      "movb      (%1),%b0\n\t"
1085      "leal      1(%1),%1\n\t"
1086      "cmpb      %b0,(%2)\n\t"
1087      "jne       2f\n\t"
1088      "leal      1(%2),%2\n\t"
1089      "testb     %b0,%b0\n\t"
1090      "jne       1b\n\t"
1091      "xorl      %0,%0\n\t"
1092      "jmp       3f\n"
1093      "2:\n\t"
1094      "movl      $1,%0\n\t"
1095      "jb        3f\n\t"
1096      "negl      %0\n"
1097      "3:"
1098      : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1099      : "1" (__s1), "2" (__s2)
1100      : "cc");
1101   return __res;
1102 }
1103
1104
1105 /* Compare N characters of S1 and S2.  */
1106 #define _HAVE_STRING_ARCH_strncmp 1
1107 #define strncmp(s1, s2, n) \
1108   (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n))   \
1109                   ? strcmp (s1, s2)                                           \
1110                   : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1111                      ? strcmp (s1, s2)                                        \
1112                      : __strncmp_g (s1, s2, n))))
1113
1114 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1115                                  size_t __n);
1116
1117 __STRING_INLINE int
1118 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1119 {
1120   register int __res;
1121   __asm__ __volatile__
1122     ("1:\n\t"
1123      "decl      %3\n\t"
1124      "js        2f\n\t"
1125      "movb      (%1),%b0\n\t"
1126      "incl      %1\n\t"
1127      "cmpb      %b0,(%2)\n\t"
1128      "jne       3f\n\t"
1129      "incl      %2\n\t"
1130      "testb     %b0,%b0\n\t"
1131      "jne       1b\n"
1132      "2:\n\t"
1133      "xorl      %0,%0\n\t"
1134      "jmp       4f\n"
1135      "3:\n\t"
1136      "movl      $1,%0\n\t"
1137      "jb        4f\n\t"
1138      "negl      %0\n"
1139      "4:"
1140      : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1141      : "1"  (__s1), "2"  (__s2),  "3" (__n)
1142      : "cc");
1143   return __res;
1144 }
1145
1146
1147 /* Find the first occurrence of C in S.  */
1148 #define _HAVE_STRING_ARCH_strchr 1
1149 #define strchr(s, c) \
1150   (__extension__ (__builtin_constant_p (c)                                    \
1151                   ? ((c) == '\0'                                              \
1152                      ? (char *) __rawmemchr (s, c)                            \
1153                      : __strchr_c (s, ((c) & 0xff) << 8))                     \
1154                   : __strchr_g (s, c)))
1155
1156 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1157
1158 __STRING_INLINE char *
1159 __strchr_c (__const char *__s, int __c)
1160 {
1161   register unsigned long int __d0;
1162   register char *__res;
1163   __asm__ __volatile__
1164     ("1:\n\t"
1165      "movb      (%0),%%al\n\t"
1166      "cmpb      %%ah,%%al\n\t"
1167      "je        2f\n\t"
1168      "leal      1(%0),%0\n\t"
1169      "testb     %%al,%%al\n\t"
1170      "jne       1b\n\t"
1171      "xorl      %0,%0\n"
1172      "2:"
1173      : "=r" (__res), "=&a" (__d0)
1174      : "0" (__s), "1" (__c)
1175      : "cc");
1176   return __res;
1177 }
1178
1179 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1180
1181 __STRING_INLINE char *
1182 __strchr_g (__const char *__s, int __c)
1183 {
1184   register unsigned long int __d0;
1185   register char *__res;
1186   __asm__ __volatile__
1187     ("movb      %%al,%%ah\n"
1188      "1:\n\t"
1189      "movb      (%0),%%al\n\t"
1190      "cmpb      %%ah,%%al\n\t"
1191      "je        2f\n\t"
1192      "leal      1(%0),%0\n\t"
1193      "testb     %%al,%%al\n\t"
1194      "jne       1b\n\t"
1195      "xorl      %0,%0\n"
1196      "2:"
1197      : "=r" (__res), "=&a" (__d0)
1198      : "0" (__s), "1" (__c)
1199      : "cc");
1200   return __res;
1201 }
1202
1203
1204 /* Find the first occurrence of C in S or the final NUL byte.  */
1205 #define _HAVE_STRING_ARCH_strchrnul 1
1206 #define __strchrnul(s, c) \
1207   (__extension__ (__builtin_constant_p (c)                                    \
1208                   ? ((c) == '\0'                                              \
1209                      ? (char *) __rawmemchr (s, c)                            \
1210                      : __strchrnul_c (s, ((c) & 0xff) << 8))                  \
1211                   : __strchrnul_g (s, c)))
1212
1213 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
1214
1215 __STRING_INLINE char *
1216 __strchrnul_c (__const char *__s, int __c)
1217 {
1218   register unsigned long int __d0;
1219   register char *__res;
1220   __asm__ __volatile__
1221     ("1:\n\t"
1222      "movb      (%0),%%al\n\t"
1223      "cmpb      %%ah,%%al\n\t"
1224      "je        2f\n\t"
1225      "leal      1(%0),%0\n\t"
1226      "testb     %%al,%%al\n\t"
1227      "jne       1b\n\t"
1228      "decl      %0\n"
1229      "2:"
1230      : "=r" (__res), "=&a" (__d0)
1231      : "0" (__s), "1" (__c)
1232      : "cc");
1233   return __res;
1234 }
1235
1236 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
1237
1238 __STRING_INLINE char *
1239 __strchrnul_g (__const char *__s, int __c)
1240 {
1241   register unsigned long int __d0;
1242   register char *__res;
1243   __asm__ __volatile__
1244     ("movb      %%al,%%ah\n"
1245      "1:\n\t"
1246      "movb      (%0),%%al\n\t"
1247      "cmpb      %%ah,%%al\n\t"
1248      "je        2f\n\t"
1249      "leal      1(%0),%0\n\t"
1250      "testb     %%al,%%al\n\t"
1251      "jne       1b\n\t"
1252      "decl      %0\n"
1253      "2:"
1254      : "=r" (__res), "=&a" (__d0)
1255      : "0" (__s), "1" (__c)
1256      : "cc");
1257   return __res;
1258 }
1259 #ifdef __USE_GNU
1260 # define strchrnul(s, c) __strchrnul (s, c)
1261 #endif
1262
1263
1264 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1265 /* Find the first occurrence of C in S.  This is the BSD name.  */
1266 # define _HAVE_STRING_ARCH_index 1
1267 # define index(s, c) \
1268   (__extension__ (__builtin_constant_p (c)                                    \
1269                   ? __strchr_c (s, ((c) & 0xff) << 8)                         \
1270                   : __strchr_g (s, c)))
1271 #endif
1272
1273
1274 /* Find the last occurrence of C in S.  */
1275 #define _HAVE_STRING_ARCH_strrchr 1
1276 #define strrchr(s, c) \
1277   (__extension__ (__builtin_constant_p (c)                                    \
1278                   ? __strrchr_c (s, ((c) & 0xff) << 8)                        \
1279                   : __strrchr_g (s, c)))
1280
1281 #ifdef __i686__
1282 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1283
1284 __STRING_INLINE char *
1285 __strrchr_c (__const char *__s, int __c)
1286 {
1287   register unsigned long int __d0, __d1;
1288   register char *__res;
1289   __asm__ __volatile__
1290     ("cld\n"
1291      "1:\n\t"
1292      "lodsb\n\t"
1293      "cmpb      %h2,%b2\n\t"
1294      "cmove     %1,%0\n\t"
1295      "testb     %b2,%b2\n\t"
1296      "jne 1b"
1297      : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1298      : "0" (1), "1" (__s), "2" (__c)
1299      : "cc");
1300   return __res - 1;
1301 }
1302
1303 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1304
1305 __STRING_INLINE char *
1306 __strrchr_g (__const char *__s, int __c)
1307 {
1308   register unsigned long int __d0, __d1;
1309   register char *__res;
1310   __asm__ __volatile__
1311     ("movb      %b2,%h2\n"
1312      "cld\n\t"
1313      "1:\n\t"
1314      "lodsb\n\t"
1315      "cmpb      %h2,%b2\n\t"
1316      "cmove     %1,%0\n\t"
1317      "testb     %b2,%b2\n\t"
1318      "jne 1b"
1319      : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1320      : "0" (1), "1" (__s), "2" (__c)
1321      : "cc");
1322   return __res - 1;
1323 }
1324 #else
1325 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1326
1327 __STRING_INLINE char *
1328 __strrchr_c (__const char *__s, int __c)
1329 {
1330   register unsigned long int __d0, __d1;
1331   register char *__res;
1332   __asm__ __volatile__
1333     ("cld\n"
1334      "1:\n\t"
1335      "lodsb\n\t"
1336      "cmpb      %%ah,%%al\n\t"
1337      "jne       2f\n\t"
1338      "leal      -1(%%esi),%0\n"
1339      "2:\n\t"
1340      "testb     %%al,%%al\n\t"
1341      "jne 1b"
1342      : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1343      : "0" (0), "1" (__s), "2" (__c)
1344      : "cc");
1345   return __res;
1346 }
1347
1348 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1349
1350 __STRING_INLINE char *
1351 __strrchr_g (__const char *__s, int __c)
1352 {
1353   register unsigned long int __d0, __d1;
1354   register char *__res;
1355   __asm__ __volatile__
1356     ("movb      %%al,%%ah\n"
1357      "cld\n\t"
1358      "1:\n\t"
1359      "lodsb\n\t"
1360      "cmpb      %%ah,%%al\n\t"
1361      "jne       2f\n\t"
1362      "leal      -1(%%esi),%0\n"
1363      "2:\n\t"
1364      "testb     %%al,%%al\n\t"
1365      "jne 1b"
1366      : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1367      : "0" (0), "1" (__s), "2" (__c)
1368      : "cc");
1369   return __res;
1370 }
1371 #endif
1372
1373
1374 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1375 /* Find the last occurrence of C in S.  This is the BSD name.  */
1376 # define _HAVE_STRING_ARCH_rindex 1
1377 # define rindex(s, c) \
1378   (__extension__ (__builtin_constant_p (c)                                    \
1379                   ? __strrchr_c (s, ((c) & 0xff) << 8)                        \
1380                   : __strrchr_g (s, c)))
1381 #endif
1382
1383
1384 /* Return the length of the initial segment of S which
1385    consists entirely of characters not in REJECT.  */
1386 #define _HAVE_STRING_ARCH_strcspn 1
1387 #define strcspn(s, reject) \
1388   (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1  \
1389                   ? ((reject)[0] == '\0'                                      \
1390                      ? strlen (s)                                             \
1391                      : ((reject)[1] == '\0'                                   \
1392                         ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00))     \
1393                         : __strcspn_cg (s, reject, strlen (reject))))         \
1394                   : __strcspn_g (s, reject)))
1395
1396 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1397
1398 __STRING_INLINE size_t
1399 __strcspn_c1 (__const char *__s, int __reject)
1400 {
1401   register unsigned long int __d0;
1402   register char *__res;
1403   __asm__ __volatile__
1404     ("1:\n\t"
1405      "movb      (%0),%%al\n\t"
1406      "leal      1(%0),%0\n\t"
1407      "cmpb      %%ah,%%al\n\t"
1408      "je        2f\n\t"
1409      "testb     %%al,%%al\n\t"
1410      "jne       1b\n"
1411      "2:"
1412      : "=r" (__res), "=&a" (__d0)
1413      : "0" (__s), "1" (__reject)
1414      : "cc");
1415   return (__res - 1) - __s;
1416 }
1417
1418 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1419                                     size_t __reject_len);
1420
1421 __STRING_INLINE size_t
1422 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1423 {
1424   register unsigned long int __d0, __d1, __d2;
1425   register __const char *__res;
1426   __asm__ __volatile__
1427     ("cld\n"
1428      "1:\n\t"
1429      "lodsb\n\t"
1430      "testb     %%al,%%al\n\t"
1431      "je        2f\n\t"
1432      "movl      %5,%%edi\n\t"
1433      "movl      %6,%%ecx\n\t"
1434      "repne; scasb\n\t"
1435      "jne       1b\n"
1436      "2:"
1437      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1438      : "0" (__s), "d" (__reject), "g" (__reject_len)
1439      : "cc");
1440   return (__res - 1) - __s;
1441 }
1442
1443 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1444 #ifdef __PIC__
1445
1446 __STRING_INLINE size_t
1447 __strcspn_g (__const char *__s, __const char *__reject)
1448 {
1449   register unsigned long int __d0, __d1, __d2;
1450   register __const char *__res;
1451   __asm__ __volatile__
1452     ("pushl     %%ebx\n\t"
1453      "movl      %4,%%edi\n\t"
1454      "cld\n\t"
1455      "repne; scasb\n\t"
1456      "notl      %%ecx\n\t"
1457      "leal      -1(%%ecx),%%ebx\n"
1458      "1:\n\t"
1459      "lodsb\n\t"
1460      "testb     %%al,%%al\n\t"
1461      "je        2f\n\t"
1462      "movl      %4,%%edi\n\t"
1463      "movl      %%ebx,%%ecx\n\t"
1464      "repne; scasb\n\t"
1465      "jne       1b\n"
1466      "2:\n\t"
1467      "popl      %%ebx"
1468      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1469      : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1470      : "cc");
1471   return (__res - 1) - __s;
1472 }
1473 #else
1474 __STRING_INLINE size_t
1475 __strcspn_g (__const char *__s, __const char *__reject)
1476 {
1477   register unsigned long int __d0, __d1, __d2, __d3;
1478   register __const char *__res;
1479   __asm__ __volatile__
1480     ("cld\n\t"
1481      "repne; scasb\n\t"
1482      "notl      %%ecx\n\t"
1483      "leal      -1(%%ecx),%%edx\n"
1484      "1:\n\t"
1485      "lodsb\n\t"
1486      "testb     %%al,%%al\n\t"
1487      "je        2f\n\t"
1488      "movl      %%ebx,%%edi\n\t"
1489      "movl      %%edx,%%ecx\n\t"
1490      "repne; scasb\n\t"
1491      "jne       1b\n"
1492      "2:"
1493      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1494      : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1495      : "cc");
1496   return (__res - 1) - __s;
1497 }
1498 #endif
1499
1500
1501 /* Return the length of the initial segment of S which
1502    consists entirely of characters in ACCEPT.  */
1503 #define _HAVE_STRING_ARCH_strspn 1
1504 #define strspn(s, accept) \
1505   (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
1506                   ? ((accept)[0] == '\0'                                      \
1507                      ? 0                                                      \
1508                      : ((accept)[1] == '\0'                                   \
1509                         ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00))     \
1510                         : __strspn_cg (s, accept, strlen (accept))))          \
1511                   : __strspn_g (s, accept)))
1512
1513 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1514
1515 __STRING_INLINE size_t
1516 __strspn_c1 (__const char *__s, int __accept)
1517 {
1518   register unsigned long int __d0;
1519   register char *__res;
1520   /* Please note that __accept never can be '\0'.  */
1521   __asm__ __volatile__
1522     ("1:\n\t"
1523      "movb      (%0),%b1\n\t"
1524      "leal      1(%0),%0\n\t"
1525      "cmpb      %h1,%b1\n\t"
1526      "je        1b"
1527      : "=r" (__res), "=&q" (__d0)
1528      : "0" (__s), "1" (__accept)
1529      : "cc");
1530   return (__res - 1) - __s;
1531 }
1532
1533 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1534                                     size_t __accept_len);
1535
1536 __STRING_INLINE size_t
1537 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1538 {
1539   register unsigned long int __d0, __d1, __d2;
1540   register __const char *__res;
1541   __asm__ __volatile__
1542     ("cld\n"
1543      "1:\n\t"
1544      "lodsb\n\t"
1545      "testb     %%al,%%al\n\t"
1546      "je        2f\n\t"
1547      "movl      %1,%%edi\n\t"
1548      "movl      %6,%%ecx\n\t"
1549      "repne; scasb\n\t"
1550      "je        1b\n"
1551      "2:"
1552      : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1553      : "0" (__s), "1" (__accept), "g" (__accept_len)
1554      : "cc");
1555   return (__res - 1) - __s;
1556 }
1557
1558 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1559 #ifdef __PIC__
1560
1561 __STRING_INLINE size_t
1562 __strspn_g (__const char *__s, __const char *__accept)
1563 {
1564   register unsigned long int __d0, __d1, __d2;
1565   register __const char *__res;
1566   __asm__ __volatile__
1567     ("pushl     %%ebx\n\t"
1568      "cld\n\t"
1569      "repne; scasb\n\t"
1570      "notl      %%ecx\n\t"
1571      "leal      -1(%%ecx),%%ebx\n"
1572      "1:\n\t"
1573      "lodsb\n\t"
1574      "testb     %%al,%%al\n\t"
1575      "je        2f\n\t"
1576      "movl      %%edx,%%edi\n\t"
1577      "movl      %%ebx,%%ecx\n\t"
1578      "repne; scasb\n\t"
1579      "je        1b\n"
1580      "2:\n\t"
1581      "popl      %%ebx"
1582      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1583      : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1584      : "cc");
1585   return (__res - 1) - __s;
1586 }
1587 #else
1588 __STRING_INLINE size_t
1589 __strspn_g (__const char *__s, __const char *__accept)
1590 {
1591   register unsigned long int __d0, __d1, __d2, __d3;
1592   register __const char *__res;
1593   __asm__ __volatile__
1594     ("cld\n\t"
1595      "repne; scasb\n\t"
1596      "notl      %%ecx\n\t"
1597      "leal      -1(%%ecx),%%edx\n"
1598      "1:\n\t"
1599      "lodsb\n\t"
1600      "testb     %%al,%%al\n\t"
1601      "je        2f\n\t"
1602      "movl      %%ebx,%%edi\n\t"
1603      "movl      %%edx,%%ecx\n\t"
1604      "repne; scasb\n\t"
1605      "je        1b\n"
1606      "2:"
1607      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1608      : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1609      : "cc");
1610   return (__res - 1) - __s;
1611 }
1612 #endif
1613
1614
1615 /* Find the first occurrence in S of any character in ACCEPT.  */
1616 #define _HAVE_STRING_ARCH_strpbrk 1
1617 #define strpbrk(s, accept) \
1618   (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
1619                   ? ((accept)[0] == '\0'                                      \
1620                      ? NULL                                                   \
1621                      : ((accept)[1] == '\0'                                   \
1622                         ? strchr (s, (accept)[0])                             \
1623                         : __strpbrk_cg (s, accept, strlen (accept))))         \
1624                   : __strpbrk_g (s, accept)))
1625
1626 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1627                                     size_t __accept_len);
1628
1629 __STRING_INLINE char *
1630 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1631 {
1632   register unsigned long int __d0, __d1, __d2;
1633   register char *__res;
1634   __asm__ __volatile__
1635     ("cld\n"
1636      "1:\n\t"
1637      "lodsb\n\t"
1638      "testb     %%al,%%al\n\t"
1639      "je        2f\n\t"
1640      "movl      %5,%%edi\n\t"
1641      "movl      %6,%%ecx\n\t"
1642      "repne; scasb\n\t"
1643      "jne       1b\n\t"
1644      "decl      %0\n\t"
1645      "jmp       3f\n"
1646      "2:\n\t"
1647      "xorl      %0,%0\n"
1648      "3:"
1649      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1650      : "0" (__s), "d" (__accept), "g" (__accept_len)
1651      : "cc");
1652   return __res;
1653 }
1654
1655 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1656 #ifdef __PIC__
1657
1658 __STRING_INLINE char *
1659 __strpbrk_g (__const char *__s, __const char *__accept)
1660 {
1661   register unsigned long int __d0, __d1, __d2;
1662   register char *__res;
1663   __asm__ __volatile__
1664     ("pushl     %%ebx\n\t"
1665      "movl      %%edx,%%edi\n\t"
1666      "cld\n\t"
1667      "repne; scasb\n\t"
1668      "notl      %%ecx\n\t"
1669      "leal      -1(%%ecx),%%ebx\n"
1670      "1:\n\t"
1671      "lodsb\n\t"
1672      "testb     %%al,%%al\n\t"
1673      "je        2f\n\t"
1674      "movl      %%edx,%%edi\n\t"
1675      "movl      %%ebx,%%ecx\n\t"
1676      "repne; scasb\n\t"
1677      "jne       1b\n\t"
1678      "decl      %0\n\t"
1679      "jmp       3f\n"
1680      "2:\n\t"
1681      "xorl      %0,%0\n"
1682      "3:\n\t"
1683      "popl      %%ebx"
1684      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1685      : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1686      : "cc");
1687   return __res;
1688 }
1689 #else
1690 __STRING_INLINE char *
1691 __strpbrk_g (__const char *__s, __const char *__accept)
1692 {
1693   register unsigned long int __d0, __d1, __d2, __d3;
1694   register char *__res;
1695   __asm__ __volatile__
1696     ("movl      %%ebx,%%edi\n\t"
1697      "cld\n\t"
1698      "repne; scasb\n\t"
1699      "notl      %%ecx\n\t"
1700      "leal      -1(%%ecx),%%edx\n"
1701      "1:\n\t"
1702      "lodsb\n\t"
1703      "testb     %%al,%%al\n\t"
1704      "je        2f\n\t"
1705      "movl      %%ebx,%%edi\n\t"
1706      "movl      %%edx,%%ecx\n\t"
1707      "repne; scasb\n\t"
1708      "jne       1b\n\t"
1709      "decl      %0\n\t"
1710      "jmp       3f\n"
1711      "2:\n\t"
1712      "xorl      %0,%0\n"
1713      "3:"
1714      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1715      : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1716      : "cc");
1717   return __res;
1718 }
1719 #endif
1720
1721
1722 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
1723 #define _HAVE_STRING_ARCH_strstr 1
1724 #define strstr(haystack, needle) \
1725   (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
1726                   ? ((needle)[0] == '\0'                                      \
1727                      ? haystack                                               \
1728                      : ((needle)[1] == '\0'                                   \
1729                         ? strchr (haystack, (needle)[0])                      \
1730                         : __strstr_cg (haystack, needle, strlen (needle))))   \
1731                   : __strstr_g (haystack, needle)))
1732
1733 /* Please note that this function need not handle NEEDLEs with a
1734    length shorter than two.  */
1735 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1736                                    size_t __needle_len);
1737
1738 __STRING_INLINE char *
1739 __strstr_cg (__const char *__haystack, __const char __needle[],
1740              size_t __needle_len)
1741 {
1742   register unsigned long int __d0, __d1, __d2;
1743   register char *__res;
1744   __asm__ __volatile__
1745     ("cld\n" \
1746      "1:\n\t"
1747      "movl      %6,%%edi\n\t"
1748      "movl      %5,%%eax\n\t"
1749      "movl      %4,%%ecx\n\t"
1750      "repe; cmpsb\n\t"
1751      "je        2f\n\t"
1752      "cmpb      $0,-1(%%esi)\n\t"
1753      "leal      1(%%eax),%5\n\t"
1754      "jne       1b\n\t"
1755      "xorl      %%eax,%%eax\n"
1756      "2:"
1757      : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1758      : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1759      : "cc");
1760   return __res;
1761 }
1762
1763 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1764 #ifdef __PIC__
1765
1766 __STRING_INLINE char *
1767 __strstr_g (__const char *__haystack, __const char *__needle)
1768 {
1769   register unsigned long int __d0, __d1, __d2;
1770   register char *__res;
1771   __asm__ __volatile__
1772     ("cld\n\t"
1773      "repne; scasb\n\t"
1774      "notl      %%ecx\n\t"
1775      "pushl     %%ebx\n\t"
1776      "decl      %%ecx\n\t"      /* NOTE! This also sets Z if searchstring='' */
1777      "movl      %%ecx,%%ebx\n"
1778      "1:\n\t"
1779      "movl      %%edx,%%edi\n\t"
1780      "movl      %%esi,%%eax\n\t"
1781      "movl      %%ebx,%%ecx\n\t"
1782      "repe; cmpsb\n\t"
1783      "je        2f\n\t"         /* also works for empty string, see above */
1784      "cmpb      $0,-1(%%esi)\n\t"
1785      "leal      1(%%eax),%%esi\n\t"
1786      "jne       1b\n\t"
1787      "xorl      %%eax,%%eax\n"
1788      "2:\n\t"
1789      "popl      %%ebx"
1790      : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1791      : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1792        "d" (__needle)
1793      : "cc");
1794   return __res;
1795 }
1796 #else
1797 __STRING_INLINE char *
1798 __strstr_g (__const char *__haystack, __const char *__needle)
1799 {
1800   register unsigned long int __d0, __d1, __d2, __d3;
1801   register char *__res;
1802   __asm__ __volatile__
1803     ("cld\n\t"
1804      "repne; scasb\n\t"
1805      "notl      %%ecx\n\t"
1806      "decl      %%ecx\n\t"      /* NOTE! This also sets Z if searchstring='' */
1807      "movl      %%ecx,%%edx\n"
1808      "1:\n\t"
1809      "movl      %%ebx,%%edi\n\t"
1810      "movl      %%esi,%%eax\n\t"
1811      "movl      %%edx,%%ecx\n\t"
1812      "repe; cmpsb\n\t"
1813      "je        2f\n\t"         /* also works for empty string, see above */
1814      "cmpb      $0,-1(%%esi)\n\t"
1815      "leal      1(%%eax),%%esi\n\t"
1816      "jne       1b\n\t"
1817      "xorl      %%eax,%%eax\n"
1818      "2:"
1819      : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1820      : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1821        "b" (__needle)
1822      : "cc");
1823   return __res;
1824 }
1825 #endif
1826
1827
1828 /* Bit find functions.  We define only the i686 version since for the other
1829    processors gcc generates good code.  */
1830 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1831 # ifdef __i686__
1832 #  define _HAVE_STRING_ARCH_ffs 1
1833 #  define ffs(word) (__builtin_constant_p (word)                              \
1834                      ? __builtin_ffs (word)                                   \
1835                      : ({ int __cnt, __tmp;                                   \
1836                           __asm__ __volatile__                                \
1837                             ("bsfl %2,%0\n\t"                                 \
1838                              "cmovel %1,%0"                                   \
1839                              : "=&r" (__cnt), "=r" (__tmp)                    \
1840                              : "rm" (word), "1" (-1));                        \
1841                           __cnt + 1; }))
1842
1843 #  ifndef ffsl
1844 #   define ffsl(word) ffs(word)
1845 #  endif
1846 # endif /* i686 */
1847 #endif  /* BSD || X/Open */
1848
1849 #ifndef _FORCE_INLINES
1850 # undef __STRING_INLINE
1851 #endif
1852
1853 #endif  /* use string inlines && GNU CC */