9b37f5898e4f3ef7964bc5d590aebb0f7bd149b0
[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 #define _HAVE_STRING_ARCH_memrchr 1
450 #ifndef _FORCE_INLINES
451 __STRING_INLINE void *
452 __memrchr (__const void *__s, int __c, size_t __n)
453 {
454   register unsigned long int __d0;
455 #ifdef __i686__
456   register unsigned long int __d1;
457 #endif
458   register void *__res;
459   if (__n == 0)
460     return NULL;
461 #ifdef __i686__
462   __asm__ __volatile__
463     ("std\n\t"
464      "repne; scasb\n\t"
465      "cmovne %2,%0\n\t"
466      "cld"
467      : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
468      : "a" (__c), "0" (__s), "1" (__n), "2" (1)
469      : "cc");
470 #else
471   __asm__ __volatile__
472     ("std\n\t"
473      "repne; scasb\n\t"
474      "je 1f\n\t"
475      "movl $1,%0\n"
476      "1:\tcld"
477      : "=D" (__res), "=&c" (__d0)
478      : "a" (__c), "0" (__s), "1" (__n)
479      : "cc");
480 #endif
481   return __res - 1;
482 }
483 #endif
484
485 /* Return pointer to C in S.  */
486 #define _HAVE_STRING_ARCH_rawmemchr 1
487 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
488
489 #ifndef _FORCE_INLINES
490 __STRING_INLINE void *
491 __rawmemchr (const void *__s, int __c)
492 {
493   register unsigned long int __d0;
494   register unsigned char *__res;
495   __asm__ __volatile__
496     ("cld\n\t"
497      "repne; scasb\n\t"
498      : "=D" (__res), "=&c" (__d0)
499      : "a" (__c), "0" (__s), "1" (0xffffffff)
500      : "cc");
501   return __res - 1;
502 }
503 # ifdef __USE_GNU
504 __STRING_INLINE void *
505 rawmemchr (const void *__s, int __c)
506 {
507   return __rawmemchr (__s, __c);
508 }
509 # endif /* use GNU */
510 #endif
511
512
513 /* Return the length of S.  */
514 #define _HAVE_STRING_ARCH_strlen 1
515 #define strlen(str) \
516   (__extension__ (__builtin_constant_p (str)                                  \
517                   ? __builtin_strlen (str)                                    \
518                   : __strlen_g (str)))
519 __STRING_INLINE size_t __strlen_g (__const char *__str);
520
521 __STRING_INLINE size_t
522 __strlen_g (__const char *__str)
523 {
524   register char __dummy;
525   register __const char *__tmp = __str;
526   __asm__ __volatile__
527     ("1:\n\t"
528      "movb      (%0),%b1\n\t"
529      "leal      1(%0),%0\n\t"
530      "testb     %b1,%b1\n\t"
531      "jne       1b"
532      : "=r" (__tmp), "=&q" (__dummy)
533      : "0" (__str)
534      : "memory", "cc" );
535   return __tmp - __str - 1;
536 }
537
538
539 /* Copy SRC to DEST.  */
540 #define _HAVE_STRING_ARCH_strcpy 1
541 #define strcpy(dest, src) \
542   (__extension__ (__builtin_constant_p (src)                                  \
543                   ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8          \
544                      ? __strcpy_small (dest, src, strlen (src) + 1)           \
545                      : (char *) memcpy ((char *) dest,                        \
546                                         (__const char *) src,                 \
547                                         strlen (src) + 1))                    \
548                   : __strcpy_g (dest, src)))
549
550 #define __strcpy_small(dest, src, srclen) \
551   (__extension__ ({ char *__dest = (dest);                                    \
552                     union {                                                   \
553                       unsigned int __ui;                                      \
554                       unsigned short int __usi;                               \
555                       unsigned char __uc;                                     \
556                       char __c;                                               \
557                     } *__u = (void *) __dest;                                 \
558                     switch (srclen)                                           \
559                       {                                                       \
560                       case 1:                                                 \
561                         __u->__uc = '\0';                                     \
562                         break;                                                \
563                       case 2:                                                 \
564                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
565                         break;                                                \
566                       case 3:                                                 \
567                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
568                         __u = __extension__ ((void *) __u + 2);               \
569                         __u->__uc = '\0';                                     \
570                         break;                                                \
571                       case 4:                                                 \
572                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
573                         break;                                                \
574                       case 5:                                                 \
575                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
576                         __u = __extension__ ((void *) __u + 4);               \
577                         __u->__uc = '\0';                                     \
578                         break;                                                \
579                       case 6:                                                 \
580                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
581                         __u = __extension__ ((void *) __u + 4);               \
582                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
583                         break;                                                \
584                       case 7:                                                 \
585                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
586                         __u = __extension__ ((void *) __u + 4);               \
587                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
588                         __u = __extension__ ((void *) __u + 2);               \
589                         __u->__uc = '\0';                                     \
590                         break;                                                \
591                       case 8:                                                 \
592                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
593                         __u = __extension__ ((void *) __u + 4);               \
594                         __u->__ui = __STRING_SMALL_GET32 (src, 4);            \
595                         break;                                                \
596                       }                                                       \
597                     (char *) __dest; }))
598
599 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
600
601 __STRING_INLINE char *
602 __strcpy_g (char *__dest, __const char *__src)
603 {
604   register char *__tmp = __dest;
605   register char __dummy;
606   __asm__ __volatile__
607     (
608      "1:\n\t"
609      "movb      (%0),%b2\n\t"
610      "leal      1(%0),%0\n\t"
611      "movb      %b2,(%1)\n\t"
612      "leal      1(%1),%1\n\t"
613      "testb     %b2,%b2\n\t"
614      "jne       1b"
615      : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
616      : "0" (__src), "1" (__tmp)
617      : "memory", "cc");
618   return __dest;
619 }
620
621
622 #ifdef __USE_GNU
623 # define _HAVE_STRING_ARCH_stpcpy 1
624 /* Copy SRC to DEST.  */
625 # define __stpcpy(dest, src) \
626   (__extension__ (__builtin_constant_p (src)                                  \
627                   ? (strlen (src) + 1 <= 8                                    \
628                      ? __stpcpy_small (dest, src, strlen (src) + 1)           \
629                      : __stpcpy_c (dest, src, strlen (src) + 1))              \
630                   : __stpcpy_g (dest, src)))
631 # define __stpcpy_c(dest, src, srclen) \
632   ((srclen) % 4 == 0                                                          \
633    ? __mempcpy_by4 (dest, src, srclen) - 1                                    \
634    : ((srclen) % 2 == 0                                                       \
635       ? __mempcpy_by2 (dest, src, srclen) - 1                                 \
636       : __mempcpy_byn (dest, src, srclen) - 1))
637
638 /* In glibc itself we use this symbol for namespace reasons.  */
639 # define stpcpy(dest, src) __stpcpy (dest, src)
640
641 # define __stpcpy_small(dest, src, srclen) \
642   (__extension__ ({ union {                                                   \
643                       unsigned int __ui;                                      \
644                       unsigned short int __usi;                               \
645                       unsigned char __uc;                                     \
646                       char __c;                                               \
647                     } *__u = (void *) (dest);                                 \
648                     switch (srclen)                                           \
649                       {                                                       \
650                       case 1:                                                 \
651                         __u->__uc = '\0';                                     \
652                         break;                                                \
653                       case 2:                                                 \
654                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
655                         __u = __extension__ ((void *) __u + 1);               \
656                         break;                                                \
657                       case 3:                                                 \
658                         __u->__usi = __STRING_SMALL_GET16 (src, 0);           \
659                         __u = __extension__ ((void *) __u + 2);               \
660                         __u->__uc = '\0';                                     \
661                         break;                                                \
662                       case 4:                                                 \
663                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
664                         __u = __extension__ ((void *) __u + 3);               \
665                         break;                                                \
666                       case 5:                                                 \
667                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
668                         __u = __extension__ ((void *) __u + 4);               \
669                         __u->__uc = '\0';                                     \
670                         break;                                                \
671                       case 6:                                                 \
672                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
673                         __u = __extension__ ((void *) __u + 4);               \
674                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
675                         __u = __extension__ ((void *) __u + 1);               \
676                         break;                                                \
677                       case 7:                                                 \
678                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
679                         __u = __extension__ ((void *) __u + 4);               \
680                         __u->__usi = __STRING_SMALL_GET16 (src, 4);           \
681                         __u = __extension__ ((void *) __u + 2);               \
682                         __u->__uc = '\0';                                     \
683                         break;                                                \
684                       case 8:                                                 \
685                         __u->__ui = __STRING_SMALL_GET32 (src, 0);            \
686                         __u = __extension__ ((void *) __u + 4);               \
687                         __u->__ui = __STRING_SMALL_GET32 (src, 4);            \
688                         __u = __extension__ ((void *) __u + 3);               \
689                         break;                                                \
690                       }                                                       \
691                     (char *) __u; }))
692
693 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
694                                      size_t __srclen);
695
696 __STRING_INLINE char *
697 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
698 {
699   register char *__tmp = __dest;
700   register unsigned long int __d0, __d1;
701   __asm__ __volatile__
702     ("1:\n\t"
703      "movl      (%2),%0\n\t"
704      "leal      4(%2),%2\n\t"
705      "movl      %0,(%1)\n\t"
706      "leal      4(%1),%1\n\t"
707      "decl      %3\n\t"
708      "jnz       1b"
709      : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
710      : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
711      : "memory", "cc");
712   return __tmp;
713 }
714
715 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
716                                      size_t __srclen);
717
718 __STRING_INLINE char *
719 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
720 {
721   register char *__tmp = __dest;
722   register unsigned long int __d0, __d1;
723   __asm__ __volatile__
724     ("shrl      $1,%3\n\t"
725      "jz        2f\n"                 /* only a word */
726      "1:\n\t"
727      "movl      (%2),%0\n\t"
728      "leal      4(%2),%2\n\t"
729      "movl      %0,(%1)\n\t"
730      "leal      4(%1),%1\n\t"
731      "decl      %3\n\t"
732      "jnz       1b\n"
733      "2:\n\t"
734      "movw      (%2),%w0\n\t"
735      "movw      %w0,(%1)"
736      : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
737      : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
738      : "memory", "cc");
739   return __tmp + 2;
740 }
741
742 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
743                                      size_t __srclen);
744
745 __STRING_INLINE char *
746 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
747 {
748   register unsigned long __d0, __d1;
749   register char *__tmp = __dest;
750   __asm__ __volatile__
751     ("cld\n\t"
752      "shrl      $1,%%ecx\n\t"
753      "jnc       1f\n\t"
754      "movsb\n"
755      "1:\n\t"
756      "shrl      $1,%%ecx\n\t"
757      "jnc       2f\n\t"
758      "movsw\n"
759      "2:\n\t"
760      "rep; movsl"
761      : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
762      : "0" (__tmp), "1" (__srclen), "2" (__src)
763      : "memory", "cc");
764   return __tmp;
765 }
766
767 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
768
769 __STRING_INLINE char *
770 __stpcpy_g (char *__dest, __const char *__src)
771 {
772   register char *__tmp = __dest;
773   register char __dummy;
774   __asm__ __volatile__
775     (
776      "1:\n\t"
777      "movb      (%0),%b2\n\t"
778      "leal      1(%0),%0\n\t"
779      "movb      %b2,(%1)\n\t"
780      "leal      1(%1),%1\n\t"
781      "testb     %b2,%b2\n\t"
782      "jne       1b"
783      : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
784      : "0" (__src), "1" (__tmp)
785      : "memory", "cc");
786   return __tmp - 1;
787 }
788 #endif
789
790
791 /* Copy no more than N characters of SRC to DEST.  */
792 #define _HAVE_STRING_ARCH_strncpy 1
793 #define strncpy(dest, src, n) \
794   (__extension__ (__builtin_constant_p (src)                                  \
795                   ? ((strlen (src) + 1 >= ((size_t) (n))                      \
796                       ? (char *) memcpy ((char *) dest,                       \
797                                          (__const char *) src, n)             \
798                       : __strncpy_cg (dest, src, strlen (src) + 1, n)))       \
799                   : __strncpy_gg (dest, src, n)))
800 #define __strncpy_cg(dest, src, srclen, n) \
801   (((srclen) % 4 == 0)                                                        \
802    ? __strncpy_by4 (dest, src, srclen, n)                                     \
803    : (((srclen) % 2 == 0)                                                     \
804       ? __strncpy_by2 (dest, src, srclen, n)                                  \
805       : __strncpy_byn (dest, src, srclen, n)))
806
807 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
808                                      size_t __srclen, size_t __n);
809
810 __STRING_INLINE char *
811 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
812 {
813   register char *__tmp = __dest;
814   register int __dummy1, __dummy2;
815   __asm__ __volatile__
816     ("1:\n\t"
817      "movl      (%2),%0\n\t"
818      "leal      4(%2),%2\n\t"
819      "movl      %0,(%1)\n\t"
820      "leal      4(%1),%1\n\t"
821      "decl      %3\n\t"
822      "jnz       1b"
823      : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
824      : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
825      : "memory", "cc");
826   (void) memset (__tmp, '\0', __n - __srclen);
827   return __dest;
828 }
829
830 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
831                                      size_t __srclen, size_t __n);
832
833 __STRING_INLINE char *
834 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
835 {
836   register char *__tmp = __dest;
837   register int __dummy1, __dummy2;
838   __asm__ __volatile__
839     ("shrl      $1,%3\n\t"
840      "jz        2f\n"                 /* only a word */
841      "1:\n\t"
842      "movl      (%2),%0\n\t"
843      "leal      4(%2),%2\n\t"
844      "movl      %0,(%1)\n\t"
845      "leal      4(%1),%1\n\t"
846      "decl      %3\n\t"
847      "jnz       1b\n"
848      "2:\n\t"
849      "movw      (%2),%w0\n\t"
850      "movw      %w0,(%1)\n\t"
851      : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
852      : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
853      : "memory", "cc");
854   (void) memset (__tmp + 2, '\0', __n - __srclen);
855   return __dest;
856 }
857
858 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
859                                      size_t __srclen, size_t __n);
860
861 __STRING_INLINE char *
862 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
863 {
864   register unsigned long int __d0, __d1;
865   register char *__tmp = __dest;
866   __asm__ __volatile__
867     ("cld\n\t"
868      "shrl      $1,%1\n\t"
869      "jnc       1f\n\t"
870      "movsb\n"
871      "1:\n\t"
872      "shrl      $1,%1\n\t"
873      "jnc       2f\n\t"
874      "movsw\n"
875      "2:\n\t"
876      "rep; movsl"
877      : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
878      : "1" (__srclen), "0" (__tmp),"2" (__src)
879      : "memory", "cc");
880   (void) memset (__tmp, '\0', __n - __srclen);
881   return __dest;
882 }
883
884 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
885                                     size_t __n);
886
887 __STRING_INLINE char *
888 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
889 {
890   register char *__tmp = __dest;
891   register char __dummy;
892   if (__n > 0)
893     __asm__ __volatile__
894       ("1:\n\t"
895        "movb    (%0),%2\n\t"
896        "incl    %0\n\t"
897        "movb    %2,(%1)\n\t"
898        "incl    %1\n\t"
899        "decl    %3\n\t"
900        "je      3f\n\t"
901        "testb   %2,%2\n\t"
902        "jne     1b\n\t"
903        "2:\n\t"
904        "movb    %2,(%1)\n\t"
905        "incl    %1\n\t"
906        "decl    %3\n\t"
907        "jne     2b\n\t"
908        "3:"
909        : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
910        : "0" (__src), "1" (__tmp), "3" (__n)
911        : "memory", "cc");
912
913   return __dest;
914 }
915
916
917 /* Append SRC onto DEST.  */
918 #define _HAVE_STRING_ARCH_strcat 1
919 #define strcat(dest, src) \
920   (__extension__ (__builtin_constant_p (src)                                  \
921                   ? __strcat_c (dest, src, strlen (src) + 1)                  \
922                   : __strcat_g (dest, src)))
923
924 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
925                                   size_t __srclen);
926
927 __STRING_INLINE char *
928 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
929 {
930 #ifdef __i686__
931   register unsigned long int __d0;
932   register char *__tmp;
933   __asm__ __volatile__
934     ("repne; scasb"
935      : "=D" (__tmp), "=&c" (__d0)
936      : "0" (__dest), "1" (0xffffffff), "a" (0)
937      : "cc");
938   --__tmp;
939 #else
940   register char *__tmp = __dest - 1;
941   __asm__ __volatile__
942     ("1:\n\t"
943      "incl      %0\n\t"
944      "cmpb      $0,(%0)\n\t"
945      "jne       1b\n"
946      : "=r" (__tmp)
947      : "0" (__tmp)
948      : "cc");
949 #endif
950   (void) memcpy (__tmp, __src, __srclen);
951   return __dest;
952 }
953
954 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
955
956 __STRING_INLINE char *
957 __strcat_g (char *__dest, __const char *__src)
958 {
959   register char *__tmp = __dest - 1;
960   register char __dummy;
961   __asm__ __volatile__
962     ("1:\n\t"
963      "incl      %1\n\t"
964      "cmpb      $0,(%1)\n\t"
965      "jne       1b\n"
966      "2:\n\t"
967      "movb      (%2),%b0\n\t"
968      "incl      %2\n\t"
969      "movb      %b0,(%1)\n\t"
970      "incl      %1\n\t"
971      "testb     %b0,%b0\n\t"
972      "jne       2b\n"
973      : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
974      : "1"  (__tmp), "2"  (__src)
975      : "memory", "cc");
976   return __dest;
977 }
978
979
980 /* Append no more than N characters from SRC onto DEST.  */
981 #define _HAVE_STRING_ARCH_strncat 1
982 #define strncat(dest, src, n) \
983   (__extension__ ({ char *__dest = (dest);                                    \
984                     __builtin_constant_p (src) && __builtin_constant_p (n)    \
985                     ? (strlen (src) < ((size_t) (n))                          \
986                        ? strcat (__dest, src)                                 \
987                        : (memcpy (strchr (__dest, '\0'),                      \
988                                   (__const char *) src, n), __dest))          \
989                     : __strncat_g (__dest, src, n); }))
990
991 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
992                                    size_t __n);
993
994 __STRING_INLINE char *
995 __strncat_g (char *__dest, __const char __src[], size_t __n)
996 {
997   register char *__tmp = __dest;
998   register char __dummy;
999 #ifdef __i686__
1000   __asm__ __volatile__
1001     ("repne; scasb\n"
1002      "decl %1\n\t"
1003      "1:\n\t"
1004      "decl      %3\n\t"
1005      "js        2f\n\t"
1006      "movb      (%2),%b0\n\t"
1007      "movsb\n\t"
1008      "testb     %b0,%b0\n\t"
1009      "jne       1b\n\t"
1010      "decl      %1\n"
1011      "2:\n\t"
1012      "movb      $0,(%1)"
1013      : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
1014      : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
1015      : "memory", "cc");
1016 #else
1017   --__tmp;
1018   __asm__ __volatile__
1019     ("1:\n\t"
1020      "cmpb      $0,1(%1)\n\t"
1021      "leal      1(%1),%1\n\t"
1022      "jne       1b\n"
1023      "2:\n\t"
1024      "decl      %3\n\t"
1025      "js        3f\n\t"
1026      "movb      (%2),%b0\n\t"
1027      "leal      1(%2),%2\n\t"
1028      "movb      %b0,(%1)\n\t"
1029      "leal      1(%1),%1\n\t"
1030      "testb     %b0,%b0\n\t"
1031      "jne       2b\n\t"
1032      "decl      %1\n"
1033      "3:\n\t"
1034      "movb      $0,(%1)"
1035      : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1036      : "1" (__tmp), "2" (__src), "3" (__n)
1037      : "memory", "cc");
1038 #endif
1039   return __dest;
1040 }
1041
1042
1043 /* Compare S1 and S2.  */
1044 #define _HAVE_STRING_ARCH_strcmp 1
1045 #define strcmp(s1, s2) \
1046   (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2)      \
1047                   && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4)              \
1048                   && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4)              \
1049                   ? memcmp ((__const char *) s1, (__const char *) s2,         \
1050                             (strlen (s1) < strlen (s2)                        \
1051                              ? strlen (s1) : strlen (s2)) + 1)                \
1052                   : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1       \
1053                      && sizeof ((s2)[0]) == 1 && strlen (s1) < 4              \
1054                      ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1    \
1055                         ? __strcmp_cc (s1, s2, strlen (s1))                   \
1056                         : __strcmp_cg (s1, s2, strlen (s1)))                  \
1057                      : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1    \
1058                         && sizeof ((s2)[0]) == 1 && strlen (s2) < 4           \
1059                         ? (__builtin_constant_p (s1)                          \
1060                            ? __strcmp_cc (s1, s2, strlen (s2))                \
1061                            : __strcmp_gc (s1, s2, strlen (s2)))               \
1062                         : __strcmp_gg (s1, s2)))))
1063
1064 #define __strcmp_cc(s1, s2, l) \
1065   (__extension__ ({ register int __result = ((unsigned char) (s1)[0]          \
1066                                              - (unsigned char) (s2)[0]);      \
1067                     if (l > 0 && __result == 0)                               \
1068                       {                                                       \
1069                         __result = ((unsigned char) (s1)[1]                   \
1070                                     - (unsigned char) (s2)[1]);               \
1071                         if (l > 1 && __result == 0)                           \
1072                           {                                                   \
1073                             __result = ((unsigned char) (s1)[2]               \
1074                                         - (unsigned char) (s2)[2]);           \
1075                             if (l > 2 && __result == 0)                       \
1076                               __result = ((unsigned char) (s1)[3]             \
1077                                           - (unsigned char) (s2)[3]);         \
1078                           }                                                   \
1079                       }                                                       \
1080                     __result; }))
1081
1082 #define __strcmp_cg(s1, s2, l1) \
1083   (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2);     \
1084                     register int __result = (unsigned char) (s1)[0] - __s2[0];\
1085                     if (l1 > 0 && __result == 0)                              \
1086                       {                                                       \
1087                         __result = (unsigned char) (s1)[1] - __s2[1];         \
1088                         if (l1 > 1 && __result == 0)                          \
1089                           {                                                   \
1090                             __result = (unsigned char) (s1)[2] - __s2[2];     \
1091                             if (l1 > 2 && __result == 0)                      \
1092                               __result = (unsigned char) (s1)[3] - __s2[3];   \
1093                           }                                                   \
1094                       }                                                       \
1095                     __result; }))
1096
1097 #define __strcmp_gc(s1, s2, l2) \
1098   (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1);     \
1099                     register int __result = __s1[0] - (unsigned char) (s2)[0];\
1100                     if (l2 > 0 && __result == 0)                              \
1101                       {                                                       \
1102                         __result = __s1[1] - (unsigned char) (s2)[1];         \
1103                         if (l2 > 1 && __result == 0)                          \
1104                           {                                                   \
1105                             __result = __s1[2] - (unsigned char) (s2)[2];     \
1106                             if (l2 > 2 && __result == 0)                      \
1107                               __result = __s1[3] - (unsigned char) (s2)[3];   \
1108                           }                                                   \
1109                       }                                                       \
1110                     __result; }))
1111
1112 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
1113
1114 __STRING_INLINE int
1115 __strcmp_gg (__const char *__s1, __const char *__s2)
1116 {
1117   register int __res;
1118   __asm__ __volatile__
1119     ("1:\n\t"
1120      "movb      (%1),%b0\n\t"
1121      "leal      1(%1),%1\n\t"
1122      "cmpb      %b0,(%2)\n\t"
1123      "jne       2f\n\t"
1124      "leal      1(%2),%2\n\t"
1125      "testb     %b0,%b0\n\t"
1126      "jne       1b\n\t"
1127      "xorl      %0,%0\n\t"
1128      "jmp       3f\n"
1129      "2:\n\t"
1130      "movl      $1,%0\n\t"
1131      "jb        3f\n\t"
1132      "negl      %0\n"
1133      "3:"
1134      : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1135      : "1" (__s1), "2" (__s2)
1136      : "cc");
1137   return __res;
1138 }
1139
1140
1141 /* Compare N characters of S1 and S2.  */
1142 #define _HAVE_STRING_ARCH_strncmp 1
1143 #define strncmp(s1, s2, n) \
1144   (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n))   \
1145                   ? strcmp (s1, s2)                                           \
1146                   : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1147                      ? strcmp (s1, s2)                                        \
1148                      : __strncmp_g (s1, s2, n))))
1149
1150 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1151                                  size_t __n);
1152
1153 __STRING_INLINE int
1154 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1155 {
1156   register int __res;
1157   __asm__ __volatile__
1158     ("1:\n\t"
1159      "decl      %3\n\t"
1160      "js        2f\n\t"
1161      "movb      (%1),%b0\n\t"
1162      "incl      %1\n\t"
1163      "cmpb      %b0,(%2)\n\t"
1164      "jne       3f\n\t"
1165      "incl      %2\n\t"
1166      "testb     %b0,%b0\n\t"
1167      "jne       1b\n"
1168      "2:\n\t"
1169      "xorl      %0,%0\n\t"
1170      "jmp       4f\n"
1171      "3:\n\t"
1172      "movl      $1,%0\n\t"
1173      "jb        4f\n\t"
1174      "negl      %0\n"
1175      "4:"
1176      : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1177      : "1"  (__s1), "2"  (__s2),  "3" (__n)
1178      : "cc");
1179   return __res;
1180 }
1181
1182
1183 /* Find the first occurrence of C in S.  */
1184 #define _HAVE_STRING_ARCH_strchr 1
1185 #define strchr(s, c) \
1186   (__extension__ (__builtin_constant_p (c)                                    \
1187                   ? ((c) == '\0'                                              \
1188                      ? (char *) __rawmemchr (s, c)                            \
1189                      : __strchr_c (s, ((c) & 0xff) << 8))                     \
1190                   : __strchr_g (s, c)))
1191
1192 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1193
1194 __STRING_INLINE char *
1195 __strchr_c (__const char *__s, int __c)
1196 {
1197   register unsigned long int __d0;
1198   register char *__res;
1199   __asm__ __volatile__
1200     ("1:\n\t"
1201      "movb      (%0),%%al\n\t"
1202      "cmpb      %%ah,%%al\n\t"
1203      "je        2f\n\t"
1204      "leal      1(%0),%0\n\t"
1205      "testb     %%al,%%al\n\t"
1206      "jne       1b\n\t"
1207      "xorl      %0,%0\n"
1208      "2:"
1209      : "=r" (__res), "=&a" (__d0)
1210      : "0" (__s), "1" (__c)
1211      : "cc");
1212   return __res;
1213 }
1214
1215 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1216
1217 __STRING_INLINE char *
1218 __strchr_g (__const char *__s, int __c)
1219 {
1220   register unsigned long int __d0;
1221   register char *__res;
1222   __asm__ __volatile__
1223     ("movb      %%al,%%ah\n"
1224      "1:\n\t"
1225      "movb      (%0),%%al\n\t"
1226      "cmpb      %%ah,%%al\n\t"
1227      "je        2f\n\t"
1228      "leal      1(%0),%0\n\t"
1229      "testb     %%al,%%al\n\t"
1230      "jne       1b\n\t"
1231      "xorl      %0,%0\n"
1232      "2:"
1233      : "=r" (__res), "=&a" (__d0)
1234      : "0" (__s), "1" (__c)
1235      : "cc");
1236   return __res;
1237 }
1238
1239
1240 /* Find the first occurrence of C in S or the final NUL byte.  */
1241 #define _HAVE_STRING_ARCH_strchrnul 1
1242 #define __strchrnul(s, c) \
1243   (__extension__ (__builtin_constant_p (c)                                    \
1244                   ? ((c) == '\0'                                              \
1245                      ? (char *) __rawmemchr (s, c)                            \
1246                      : __strchrnul_c (s, ((c) & 0xff) << 8))                  \
1247                   : __strchrnul_g (s, c)))
1248
1249 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
1250
1251 __STRING_INLINE char *
1252 __strchrnul_c (__const char *__s, int __c)
1253 {
1254   register unsigned long int __d0;
1255   register char *__res;
1256   __asm__ __volatile__
1257     ("1:\n\t"
1258      "movb      (%0),%%al\n\t"
1259      "cmpb      %%ah,%%al\n\t"
1260      "je        2f\n\t"
1261      "leal      1(%0),%0\n\t"
1262      "testb     %%al,%%al\n\t"
1263      "jne       1b\n\t"
1264      "decl      %0\n"
1265      "2:"
1266      : "=r" (__res), "=&a" (__d0)
1267      : "0" (__s), "1" (__c)
1268      : "cc");
1269   return __res;
1270 }
1271
1272 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
1273
1274 __STRING_INLINE char *
1275 __strchrnul_g (__const char *__s, int __c)
1276 {
1277   register unsigned long int __d0;
1278   register char *__res;
1279   __asm__ __volatile__
1280     ("movb      %%al,%%ah\n"
1281      "1:\n\t"
1282      "movb      (%0),%%al\n\t"
1283      "cmpb      %%ah,%%al\n\t"
1284      "je        2f\n\t"
1285      "leal      1(%0),%0\n\t"
1286      "testb     %%al,%%al\n\t"
1287      "jne       1b\n\t"
1288      "decl      %0\n"
1289      "2:"
1290      : "=r" (__res), "=&a" (__d0)
1291      : "0" (__s), "1" (__c)
1292      : "cc");
1293   return __res;
1294 }
1295 #ifdef __USE_GNU
1296 # define strchrnul(s, c) __strchrnul (s, c)
1297 #endif
1298
1299
1300 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1301 /* Find the first occurrence of C in S.  This is the BSD name.  */
1302 # define _HAVE_STRING_ARCH_index 1
1303 # define index(s, c) \
1304   (__extension__ (__builtin_constant_p (c)                                    \
1305                   ? __strchr_c (s, ((c) & 0xff) << 8)                         \
1306                   : __strchr_g (s, c)))
1307 #endif
1308
1309
1310 /* Find the last occurrence of C in S.  */
1311 #define _HAVE_STRING_ARCH_strrchr 1
1312 #define strrchr(s, c) \
1313   (__extension__ (__builtin_constant_p (c)                                    \
1314                   ? __strrchr_c (s, ((c) & 0xff) << 8)                        \
1315                   : __strrchr_g (s, c)))
1316
1317 #ifdef __i686__
1318 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1319
1320 __STRING_INLINE char *
1321 __strrchr_c (__const char *__s, int __c)
1322 {
1323   register unsigned long int __d0, __d1;
1324   register char *__res;
1325   __asm__ __volatile__
1326     ("cld\n"
1327      "1:\n\t"
1328      "lodsb\n\t"
1329      "cmpb      %h2,%b2\n\t"
1330      "cmove     %1,%0\n\t"
1331      "testb     %b2,%b2\n\t"
1332      "jne 1b"
1333      : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1334      : "0" (1), "1" (__s), "2" (__c)
1335      : "cc");
1336   return __res - 1;
1337 }
1338
1339 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1340
1341 __STRING_INLINE char *
1342 __strrchr_g (__const char *__s, int __c)
1343 {
1344   register unsigned long int __d0, __d1;
1345   register char *__res;
1346   __asm__ __volatile__
1347     ("movb      %b2,%h2\n"
1348      "cld\n\t"
1349      "1:\n\t"
1350      "lodsb\n\t"
1351      "cmpb      %h2,%b2\n\t"
1352      "cmove     %1,%0\n\t"
1353      "testb     %b2,%b2\n\t"
1354      "jne 1b"
1355      : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1356      : "0" (1), "1" (__s), "2" (__c)
1357      : "cc");
1358   return __res - 1;
1359 }
1360 #else
1361 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1362
1363 __STRING_INLINE char *
1364 __strrchr_c (__const char *__s, int __c)
1365 {
1366   register unsigned long int __d0, __d1;
1367   register char *__res;
1368   __asm__ __volatile__
1369     ("cld\n"
1370      "1:\n\t"
1371      "lodsb\n\t"
1372      "cmpb      %%ah,%%al\n\t"
1373      "jne       2f\n\t"
1374      "leal      -1(%%esi),%0\n"
1375      "2:\n\t"
1376      "testb     %%al,%%al\n\t"
1377      "jne 1b"
1378      : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1379      : "0" (0), "1" (__s), "2" (__c)
1380      : "cc");
1381   return __res;
1382 }
1383
1384 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1385
1386 __STRING_INLINE char *
1387 __strrchr_g (__const char *__s, int __c)
1388 {
1389   register unsigned long int __d0, __d1;
1390   register char *__res;
1391   __asm__ __volatile__
1392     ("movb      %%al,%%ah\n"
1393      "cld\n\t"
1394      "1:\n\t"
1395      "lodsb\n\t"
1396      "cmpb      %%ah,%%al\n\t"
1397      "jne       2f\n\t"
1398      "leal      -1(%%esi),%0\n"
1399      "2:\n\t"
1400      "testb     %%al,%%al\n\t"
1401      "jne 1b"
1402      : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1403      : "0" (0), "1" (__s), "2" (__c)
1404      : "cc");
1405   return __res;
1406 }
1407 #endif
1408
1409
1410 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1411 /* Find the last occurrence of C in S.  This is the BSD name.  */
1412 # define _HAVE_STRING_ARCH_rindex 1
1413 # define rindex(s, c) \
1414   (__extension__ (__builtin_constant_p (c)                                    \
1415                   ? __strrchr_c (s, ((c) & 0xff) << 8)                        \
1416                   : __strrchr_g (s, c)))
1417 #endif
1418
1419
1420 /* Return the length of the initial segment of S which
1421    consists entirely of characters not in REJECT.  */
1422 #define _HAVE_STRING_ARCH_strcspn 1
1423 #define strcspn(s, reject) \
1424   (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1  \
1425                   ? ((reject)[0] == '\0'                                      \
1426                      ? strlen (s)                                             \
1427                      : ((reject)[1] == '\0'                                   \
1428                         ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00))     \
1429                         : __strcspn_cg (s, reject, strlen (reject))))         \
1430                   : __strcspn_g (s, reject)))
1431
1432 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1433
1434 __STRING_INLINE size_t
1435 __strcspn_c1 (__const char *__s, int __reject)
1436 {
1437   register unsigned long int __d0;
1438   register char *__res;
1439   __asm__ __volatile__
1440     ("1:\n\t"
1441      "movb      (%0),%%al\n\t"
1442      "leal      1(%0),%0\n\t"
1443      "cmpb      %%ah,%%al\n\t"
1444      "je        2f\n\t"
1445      "testb     %%al,%%al\n\t"
1446      "jne       1b\n"
1447      "2:"
1448      : "=r" (__res), "=&a" (__d0)
1449      : "0" (__s), "1" (__reject)
1450      : "cc");
1451   return (__res - 1) - __s;
1452 }
1453
1454 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1455                                     size_t __reject_len);
1456
1457 __STRING_INLINE size_t
1458 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1459 {
1460   register unsigned long int __d0, __d1, __d2;
1461   register __const char *__res;
1462   __asm__ __volatile__
1463     ("cld\n"
1464      "1:\n\t"
1465      "lodsb\n\t"
1466      "testb     %%al,%%al\n\t"
1467      "je        2f\n\t"
1468      "movl      %5,%%edi\n\t"
1469      "movl      %6,%%ecx\n\t"
1470      "repne; scasb\n\t"
1471      "jne       1b\n"
1472      "2:"
1473      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1474      : "0" (__s), "d" (__reject), "g" (__reject_len)
1475      : "cc");
1476   return (__res - 1) - __s;
1477 }
1478
1479 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1480 #ifdef __PIC__
1481
1482 __STRING_INLINE size_t
1483 __strcspn_g (__const char *__s, __const char *__reject)
1484 {
1485   register unsigned long int __d0, __d1, __d2;
1486   register __const char *__res;
1487   __asm__ __volatile__
1488     ("pushl     %%ebx\n\t"
1489      "movl      %4,%%edi\n\t"
1490      "cld\n\t"
1491      "repne; scasb\n\t"
1492      "notl      %%ecx\n\t"
1493      "leal      -1(%%ecx),%%ebx\n"
1494      "1:\n\t"
1495      "lodsb\n\t"
1496      "testb     %%al,%%al\n\t"
1497      "je        2f\n\t"
1498      "movl      %4,%%edi\n\t"
1499      "movl      %%ebx,%%ecx\n\t"
1500      "repne; scasb\n\t"
1501      "jne       1b\n"
1502      "2:\n\t"
1503      "popl      %%ebx"
1504      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1505      : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1506      : "cc");
1507   return (__res - 1) - __s;
1508 }
1509 #else
1510 __STRING_INLINE size_t
1511 __strcspn_g (__const char *__s, __const char *__reject)
1512 {
1513   register unsigned long int __d0, __d1, __d2, __d3;
1514   register __const char *__res;
1515   __asm__ __volatile__
1516     ("cld\n\t"
1517      "repne; scasb\n\t"
1518      "notl      %%ecx\n\t"
1519      "leal      -1(%%ecx),%%edx\n"
1520      "1:\n\t"
1521      "lodsb\n\t"
1522      "testb     %%al,%%al\n\t"
1523      "je        2f\n\t"
1524      "movl      %%ebx,%%edi\n\t"
1525      "movl      %%edx,%%ecx\n\t"
1526      "repne; scasb\n\t"
1527      "jne       1b\n"
1528      "2:"
1529      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1530      : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1531      : "cc");
1532   return (__res - 1) - __s;
1533 }
1534 #endif
1535
1536
1537 /* Return the length of the initial segment of S which
1538    consists entirely of characters in ACCEPT.  */
1539 #define _HAVE_STRING_ARCH_strspn 1
1540 #define strspn(s, accept) \
1541   (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
1542                   ? ((accept)[0] == '\0'                                      \
1543                      ? 0                                                      \
1544                      : ((accept)[1] == '\0'                                   \
1545                         ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00))     \
1546                         : __strspn_cg (s, accept, strlen (accept))))          \
1547                   : __strspn_g (s, accept)))
1548
1549 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1550
1551 __STRING_INLINE size_t
1552 __strspn_c1 (__const char *__s, int __accept)
1553 {
1554   register unsigned long int __d0;
1555   register char *__res;
1556   /* Please note that __accept never can be '\0'.  */
1557   __asm__ __volatile__
1558     ("1:\n\t"
1559      "movb      (%0),%b1\n\t"
1560      "leal      1(%0),%0\n\t"
1561      "cmpb      %h1,%b1\n\t"
1562      "je        1b"
1563      : "=r" (__res), "=&q" (__d0)
1564      : "0" (__s), "1" (__accept)
1565      : "cc");
1566   return (__res - 1) - __s;
1567 }
1568
1569 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1570                                     size_t __accept_len);
1571
1572 __STRING_INLINE size_t
1573 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1574 {
1575   register unsigned long int __d0, __d1, __d2;
1576   register __const char *__res;
1577   __asm__ __volatile__
1578     ("cld\n"
1579      "1:\n\t"
1580      "lodsb\n\t"
1581      "testb     %%al,%%al\n\t"
1582      "je        2f\n\t"
1583      "movl      %1,%%edi\n\t"
1584      "movl      %6,%%ecx\n\t"
1585      "repne; scasb\n\t"
1586      "je        1b\n"
1587      "2:"
1588      : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1589      : "0" (__s), "1" (__accept), "g" (__accept_len)
1590      : "cc");
1591   return (__res - 1) - __s;
1592 }
1593
1594 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1595 #ifdef __PIC__
1596
1597 __STRING_INLINE size_t
1598 __strspn_g (__const char *__s, __const char *__accept)
1599 {
1600   register unsigned long int __d0, __d1, __d2;
1601   register __const char *__res;
1602   __asm__ __volatile__
1603     ("pushl     %%ebx\n\t"
1604      "cld\n\t"
1605      "repne; scasb\n\t"
1606      "notl      %%ecx\n\t"
1607      "leal      -1(%%ecx),%%ebx\n"
1608      "1:\n\t"
1609      "lodsb\n\t"
1610      "testb     %%al,%%al\n\t"
1611      "je        2f\n\t"
1612      "movl      %%edx,%%edi\n\t"
1613      "movl      %%ebx,%%ecx\n\t"
1614      "repne; scasb\n\t"
1615      "je        1b\n"
1616      "2:\n\t"
1617      "popl      %%ebx"
1618      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1619      : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1620      : "cc");
1621   return (__res - 1) - __s;
1622 }
1623 #else
1624 __STRING_INLINE size_t
1625 __strspn_g (__const char *__s, __const char *__accept)
1626 {
1627   register unsigned long int __d0, __d1, __d2, __d3;
1628   register __const char *__res;
1629   __asm__ __volatile__
1630     ("cld\n\t"
1631      "repne; scasb\n\t"
1632      "notl      %%ecx\n\t"
1633      "leal      -1(%%ecx),%%edx\n"
1634      "1:\n\t"
1635      "lodsb\n\t"
1636      "testb     %%al,%%al\n\t"
1637      "je        2f\n\t"
1638      "movl      %%ebx,%%edi\n\t"
1639      "movl      %%edx,%%ecx\n\t"
1640      "repne; scasb\n\t"
1641      "je        1b\n"
1642      "2:"
1643      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1644      : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1645      : "cc");
1646   return (__res - 1) - __s;
1647 }
1648 #endif
1649
1650
1651 /* Find the first occurrence in S of any character in ACCEPT.  */
1652 #define _HAVE_STRING_ARCH_strpbrk 1
1653 #define strpbrk(s, accept) \
1654   (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1  \
1655                   ? ((accept)[0] == '\0'                                      \
1656                      ? NULL                                                   \
1657                      : ((accept)[1] == '\0'                                   \
1658                         ? strchr (s, (accept)[0])                             \
1659                         : __strpbrk_cg (s, accept, strlen (accept))))         \
1660                   : __strpbrk_g (s, accept)))
1661
1662 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1663                                     size_t __accept_len);
1664
1665 __STRING_INLINE char *
1666 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1667 {
1668   register unsigned long int __d0, __d1, __d2;
1669   register char *__res;
1670   __asm__ __volatile__
1671     ("cld\n"
1672      "1:\n\t"
1673      "lodsb\n\t"
1674      "testb     %%al,%%al\n\t"
1675      "je        2f\n\t"
1676      "movl      %5,%%edi\n\t"
1677      "movl      %6,%%ecx\n\t"
1678      "repne; scasb\n\t"
1679      "jne       1b\n\t"
1680      "decl      %0\n\t"
1681      "jmp       3f\n"
1682      "2:\n\t"
1683      "xorl      %0,%0\n"
1684      "3:"
1685      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1686      : "0" (__s), "d" (__accept), "g" (__accept_len)
1687      : "cc");
1688   return __res;
1689 }
1690
1691 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1692 #ifdef __PIC__
1693
1694 __STRING_INLINE char *
1695 __strpbrk_g (__const char *__s, __const char *__accept)
1696 {
1697   register unsigned long int __d0, __d1, __d2;
1698   register char *__res;
1699   __asm__ __volatile__
1700     ("pushl     %%ebx\n\t"
1701      "movl      %%edx,%%edi\n\t"
1702      "cld\n\t"
1703      "repne; scasb\n\t"
1704      "notl      %%ecx\n\t"
1705      "leal      -1(%%ecx),%%ebx\n"
1706      "1:\n\t"
1707      "lodsb\n\t"
1708      "testb     %%al,%%al\n\t"
1709      "je        2f\n\t"
1710      "movl      %%edx,%%edi\n\t"
1711      "movl      %%ebx,%%ecx\n\t"
1712      "repne; scasb\n\t"
1713      "jne       1b\n\t"
1714      "decl      %0\n\t"
1715      "jmp       3f\n"
1716      "2:\n\t"
1717      "xorl      %0,%0\n"
1718      "3:\n\t"
1719      "popl      %%ebx"
1720      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1721      : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1722      : "cc");
1723   return __res;
1724 }
1725 #else
1726 __STRING_INLINE char *
1727 __strpbrk_g (__const char *__s, __const char *__accept)
1728 {
1729   register unsigned long int __d0, __d1, __d2, __d3;
1730   register char *__res;
1731   __asm__ __volatile__
1732     ("movl      %%ebx,%%edi\n\t"
1733      "cld\n\t"
1734      "repne; scasb\n\t"
1735      "notl      %%ecx\n\t"
1736      "leal      -1(%%ecx),%%edx\n"
1737      "1:\n\t"
1738      "lodsb\n\t"
1739      "testb     %%al,%%al\n\t"
1740      "je        2f\n\t"
1741      "movl      %%ebx,%%edi\n\t"
1742      "movl      %%edx,%%ecx\n\t"
1743      "repne; scasb\n\t"
1744      "jne       1b\n\t"
1745      "decl      %0\n\t"
1746      "jmp       3f\n"
1747      "2:\n\t"
1748      "xorl      %0,%0\n"
1749      "3:"
1750      : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1751      : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1752      : "cc");
1753   return __res;
1754 }
1755 #endif
1756
1757
1758 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
1759 #define _HAVE_STRING_ARCH_strstr 1
1760 #define strstr(haystack, needle) \
1761   (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1  \
1762                   ? ((needle)[0] == '\0'                                      \
1763                      ? haystack                                               \
1764                      : ((needle)[1] == '\0'                                   \
1765                         ? strchr (haystack, (needle)[0])                      \
1766                         : __strstr_cg (haystack, needle, strlen (needle))))   \
1767                   : __strstr_g (haystack, needle)))
1768
1769 /* Please note that this function need not handle NEEDLEs with a
1770    length shorter than two.  */
1771 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1772                                    size_t __needle_len);
1773
1774 __STRING_INLINE char *
1775 __strstr_cg (__const char *__haystack, __const char __needle[],
1776              size_t __needle_len)
1777 {
1778   register unsigned long int __d0, __d1, __d2;
1779   register char *__res;
1780   __asm__ __volatile__
1781     ("cld\n" \
1782      "1:\n\t"
1783      "movl      %6,%%edi\n\t"
1784      "movl      %5,%%eax\n\t"
1785      "movl      %4,%%ecx\n\t"
1786      "repe; cmpsb\n\t"
1787      "je        2f\n\t"
1788      "cmpb      $0,-1(%%esi)\n\t"
1789      "leal      1(%%eax),%5\n\t"
1790      "jne       1b\n\t"
1791      "xorl      %%eax,%%eax\n"
1792      "2:"
1793      : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1794      : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1795      : "cc");
1796   return __res;
1797 }
1798
1799 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1800 #ifdef __PIC__
1801
1802 __STRING_INLINE char *
1803 __strstr_g (__const char *__haystack, __const char *__needle)
1804 {
1805   register unsigned long int __d0, __d1, __d2;
1806   register char *__res;
1807   __asm__ __volatile__
1808     ("cld\n\t"
1809      "repne; scasb\n\t"
1810      "notl      %%ecx\n\t"
1811      "pushl     %%ebx\n\t"
1812      "decl      %%ecx\n\t"      /* NOTE! This also sets Z if searchstring='' */
1813      "movl      %%ecx,%%ebx\n"
1814      "1:\n\t"
1815      "movl      %%edx,%%edi\n\t"
1816      "movl      %%esi,%%eax\n\t"
1817      "movl      %%ebx,%%ecx\n\t"
1818      "repe; cmpsb\n\t"
1819      "je        2f\n\t"         /* also works for empty string, see above */
1820      "cmpb      $0,-1(%%esi)\n\t"
1821      "leal      1(%%eax),%%esi\n\t"
1822      "jne       1b\n\t"
1823      "xorl      %%eax,%%eax\n"
1824      "2:\n\t"
1825      "popl      %%ebx"
1826      : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1827      : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1828        "d" (__needle)
1829      : "cc");
1830   return __res;
1831 }
1832 #else
1833 __STRING_INLINE char *
1834 __strstr_g (__const char *__haystack, __const char *__needle)
1835 {
1836   register unsigned long int __d0, __d1, __d2, __d3;
1837   register char *__res;
1838   __asm__ __volatile__
1839     ("cld\n\t"
1840      "repne; scasb\n\t"
1841      "notl      %%ecx\n\t"
1842      "decl      %%ecx\n\t"      /* NOTE! This also sets Z if searchstring='' */
1843      "movl      %%ecx,%%edx\n"
1844      "1:\n\t"
1845      "movl      %%ebx,%%edi\n\t"
1846      "movl      %%esi,%%eax\n\t"
1847      "movl      %%edx,%%ecx\n\t"
1848      "repe; cmpsb\n\t"
1849      "je        2f\n\t"         /* also works for empty string, see above */
1850      "cmpb      $0,-1(%%esi)\n\t"
1851      "leal      1(%%eax),%%esi\n\t"
1852      "jne       1b\n\t"
1853      "xorl      %%eax,%%eax\n"
1854      "2:"
1855      : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1856      : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1857        "b" (__needle)
1858      : "cc");
1859   return __res;
1860 }
1861 #endif
1862
1863
1864 /* Bit find functions.  We define only the i686 version since for the other
1865    processors gcc generates good code.  */
1866 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1867 # ifdef __i686__
1868 #  define _HAVE_STRING_ARCH_ffs 1
1869 #  define ffs(word) (__builtin_constant_p (word)                              \
1870                      ? __builtin_ffs (word)                                   \
1871                      : ({ int __cnt, __tmp;                                   \
1872                           __asm__ __volatile__                                \
1873                             ("bsfl %2,%0\n\t"                                 \
1874                              "cmovel %1,%0"                                   \
1875                              : "=&r" (__cnt), "=r" (__tmp)                    \
1876                              : "rm" (word), "1" (-1));                        \
1877                           __cnt + 1; }))
1878
1879 #  ifndef ffsl
1880 #   define ffsl(word) ffs(word)
1881 #  endif
1882 # endif /* i686 */
1883 #endif  /* BSD || X/Open */
1884
1885 #ifndef _FORCE_INLINES
1886 # undef __STRING_INLINE
1887 #endif
1888
1889 #endif  /* use string inlines && GNU CC */