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