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