1 /* Optimized, inlined string functions. i486/x86-64 version.
2 Copyright (C) 2001-2015 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
20 # error "Never use <bits/string.h> directly; include <string.h> instead."
23 /* The ix86 processors can access unaligned multi-byte variables. */
24 #define _STRING_ARCH_unaligned 1
26 /* Enable inline functions only for i486 or better when compiling for
28 #if !defined __x86_64__ && (defined __i486__ || defined __pentium__ \
29 || defined __pentiumpro__ || defined __pentium4__ \
30 || defined __nocona__ || defined __atom__ \
31 || defined __core2__ || defined __corei7__ \
32 || defined __sandybridge__ || defined __haswell__ \
33 || defined __bonnell__ || defined __silvermont__ \
34 || defined __k6__ || defined __geode__ \
35 || defined __k8__ || defined __athlon__ \
36 || defined __amdfam10__ || defined __bdver1__ \
37 || defined __bdver2__ || defined __bdver3__ \
38 || defined __bdver4__ || defined __btver1__ \
39 || defined __btver2__)
41 /* We only provide optimizations if the user selects them and if
43 # if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
44 && defined __GNUC__ && __GNUC__ >= 2
46 # ifndef __STRING_INLINE
47 # ifndef __extern_inline
48 # define __STRING_INLINE inline
50 # define __STRING_INLINE __extern_inline
54 /* The macros are used in some of the optimized implementations below. */
55 # define __STRING_SMALL_GET16(src, idx) \
56 ((((const unsigned char *) (src))[idx + 1] << 8) \
57 | ((const unsigned char *) (src))[idx])
58 # define __STRING_SMALL_GET32(src, idx) \
59 (((((const unsigned char *) (src))[idx + 3] << 8 \
60 | ((const unsigned char *) (src))[idx + 2]) << 8 \
61 | ((const unsigned char *) (src))[idx + 1]) << 8 \
62 | ((const unsigned char *) (src))[idx])
65 /* Copy N bytes of SRC to DEST. */
66 # define _HAVE_STRING_ARCH_memcpy 1
67 # define memcpy(dest, src, n) \
68 (__extension__ (__builtin_constant_p (n) \
69 ? __memcpy_c ((dest), (src), (n)) \
70 : __memcpy_g ((dest), (src), (n))))
71 # define __memcpy_c(dest, src, n) \
75 ? __memcpy_by4 (dest, src, n) \
77 ? __memcpy_by2 (dest, src, n) \
78 : __memcpy_g (dest, src, n))))
80 __STRING_INLINE
void *__memcpy_by4 (void *__dest
, const void *__src
,
83 __STRING_INLINE
void *
84 __memcpy_by4 (void *__dest
, const void *__src
, size_t __n
)
86 register unsigned long int __d0
, __d1
;
87 register void *__tmp
= __dest
;
96 : "=&r" (__d0
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
97 : "1" (__tmp
), "2" (__src
), "3" (__n
/ 4)
102 __STRING_INLINE
void *__memcpy_by2 (void *__dest
, const void *__src
,
105 __STRING_INLINE
void *
106 __memcpy_by2 (void *__dest
, const void *__src
, size_t __n
)
108 register unsigned long int __d0
, __d1
;
109 register void *__tmp
= __dest
;
112 "jz 2f\n" /* only a word */
123 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
124 : "1" (__tmp
), "2" (__src
), "3" (__n
/ 2)
129 __STRING_INLINE
void *__memcpy_g (void *__dest
, const void *__src
, size_t __n
);
131 __STRING_INLINE
void *
132 __memcpy_g (void *__dest
, const void *__src
, size_t __n
)
134 register unsigned long int __d0
, __d1
, __d2
;
135 register void *__tmp
= __dest
;
147 : "=&c" (__d0
), "=&D" (__d1
), "=&S" (__d2
),
148 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__dest
)
149 : "0" (__n
), "1" (__tmp
), "2" (__src
),
150 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__src
)
155 # define _HAVE_STRING_ARCH_memmove 1
156 # ifndef _FORCE_INLINES
157 /* Copy N bytes of SRC to DEST, guaranteeing
158 correct behavior for overlapping strings. */
159 # define memmove(dest, src, n) __memmove_g (dest, src, n)
161 __STRING_INLINE
void *__memmove_g (void *, const void *, size_t)
164 __STRING_INLINE
void *
165 __memmove_g (void *__dest
, const void *__src
, size_t __n
)
167 register unsigned long int __d0
, __d1
, __d2
;
168 register void *__tmp
= __dest
;
173 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
),
174 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__dest
)
175 : "0" (__n
), "1" (__src
), "2" (__tmp
),
176 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__src
));
182 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
),
183 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__dest
)
184 : "0" (__n
), "1" (__n
- 1 + (const char *) __src
),
185 "2" (__n
- 1 + (char *) __tmp
),
186 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__src
));
191 /* Compare N bytes of S1 and S2. */
192 # define _HAVE_STRING_ARCH_memcmp 1
193 # ifndef _FORCE_INLINES
195 /* gcc has problems to spill registers when using PIC. */
197 memcmp (const void *__s1
, const void *__s2
, size_t __n
)
199 register unsigned long int __d0
, __d1
, __d2
;
209 : "=&a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
210 : "0" (0), "1" (__s1
), "2" (__s2
), "3" (__n
),
211 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s1
),
212 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s2
)
219 /* Set N bytes of S to C. */
220 # define _HAVE_STRING_ARCH_memset 1
221 # define _USE_STRING_ARCH_memset 1
222 # define memset(s, c, n) \
223 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
225 ? __memset_c1 ((s), (c)) \
226 : __memset_gc ((s), (c), (n))) \
227 : (__builtin_constant_p (c) \
228 ? (__builtin_constant_p (n) \
229 ? __memset_ccn ((s), (c), (n)) \
230 : memset ((s), (c), (n))) \
231 : (__builtin_constant_p (n) \
232 ? __memset_gcn ((s), (c), (n)) \
233 : memset ((s), (c), (n))))))
235 # define __memset_c1(s, c) ({ void *__s = (s); \
236 *((unsigned char *) __s) = (unsigned char) (c); \
239 # define __memset_gc(s, c, n) \
240 ({ void *__s = (s); \
243 unsigned short int __usi; \
244 unsigned char __uc; \
246 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
248 /* We apply a trick here. `gcc' would implement the following \
249 assignments using immediate operands. But this uses to much \
250 memory (7, instead of 4 bytes). So we force the value in a \
252 if ((n) == 3 || (n) >= 5) \
253 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
255 /* This `switch' statement will be removed at compile-time. */ \
260 __u = __extension__ ((void *) __u + 4); \
263 __u = __extension__ ((void *) __u + 4); \
266 __u = __extension__ ((void *) __u + 4); \
268 __u->__usi = (unsigned short int) __c; \
269 __u = __extension__ ((void *) __u + 2); \
270 __u->__uc = (unsigned char) __c; \
275 __u = __extension__ ((void *) __u + 4); \
278 __u = __extension__ ((void *) __u + 4); \
281 __u = __extension__ ((void *) __u + 4); \
283 __u->__usi = (unsigned short int) __c; \
288 __u = __extension__ ((void *) __u + 4); \
291 __u = __extension__ ((void *) __u + 4); \
294 __u = __extension__ ((void *) __u + 4); \
296 __u->__uc = (unsigned char) __c; \
301 __u = __extension__ ((void *) __u + 4); \
304 __u = __extension__ ((void *) __u + 4); \
307 __u = __extension__ ((void *) __u + 4); \
316 # define __memset_ccn(s, c, n) \
318 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
321 ? __memset_ccn_by2 (s, \
322 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
326 __STRING_INLINE
void *__memset_ccn_by4 (void *__s
, unsigned int __c
,
329 __STRING_INLINE
void *
330 __memset_ccn_by4 (void *__s
, unsigned int __c
, size_t __n
)
332 register void *__tmp
= __s
;
333 register unsigned long int __d0
;
338 : "=&a" (__c
), "=&D" (__tmp
), "=&c" (__d0
),
339 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
340 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
349 : "=&r" (__c
), "=&r" (__tmp
), "=&r" (__d0
),
350 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
351 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
357 __STRING_INLINE
void *__memset_ccn_by2 (void *__s
, unsigned int __c
,
360 __STRING_INLINE
void *
361 __memset_ccn_by2 (void *__s
, unsigned int __c
, size_t __n
)
363 register unsigned long int __d0
, __d1
;
364 register void *__tmp
= __s
;
370 : "=&a" (__d0
), "=&D" (__tmp
), "=&c" (__d1
),
371 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
372 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
376 ("1:\tmovl %0,(%1)\n\t"
381 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__d1
),
382 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
383 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
389 # define __memset_gcn(s, c, n) \
391 ? __memset_gcn_by4 (s, c, n) \
393 ? __memset_gcn_by2 (s, c, n) \
396 __STRING_INLINE
void *__memset_gcn_by4 (void *__s
, int __c
, size_t __n
);
398 __STRING_INLINE
void *
399 __memset_gcn_by4 (void *__s
, int __c
, size_t __n
)
401 register void *__tmp
= __s
;
402 register unsigned long int __d0
;
413 : "=&q" (__c
), "=&r" (__tmp
), "=&r" (__d0
),
414 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
415 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
420 __STRING_INLINE
void *__memset_gcn_by2 (void *__s
, int __c
, size_t __n
);
422 __STRING_INLINE
void *
423 __memset_gcn_by2 (void *__s
, int __c
, size_t __n
)
425 register unsigned long int __d0
, __d1
;
426 register void *__tmp
= __s
;
438 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__d1
),
439 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
440 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
446 /* Search N bytes of S for C. */
447 # define _HAVE_STRING_ARCH_memchr 1
448 # ifndef _FORCE_INLINES
449 __STRING_INLINE
void *
450 memchr (const void *__s
, int __c
, size_t __n
)
452 register unsigned long int __d0
;
454 register unsigned long int __d1
;
456 register unsigned char *__res
;
464 : "=D" (__res
), "=&c" (__d0
), "=&r" (__d1
)
465 : "a" (__c
), "0" (__s
), "1" (__n
), "2" (1),
466 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
475 : "=D" (__res
), "=&c" (__d0
)
476 : "a" (__c
), "0" (__s
), "1" (__n
),
477 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
484 # define _HAVE_STRING_ARCH_memrchr 1
485 # ifndef _FORCE_INLINES
486 __STRING_INLINE
void *__memrchr (const void *__s
, int __c
, size_t __n
);
488 __STRING_INLINE
void *
489 __memrchr (const void *__s
, int __c
, size_t __n
)
491 register unsigned long int __d0
;
493 register unsigned long int __d1
;
495 register void *__res
;
505 : "=D" (__res
), "=&c" (__d0
), "=&r" (__d1
)
506 : "a" (__c
), "0" (__s
+ __n
- 1), "1" (__n
), "2" (-1),
507 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
517 : "=D" (__res
), "=&c" (__d0
)
518 : "a" (__c
), "0" (__s
+ __n
- 1), "1" (__n
),
519 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
525 # define memrchr(s, c, n) __memrchr ((s), (c), (n))
529 /* Return pointer to C in S. */
530 # define _HAVE_STRING_ARCH_rawmemchr 1
531 __STRING_INLINE
void *__rawmemchr (const void *__s
, int __c
);
533 # ifndef _FORCE_INLINES
534 __STRING_INLINE
void *
535 __rawmemchr (const void *__s
, int __c
)
537 register unsigned long int __d0
;
538 register unsigned char *__res
;
542 : "=D" (__res
), "=&c" (__d0
)
543 : "a" (__c
), "0" (__s
), "1" (0xffffffff),
544 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
549 __STRING_INLINE
void *
550 rawmemchr (const void *__s
, int __c
)
552 return __rawmemchr (__s
, __c
);
554 # endif /* use GNU */
558 /* Return the length of S. */
559 # define _HAVE_STRING_ARCH_strlen 1
560 # define strlen(str) \
561 (__extension__ (__builtin_constant_p (str) \
562 ? __builtin_strlen (str) \
564 __STRING_INLINE
size_t __strlen_g (const char *__str
);
566 __STRING_INLINE
size_t
567 __strlen_g (const char *__str
)
569 register char __dummy
;
570 register const char *__tmp
= __str
;
577 : "=r" (__tmp
), "=&q" (__dummy
)
579 "m" ( *(struct { char __x
[0xfffffff]; } *)__str
)
581 return __tmp
- __str
- 1;
585 /* Copy SRC to DEST. */
586 # define _HAVE_STRING_ARCH_strcpy 1
587 # define strcpy(dest, src) \
588 (__extension__ (__builtin_constant_p (src) \
589 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
590 ? __strcpy_a_small ((dest), (src), strlen (src) + 1) \
591 : (char *) memcpy ((char *) (dest), \
592 (const char *) (src), \
594 : __strcpy_g ((dest), (src))))
596 # define __strcpy_a_small(dest, src, srclen) \
597 (__extension__ ({ char *__dest = (dest); \
600 unsigned short int __usi; \
601 unsigned char __uc; \
603 } *__u = (void *) __dest; \
610 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
613 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
614 __u = __extension__ ((void *) __u + 2); \
618 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
621 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
622 __u = __extension__ ((void *) __u + 4); \
626 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
627 __u = __extension__ ((void *) __u + 4); \
628 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
631 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
632 __u = __extension__ ((void *) __u + 4); \
633 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
634 __u = __extension__ ((void *) __u + 2); \
638 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
639 __u = __extension__ ((void *) __u + 4); \
640 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
645 __STRING_INLINE
char *__strcpy_g (char *__dest
, const char *__src
);
647 __STRING_INLINE
char *
648 __strcpy_g (char *__dest
, const char *__src
)
650 register char *__tmp
= __dest
;
651 register char __dummy
;
661 : "=&r" (__src
), "=&r" (__tmp
), "=&q" (__dummy
),
662 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
663 : "0" (__src
), "1" (__tmp
),
664 "m" ( *(struct { char __x
[0xfffffff]; } *)__src
)
671 # define _HAVE_STRING_ARCH_stpcpy 1
672 /* Copy SRC to DEST. */
673 # define __stpcpy(dest, src) \
674 (__extension__ (__builtin_constant_p (src) \
675 ? (strlen (src) + 1 <= 8 \
676 ? __stpcpy_a_small ((dest), (src), strlen (src) + 1) \
677 : __stpcpy_c ((dest), (src), strlen (src) + 1)) \
678 : __stpcpy_g ((dest), (src))))
679 # define __stpcpy_c(dest, src, srclen) \
681 ? __mempcpy_by4 (dest, src, srclen) - 1 \
682 : ((srclen) % 2 == 0 \
683 ? __mempcpy_by2 (dest, src, srclen) - 1 \
684 : __mempcpy_byn (dest, src, srclen) - 1))
686 /* In glibc itself we use this symbol for namespace reasons. */
687 # define stpcpy(dest, src) __stpcpy ((dest), (src))
689 # define __stpcpy_a_small(dest, src, srclen) \
690 (__extension__ ({ union { \
692 unsigned short int __usi; \
693 unsigned char __uc; \
695 } *__u = (void *) (dest); \
702 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
703 __u = __extension__ ((void *) __u + 1); \
706 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
707 __u = __extension__ ((void *) __u + 2); \
711 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
712 __u = __extension__ ((void *) __u + 3); \
715 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
716 __u = __extension__ ((void *) __u + 4); \
720 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
721 __u = __extension__ ((void *) __u + 4); \
722 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
723 __u = __extension__ ((void *) __u + 1); \
726 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
727 __u = __extension__ ((void *) __u + 4); \
728 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
729 __u = __extension__ ((void *) __u + 2); \
733 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
734 __u = __extension__ ((void *) __u + 4); \
735 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
736 __u = __extension__ ((void *) __u + 3); \
741 __STRING_INLINE
char *__mempcpy_by4 (char *__dest
, const char *__src
,
744 __STRING_INLINE
char *
745 __mempcpy_by4 (char *__dest
, const char *__src
, size_t __srclen
)
747 register char *__tmp
= __dest
;
748 register unsigned long int __d0
, __d1
;
757 : "=&r" (__d0
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
758 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 4)
763 __STRING_INLINE
char *__mempcpy_by2 (char *__dest
, const char *__src
,
766 __STRING_INLINE
char *
767 __mempcpy_by2 (char *__dest
, const char *__src
, size_t __srclen
)
769 register char *__tmp
= __dest
;
770 register unsigned long int __d0
, __d1
;
773 "jz 2f\n" /* only a word */
784 : "=&q" (__d0
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__d1
),
785 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
786 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 2),
787 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
792 __STRING_INLINE
char *__mempcpy_byn (char *__dest
, const char *__src
,
795 __STRING_INLINE
char *
796 __mempcpy_byn (char *__dest
, const char *__src
, size_t __srclen
)
798 register unsigned long __d0
, __d1
;
799 register char *__tmp
= __dest
;
811 : "=D" (__tmp
), "=&c" (__d0
), "=&S" (__d1
),
812 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
813 : "0" (__tmp
), "1" (__srclen
), "2" (__src
),
814 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
819 __STRING_INLINE
char *__stpcpy_g (char *__dest
, const char *__src
);
821 __STRING_INLINE
char *
822 __stpcpy_g (char *__dest
, const char *__src
)
824 register char *__tmp
= __dest
;
825 register char __dummy
;
835 : "=&r" (__src
), "=r" (__tmp
), "=&q" (__dummy
),
836 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
837 : "0" (__src
), "1" (__tmp
),
838 "m" ( *(struct { char __x
[0xfffffff]; } *)__src
)
845 /* Copy no more than N characters of SRC to DEST. */
846 # define _HAVE_STRING_ARCH_strncpy 1
847 # define strncpy(dest, src, n) \
848 (__extension__ (__builtin_constant_p (src) \
849 ? ((strlen (src) + 1 >= ((size_t) (n)) \
850 ? (char *) memcpy ((char *) (dest), \
851 (const char *) (src), n) \
852 : __strncpy_cg ((dest), (src), strlen (src) + 1, n))) \
853 : __strncpy_gg ((dest), (src), n)))
854 # define __strncpy_cg(dest, src, srclen, n) \
855 (((srclen) % 4 == 0) \
856 ? __strncpy_by4 (dest, src, srclen, n) \
857 : (((srclen) % 2 == 0) \
858 ? __strncpy_by2 (dest, src, srclen, n) \
859 : __strncpy_byn (dest, src, srclen, n)))
861 __STRING_INLINE
char *__strncpy_by4 (char *__dest
, const char __src
[],
862 size_t __srclen
, size_t __n
);
864 __STRING_INLINE
char *
865 __strncpy_by4 (char *__dest
, const char __src
[], size_t __srclen
, size_t __n
)
867 register char *__tmp
= __dest
;
868 register int __dummy1
, __dummy2
;
877 : "=&r" (__dummy1
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__dummy2
),
878 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
879 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 4),
880 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
882 (void) memset (__tmp
, '\0', __n
- __srclen
);
886 __STRING_INLINE
char *__strncpy_by2 (char *__dest
, const char __src
[],
887 size_t __srclen
, size_t __n
);
889 __STRING_INLINE
char *
890 __strncpy_by2 (char *__dest
, const char __src
[], size_t __srclen
, size_t __n
)
892 register char *__tmp
= __dest
;
893 register int __dummy1
, __dummy2
;
896 "jz 2f\n" /* only a word */
907 : "=&q" (__dummy1
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__dummy2
),
908 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
909 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 2),
910 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
912 (void) memset (__tmp
+ 2, '\0', __n
- __srclen
);
916 __STRING_INLINE
char *__strncpy_byn (char *__dest
, const char __src
[],
917 size_t __srclen
, size_t __n
);
919 __STRING_INLINE
char *
920 __strncpy_byn (char *__dest
, const char __src
[], size_t __srclen
, size_t __n
)
922 register unsigned long int __d0
, __d1
;
923 register char *__tmp
= __dest
;
935 : "=D" (__tmp
), "=&c" (__d0
), "=&S" (__d1
),
936 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
937 : "1" (__srclen
), "0" (__tmp
),"2" (__src
),
938 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
940 (void) memset (__tmp
, '\0', __n
- __srclen
);
944 __STRING_INLINE
char *__strncpy_gg (char *__dest
, const char *__src
,
947 __STRING_INLINE
char *
948 __strncpy_gg (char *__dest
, const char *__src
, size_t __n
)
950 register char *__tmp
= __dest
;
951 register char __dummy
;
969 : "=&r" (__src
), "=&r" (__tmp
), "=&q" (__dummy
), "=&r" (__n
)
970 : "0" (__src
), "1" (__tmp
), "3" (__n
)
977 /* Append SRC onto DEST. */
978 # define _HAVE_STRING_ARCH_strcat 1
979 # define strcat(dest, src) \
980 (__extension__ (__builtin_constant_p (src) \
981 ? __strcat_c ((dest), (src), strlen (src) + 1) \
982 : __strcat_g ((dest), (src))))
984 __STRING_INLINE
char *__strcat_c (char *__dest
, const char __src
[],
987 __STRING_INLINE
char *
988 __strcat_c (char *__dest
, const char __src
[], size_t __srclen
)
991 register unsigned long int __d0
;
992 register char *__tmp
;
995 : "=D" (__tmp
), "=&c" (__d0
),
996 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
997 : "0" (__dest
), "1" (0xffffffff), "a" (0),
998 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
1002 register char *__tmp
= __dest
- 1;
1003 __asm__ __volatile__
1009 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
1011 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
1014 (void) memcpy (__tmp
, __src
, __srclen
);
1018 __STRING_INLINE
char *__strcat_g (char *__dest
, const char *__src
);
1020 __STRING_INLINE
char *
1021 __strcat_g (char *__dest
, const char *__src
)
1023 register char *__tmp
= __dest
- 1;
1024 register char __dummy
;
1025 __asm__ __volatile__
1037 : "=&q" (__dummy
), "=&r" (__tmp
), "=&r" (__src
),
1038 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
1039 : "1" (__tmp
), "2" (__src
),
1040 "m" ( *(struct { char __x
[0xfffffff]; } *)__src
)
1046 /* Append no more than N characters from SRC onto DEST. */
1047 # define _HAVE_STRING_ARCH_strncat 1
1048 # define strncat(dest, src, n) \
1049 (__extension__ ({ char *__dest = (dest); \
1050 __builtin_constant_p (src) && __builtin_constant_p (n) \
1051 ? (strlen (src) < ((size_t) (n)) \
1052 ? strcat (__dest, (src)) \
1053 : (*(char *)__mempcpy (strchr (__dest, '\0'), \
1054 (const char *) (src), \
1055 (n)) = 0, __dest)) \
1056 : __strncat_g (__dest, (src), (n)); }))
1058 __STRING_INLINE
char *__strncat_g (char *__dest
, const char __src
[],
1061 __STRING_INLINE
char *
1062 __strncat_g (char *__dest
, const char __src
[], size_t __n
)
1064 register char *__tmp
= __dest
;
1065 register char __dummy
;
1067 __asm__ __volatile__
1081 : "=&a" (__dummy
), "=&D" (__tmp
), "=&S" (__src
), "=&c" (__n
)
1082 : "g" (__n
), "0" (0), "1" (__tmp
), "2" (__src
), "3" (0xffffffff)
1086 __asm__ __volatile__
1103 : "=&q" (__dummy
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__n
)
1104 : "1" (__tmp
), "2" (__src
), "3" (__n
)
1111 /* Compare S1 and S2. */
1112 # define _HAVE_STRING_ARCH_strcmp 1
1113 # define strcmp(s1, s2) \
1114 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1115 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1116 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1117 ? memcmp ((const char *) (s1), (const char *) (s2), \
1118 (strlen (s1) < strlen (s2) \
1119 ? strlen (s1) : strlen (s2)) + 1) \
1120 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1121 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1122 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1123 ? __strcmp_cc ((const unsigned char *) (s1), \
1124 (const unsigned char *) (s2), \
1126 : __strcmp_cg ((const unsigned char *) (s1), \
1127 (const unsigned char *) (s2), \
1129 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1130 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1131 ? (__builtin_constant_p (s1) \
1132 ? __strcmp_cc ((const unsigned char *) (s1), \
1133 (const unsigned char *) (s2), \
1135 : __strcmp_gc ((const unsigned char *) (s1), \
1136 (const unsigned char *) (s2), \
1138 : __strcmp_gg ((s1), (s2))))))
1140 # define __strcmp_cc(s1, s2, l) \
1141 (__extension__ ({ register int __result = (s1)[0] - (s2)[0]; \
1142 if (l > 0 && __result == 0) \
1144 __result = (s1)[1] - (s2)[1]; \
1145 if (l > 1 && __result == 0) \
1147 __result = (s1)[2] - (s2)[2]; \
1148 if (l > 2 && __result == 0) \
1149 __result = (s1)[3] - (s2)[3]; \
1154 # define __strcmp_cg(s1, s2, l1) \
1155 (__extension__ ({ const unsigned char *__s2 = (s2); \
1156 register int __result = (s1)[0] - __s2[0]; \
1157 if (l1 > 0 && __result == 0) \
1159 __result = (s1)[1] - __s2[1]; \
1160 if (l1 > 1 && __result == 0) \
1162 __result = (s1)[2] - __s2[2]; \
1163 if (l1 > 2 && __result == 0) \
1164 __result = (s1)[3] - __s2[3]; \
1169 # define __strcmp_gc(s1, s2, l2) \
1170 (__extension__ ({ const unsigned char *__s1 = (s1); \
1171 register int __result = __s1[0] - (s2)[0]; \
1172 if (l2 > 0 && __result == 0) \
1174 __result = __s1[1] - (s2)[1]; \
1175 if (l2 > 1 && __result == 0) \
1177 __result = __s1[2] - (s2)[2]; \
1178 if (l2 > 2 && __result == 0) \
1179 __result = __s1[3] - (s2)[3]; \
1184 __STRING_INLINE
int __strcmp_gg (const char *__s1
, const char *__s2
);
1187 __strcmp_gg (const char *__s1
, const char *__s2
)
1190 __asm__ __volatile__
1206 : "=q" (__res
), "=&r" (__s1
), "=&r" (__s2
)
1207 : "1" (__s1
), "2" (__s2
),
1208 "m" ( *(struct { char __x
[0xfffffff]; } *)__s1
),
1209 "m" ( *(struct { char __x
[0xfffffff]; } *)__s2
)
1215 /* Compare N characters of S1 and S2. */
1216 # define _HAVE_STRING_ARCH_strncmp 1
1217 # define strncmp(s1, s2, n) \
1218 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1219 ? strcmp ((s1), (s2)) \
1220 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1221 ? strcmp ((s1), (s2)) \
1222 : __strncmp_g ((s1), (s2), (n)))))
1224 __STRING_INLINE
int __strncmp_g (const char *__s1
, const char *__s2
,
1228 __strncmp_g (const char *__s1
, const char *__s2
, size_t __n
)
1231 __asm__ __volatile__
1250 : "=q" (__res
), "=&r" (__s1
), "=&r" (__s2
), "=&r" (__n
)
1251 : "1" (__s1
), "2" (__s2
), "3" (__n
),
1252 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s1
),
1253 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s2
)
1259 /* Find the first occurrence of C in S. */
1260 # define _HAVE_STRING_ARCH_strchr 1
1261 # define _USE_STRING_ARCH_strchr 1
1262 # define strchr(s, c) \
1263 (__extension__ (__builtin_constant_p (c) \
1265 ? (char *) __rawmemchr ((s), (c)) \
1266 : __strchr_c ((s), ((c) & 0xff) << 8)) \
1267 : __strchr_g ((s), (c))))
1269 __STRING_INLINE
char *__strchr_c (const char *__s
, int __c
);
1271 __STRING_INLINE
char *
1272 __strchr_c (const char *__s
, int __c
)
1274 register unsigned long int __d0
;
1275 register char *__res
;
1276 __asm__ __volatile__
1278 "movb (%0),%%al\n\t"
1279 "cmpb %%ah,%%al\n\t"
1282 "testb %%al,%%al\n\t"
1286 : "=r" (__res
), "=&a" (__d0
)
1287 : "0" (__s
), "1" (__c
),
1288 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1293 __STRING_INLINE
char *__strchr_g (const char *__s
, int __c
);
1295 __STRING_INLINE
char *
1296 __strchr_g (const char *__s
, int __c
)
1298 register unsigned long int __d0
;
1299 register char *__res
;
1300 __asm__ __volatile__
1303 "movb (%0),%%al\n\t"
1304 "cmpb %%ah,%%al\n\t"
1307 "testb %%al,%%al\n\t"
1311 : "=r" (__res
), "=&a" (__d0
)
1312 : "0" (__s
), "1" (__c
),
1313 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1319 /* Find the first occurrence of C in S or the final NUL byte. */
1320 # define _HAVE_STRING_ARCH_strchrnul 1
1321 # define __strchrnul(s, c) \
1322 (__extension__ (__builtin_constant_p (c) \
1324 ? (char *) __rawmemchr ((s), c) \
1325 : __strchrnul_c ((s), ((c) & 0xff) << 8)) \
1326 : __strchrnul_g ((s), c)))
1328 __STRING_INLINE
char *__strchrnul_c (const char *__s
, int __c
);
1330 __STRING_INLINE
char *
1331 __strchrnul_c (const char *__s
, int __c
)
1333 register unsigned long int __d0
;
1334 register char *__res
;
1335 __asm__ __volatile__
1337 "movb (%0),%%al\n\t"
1338 "cmpb %%ah,%%al\n\t"
1341 "testb %%al,%%al\n\t"
1345 : "=r" (__res
), "=&a" (__d0
)
1346 : "0" (__s
), "1" (__c
),
1347 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1352 __STRING_INLINE
char *__strchrnul_g (const char *__s
, int __c
);
1354 __STRING_INLINE
char *
1355 __strchrnul_g (const char *__s
, int __c
)
1357 register unsigned long int __d0
;
1358 register char *__res
;
1359 __asm__ __volatile__
1362 "movb (%0),%%al\n\t"
1363 "cmpb %%ah,%%al\n\t"
1366 "testb %%al,%%al\n\t"
1370 : "=r" (__res
), "=&a" (__d0
)
1371 : "0" (__s
), "1" (__c
),
1372 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1377 # define strchrnul(s, c) __strchrnul ((s), (c))
1381 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1382 /* Find the first occurrence of C in S. This is the BSD name. */
1383 # define _HAVE_STRING_ARCH_index 1
1384 # define index(s, c) \
1385 (__extension__ (__builtin_constant_p (c) \
1386 ? __strchr_c ((s), ((c) & 0xff) << 8) \
1387 : __strchr_g ((s), (c))))
1391 /* Find the last occurrence of C in S. */
1392 # define _HAVE_STRING_ARCH_strrchr 1
1393 # define strrchr(s, c) \
1394 (__extension__ (__builtin_constant_p (c) \
1395 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1396 : __strrchr_g ((s), (c))))
1399 __STRING_INLINE
char *__strrchr_c (const char *__s
, int __c
);
1401 __STRING_INLINE
char *
1402 __strrchr_c (const char *__s
, int __c
)
1404 register unsigned long int __d0
, __d1
;
1405 register char *__res
;
1406 __asm__ __volatile__
1414 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1415 : "0" (1), "1" (__s
), "2" (__c
),
1416 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1421 __STRING_INLINE
char *__strrchr_g (const char *__s
, int __c
);
1423 __STRING_INLINE
char *
1424 __strrchr_g (const char *__s
, int __c
)
1426 register unsigned long int __d0
, __d1
;
1427 register char *__res
;
1428 __asm__ __volatile__
1437 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1438 : "0" (1), "1" (__s
), "2" (__c
),
1439 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1444 __STRING_INLINE
char *__strrchr_c (const char *__s
, int __c
);
1446 __STRING_INLINE
char *
1447 __strrchr_c (const char *__s
, int __c
)
1449 register unsigned long int __d0
, __d1
;
1450 register char *__res
;
1451 __asm__ __volatile__
1455 "cmpb %%ah,%%al\n\t"
1457 "leal -1(%%esi),%0\n"
1459 "testb %%al,%%al\n\t"
1461 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1462 : "0" (0), "1" (__s
), "2" (__c
),
1463 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1468 __STRING_INLINE
char *__strrchr_g (const char *__s
, int __c
);
1470 __STRING_INLINE
char *
1471 __strrchr_g (const char *__s
, int __c
)
1473 register unsigned long int __d0
, __d1
;
1474 register char *__res
;
1475 __asm__ __volatile__
1480 "cmpb %%ah,%%al\n\t"
1482 "leal -1(%%esi),%0\n"
1484 "testb %%al,%%al\n\t"
1486 : "=r" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1487 : "0" (0), "1" (__s
), "2" (__c
),
1488 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1495 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1496 /* Find the last occurrence of C in S. This is the BSD name. */
1497 # define _HAVE_STRING_ARCH_rindex 1
1498 # define rindex(s, c) \
1499 (__extension__ (__builtin_constant_p (c) \
1500 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1501 : __strrchr_g ((s), (c))))
1505 /* Return the length of the initial segment of S which
1506 consists entirely of characters not in REJECT. */
1507 # define _HAVE_STRING_ARCH_strcspn 1
1508 # define strcspn(s, reject) \
1509 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1510 ? ((reject)[0] == '\0' \
1512 : ((reject)[1] == '\0' \
1513 ? __strcspn_c1 ((s), (((reject)[0] << 8) & 0xff00)) \
1514 : __strcspn_cg ((s), (reject), strlen (reject)))) \
1515 : __strcspn_g ((s), (reject))))
1517 __STRING_INLINE
size_t __strcspn_c1 (const char *__s
, int __reject
);
1519 # ifndef _FORCE_INLINES
1520 __STRING_INLINE
size_t
1521 __strcspn_c1 (const char *__s
, int __reject
)
1523 register unsigned long int __d0
;
1524 register char *__res
;
1525 __asm__ __volatile__
1527 "movb (%0),%%al\n\t"
1529 "cmpb %%ah,%%al\n\t"
1531 "testb %%al,%%al\n\t"
1534 : "=r" (__res
), "=&a" (__d0
)
1535 : "0" (__s
), "1" (__reject
),
1536 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1538 return (__res
- 1) - __s
;
1542 __STRING_INLINE
size_t __strcspn_cg (const char *__s
, const char __reject
[],
1543 size_t __reject_len
);
1545 __STRING_INLINE
size_t
1546 __strcspn_cg (const char *__s
, const char __reject
[], size_t __reject_len
)
1548 register unsigned long int __d0
, __d1
, __d2
;
1549 register const char *__res
;
1550 __asm__ __volatile__
1554 "testb %%al,%%al\n\t"
1561 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1562 : "0" (__s
), "d" (__reject
), "g" (__reject_len
)
1564 return (__res
- 1) - __s
;
1567 __STRING_INLINE
size_t __strcspn_g (const char *__s
, const char *__reject
);
1570 __STRING_INLINE
size_t
1571 __strcspn_g (const char *__s
, const char *__reject
)
1573 register unsigned long int __d0
, __d1
, __d2
;
1574 register const char *__res
;
1575 __asm__ __volatile__
1581 "leal -1(%%ecx),%%ebx\n"
1584 "testb %%al,%%al\n\t"
1587 "movl %%ebx,%%ecx\n\t"
1592 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1593 : "r" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff)
1595 return (__res
- 1) - __s
;
1598 __STRING_INLINE
size_t
1599 __strcspn_g (const char *__s
, const char *__reject
)
1601 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1602 register const char *__res
;
1603 __asm__ __volatile__
1607 "leal -1(%%ecx),%%edx\n"
1610 "testb %%al,%%al\n\t"
1612 "movl %%ebx,%%edi\n\t"
1613 "movl %%edx,%%ecx\n\t"
1617 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1618 : "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__reject
), "b" (__reject
)
1619 /* Clobber memory, otherwise GCC cannot handle this. */
1621 return (__res
- 1) - __s
;
1626 /* Return the length of the initial segment of S which
1627 consists entirely of characters in ACCEPT. */
1628 # define _HAVE_STRING_ARCH_strspn 1
1629 # define strspn(s, accept) \
1630 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1631 ? ((accept)[0] == '\0' \
1633 : ((accept)[1] == '\0' \
1634 ? __strspn_c1 ((s), (((accept)[0] << 8 ) & 0xff00)) \
1635 : __strspn_cg ((s), (accept), strlen (accept)))) \
1636 : __strspn_g ((s), (accept))))
1638 # ifndef _FORCE_INLINES
1639 __STRING_INLINE
size_t __strspn_c1 (const char *__s
, int __accept
);
1641 __STRING_INLINE
size_t
1642 __strspn_c1 (const char *__s
, int __accept
)
1644 register unsigned long int __d0
;
1645 register char *__res
;
1646 /* Please note that __accept never can be '\0'. */
1647 __asm__ __volatile__
1653 : "=r" (__res
), "=&q" (__d0
)
1654 : "0" (__s
), "1" (__accept
),
1655 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1657 return (__res
- 1) - __s
;
1661 __STRING_INLINE
size_t __strspn_cg (const char *__s
, const char __accept
[],
1662 size_t __accept_len
);
1664 __STRING_INLINE
size_t
1665 __strspn_cg (const char *__s
, const char __accept
[], size_t __accept_len
)
1667 register unsigned long int __d0
, __d1
, __d2
;
1668 register const char *__res
;
1669 __asm__ __volatile__
1673 "testb %%al,%%al\n\t"
1680 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1681 : "0" (__s
), "g" (__accept
), "g" (__accept_len
),
1682 /* Since we do not know how large the memory we access it, use a
1683 really large amount. */
1684 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
),
1685 "m" ( *(struct { __extension__
char __x
[__accept_len
]; } *)__accept
)
1687 return (__res
- 1) - __s
;
1690 __STRING_INLINE
size_t __strspn_g (const char *__s
, const char *__accept
);
1693 __STRING_INLINE
size_t
1694 __strspn_g (const char *__s
, const char *__accept
)
1696 register unsigned long int __d0
, __d1
, __d2
;
1697 register const char *__res
;
1698 __asm__ __volatile__
1703 "leal -1(%%ecx),%%ebx\n"
1706 "testb %%al,%%al\n\t"
1708 "movl %%edx,%%edi\n\t"
1709 "movl %%ebx,%%ecx\n\t"
1714 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1715 : "d" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__accept
)
1717 return (__res
- 1) - __s
;
1720 __STRING_INLINE
size_t
1721 __strspn_g (const char *__s
, const char *__accept
)
1723 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1724 register const char *__res
;
1725 __asm__ __volatile__
1729 "leal -1(%%ecx),%%edx\n"
1732 "testb %%al,%%al\n\t"
1734 "movl %%ebx,%%edi\n\t"
1735 "movl %%edx,%%ecx\n\t"
1739 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1740 : "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__accept
), "b" (__accept
)
1742 return (__res
- 1) - __s
;
1747 /* Find the first occurrence in S of any character in ACCEPT. */
1748 # define _HAVE_STRING_ARCH_strpbrk 1
1749 # define strpbrk(s, accept) \
1750 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1751 ? ((accept)[0] == '\0' \
1752 ? ((void) (s), (char *) 0) \
1753 : ((accept)[1] == '\0' \
1754 ? strchr ((s), (accept)[0]) \
1755 : __strpbrk_cg ((s), (accept), strlen (accept)))) \
1756 : __strpbrk_g ((s), (accept))))
1758 __STRING_INLINE
char *__strpbrk_cg (const char *__s
, const char __accept
[],
1759 size_t __accept_len
);
1761 __STRING_INLINE
char *
1762 __strpbrk_cg (const char *__s
, const char __accept
[], size_t __accept_len
)
1764 register unsigned long int __d0
, __d1
, __d2
;
1765 register char *__res
;
1766 __asm__ __volatile__
1770 "testb %%al,%%al\n\t"
1781 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1782 : "0" (__s
), "d" (__accept
), "g" (__accept_len
)
1787 __STRING_INLINE
char *__strpbrk_g (const char *__s
, const char *__accept
);
1790 __STRING_INLINE
char *
1791 __strpbrk_g (const char *__s
, const char *__accept
)
1793 register unsigned long int __d0
, __d1
, __d2
;
1794 register char *__res
;
1795 __asm__ __volatile__
1797 "movl %%edx,%%edi\n\t"
1801 "leal -1(%%ecx),%%ebx\n"
1804 "testb %%al,%%al\n\t"
1806 "movl %%edx,%%edi\n\t"
1807 "movl %%ebx,%%ecx\n\t"
1816 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1817 : "d" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
1822 __STRING_INLINE
char *
1823 __strpbrk_g (const char *__s
, const char *__accept
)
1825 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1826 register char *__res
;
1827 __asm__ __volatile__
1828 ("movl %%ebx,%%edi\n\t"
1832 "leal -1(%%ecx),%%edx\n"
1835 "testb %%al,%%al\n\t"
1837 "movl %%ebx,%%edi\n\t"
1838 "movl %%edx,%%ecx\n\t"
1846 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
1847 : "0" (__s
), "1" (0), "2" (0xffffffff), "b" (__accept
)
1854 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1855 # define _HAVE_STRING_ARCH_strstr 1
1856 # define strstr(haystack, needle) \
1857 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1858 ? ((needle)[0] == '\0' \
1860 : ((needle)[1] == '\0' \
1861 ? strchr ((haystack), (needle)[0]) \
1862 : __strstr_cg ((haystack), (needle), \
1863 strlen (needle)))) \
1864 : __strstr_g ((haystack), (needle))))
1866 /* Please note that this function need not handle NEEDLEs with a
1867 length shorter than two. */
1868 __STRING_INLINE
char *__strstr_cg (const char *__haystack
,
1869 const char __needle
[],
1870 size_t __needle_len
);
1872 __STRING_INLINE
char *
1873 __strstr_cg (const char *__haystack
, const char __needle
[],
1874 size_t __needle_len
)
1876 register unsigned long int __d0
, __d1
, __d2
;
1877 register char *__res
;
1878 __asm__ __volatile__
1886 "cmpb $0,-1(%%esi)\n\t"
1887 "leal 1(%%eax),%5\n\t"
1889 "xorl %%eax,%%eax\n"
1891 : "=&a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
1892 : "g" (__needle_len
), "1" (__haystack
), "d" (__needle
)
1897 __STRING_INLINE
char *__strstr_g (const char *__haystack
,
1898 const char *__needle
);
1901 __STRING_INLINE
char *
1902 __strstr_g (const char *__haystack
, const char *__needle
)
1904 register unsigned long int __d0
, __d1
, __d2
;
1905 register char *__res
;
1906 __asm__ __volatile__
1911 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1912 "movl %%ecx,%%ebx\n"
1914 "movl %%edx,%%edi\n\t"
1915 "movl %%esi,%%eax\n\t"
1916 "movl %%ebx,%%ecx\n\t"
1918 "je 2f\n\t" /* also works for empty string, see above */
1919 "cmpb $0,-1(%%esi)\n\t"
1920 "leal 1(%%eax),%%esi\n\t"
1922 "xorl %%eax,%%eax\n"
1925 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
1926 : "0" (0), "1" (0xffffffff), "2" (__haystack
), "3" (__needle
),
1932 __STRING_INLINE
char *
1933 __strstr_g (const char *__haystack
, const char *__needle
)
1935 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1936 register char *__res
;
1937 __asm__ __volatile__
1941 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1942 "movl %%ecx,%%edx\n"
1944 "movl %%ebx,%%edi\n\t"
1945 "movl %%esi,%%eax\n\t"
1946 "movl %%edx,%%ecx\n\t"
1948 "je 2f\n\t" /* also works for empty string, see above */
1949 "cmpb $0,-1(%%esi)\n\t"
1950 "leal 1(%%eax),%%esi\n\t"
1952 "xorl %%eax,%%eax\n"
1954 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1955 : "0" (0), "1" (0xffffffff), "2" (__haystack
), "3" (__needle
),
1963 /* Bit find functions. We define only the i686 version since for the other
1964 processors gcc generates good code. */
1965 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1967 # define _HAVE_STRING_ARCH_ffs 1
1968 # define ffs(word) (__builtin_constant_p (word) \
1969 ? __builtin_ffs (word) \
1970 : ({ int __cnt, __tmp; \
1971 __asm__ __volatile__ \
1974 : "=&r" (__cnt), "=r" (__tmp) \
1975 : "rm" (word), "1" (-1)); \
1979 # define ffsl(word) ffs(word)
1982 # endif /* Misc || X/Open */
1984 # ifndef _FORCE_INLINES
1985 # undef __STRING_INLINE
1988 # endif /* use string inlines && GNU CC */