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