1 /* Optimized, inlined string functions. i486/x86-64 version.
2 Copyright (C) 2001-2016 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 /* Use the unaligned string inline ABI. */
24 #define _STRING_INLINE_unaligned 1
26 /* Don't inline mempcpy into memcpy as x86 has an optimized mempcpy. */
27 #define _HAVE_STRING_ARCH_mempcpy 1
29 /* Enable inline functions only for i486 or better when compiling for
31 #if !defined __x86_64__ && (defined __i486__ || defined __pentium__ \
32 || defined __pentiumpro__ || defined __pentium4__ \
33 || defined __nocona__ || defined __atom__ \
34 || defined __core2__ || defined __corei7__ \
35 || defined __sandybridge__ || defined __haswell__ \
36 || defined __bonnell__ || defined __silvermont__ \
37 || defined __k6__ || defined __geode__ \
38 || defined __k8__ || defined __athlon__ \
39 || defined __amdfam10__ || defined __bdver1__ \
40 || defined __bdver2__ || defined __bdver3__ \
41 || defined __bdver4__ || defined __btver1__ \
42 || defined __btver2__)
44 /* We only provide optimizations if the user selects them and if
46 # if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
47 && defined __GNUC__ && __GNUC__ >= 2
49 # ifndef __STRING_INLINE
50 # ifndef __extern_inline
51 # define __STRING_INLINE inline
53 # define __STRING_INLINE __extern_inline
57 /* The macros are used in some of the optimized implementations below. */
58 # define __STRING_SMALL_GET16(src, idx) \
59 ((((const unsigned char *) (src))[idx + 1] << 8) \
60 | ((const unsigned char *) (src))[idx])
61 # define __STRING_SMALL_GET32(src, idx) \
62 (((((const unsigned char *) (src))[idx + 3] << 8 \
63 | ((const unsigned char *) (src))[idx + 2]) << 8 \
64 | ((const unsigned char *) (src))[idx + 1]) << 8 \
65 | ((const unsigned char *) (src))[idx])
68 /* Copy N bytes of SRC to DEST. */
69 # define _HAVE_STRING_ARCH_memcpy 1
70 # define memcpy(dest, src, n) \
71 (__extension__ (__builtin_constant_p (n) \
72 ? __memcpy_c ((dest), (src), (n)) \
73 : __memcpy_g ((dest), (src), (n))))
74 # define __memcpy_c(dest, src, n) \
78 ? __memcpy_by4 (dest, src, n) \
80 ? __memcpy_by2 (dest, src, n) \
81 : __memcpy_g (dest, src, n))))
83 __STRING_INLINE
void *__memcpy_by4 (void *__dest
, const void *__src
,
86 __STRING_INLINE
void *
87 __memcpy_by4 (void *__dest
, const void *__src
, size_t __n
)
89 register unsigned long int __d0
, __d1
;
90 register void *__tmp
= __dest
;
99 : "=&r" (__d0
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
100 : "1" (__tmp
), "2" (__src
), "3" (__n
/ 4)
105 __STRING_INLINE
void *__memcpy_by2 (void *__dest
, const void *__src
,
108 __STRING_INLINE
void *
109 __memcpy_by2 (void *__dest
, const void *__src
, size_t __n
)
111 register unsigned long int __d0
, __d1
;
112 register void *__tmp
= __dest
;
115 "jz 2f\n" /* only a word */
126 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
127 : "1" (__tmp
), "2" (__src
), "3" (__n
/ 2)
132 __STRING_INLINE
void *__memcpy_g (void *__dest
, const void *__src
, size_t __n
);
134 __STRING_INLINE
void *
135 __memcpy_g (void *__dest
, const void *__src
, size_t __n
)
137 register unsigned long int __d0
, __d1
, __d2
;
138 register void *__tmp
= __dest
;
150 : "=&c" (__d0
), "=&D" (__d1
), "=&S" (__d2
),
151 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__dest
)
152 : "0" (__n
), "1" (__tmp
), "2" (__src
),
153 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__src
)
158 # define _HAVE_STRING_ARCH_memmove 1
159 # ifndef _FORCE_INLINES
160 /* Copy N bytes of SRC to DEST, guaranteeing
161 correct behavior for overlapping strings. */
162 # define memmove(dest, src, n) __memmove_g (dest, src, n)
164 __STRING_INLINE
void *__memmove_g (void *, const void *, size_t)
167 __STRING_INLINE
void *
168 __memmove_g (void *__dest
, const void *__src
, size_t __n
)
170 register unsigned long int __d0
, __d1
, __d2
;
171 register void *__tmp
= __dest
;
176 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
),
177 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__dest
)
178 : "0" (__n
), "1" (__src
), "2" (__tmp
),
179 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__src
));
187 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
),
188 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__dest
)
189 : "0" (__n
), "1" (__n
+ (const char *) __src
),
190 "2" (__n
+ (char *) __tmp
),
191 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__src
));
196 /* Compare N bytes of S1 and S2. */
197 # define _HAVE_STRING_ARCH_memcmp 1
198 # ifndef _FORCE_INLINES
200 /* gcc has problems to spill registers when using PIC. */
202 memcmp (const void *__s1
, const void *__s2
, size_t __n
)
204 register unsigned long int __d0
, __d1
, __d2
;
214 : "=&a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
215 : "0" (0), "1" (__s1
), "2" (__s2
), "3" (__n
),
216 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s1
),
217 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s2
)
224 /* Set N bytes of S to C. */
225 # define _HAVE_STRING_ARCH_memset 1
226 # define _USE_STRING_ARCH_memset 1
227 # define memset(s, c, n) \
228 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
230 ? __memset_c1 ((s), (c)) \
231 : __memset_gc ((s), (c), (n))) \
232 : (__builtin_constant_p (c) \
233 ? (__builtin_constant_p (n) \
234 ? __memset_ccn ((s), (c), (n)) \
235 : memset ((s), (c), (n))) \
236 : (__builtin_constant_p (n) \
237 ? __memset_gcn ((s), (c), (n)) \
238 : memset ((s), (c), (n))))))
240 # define __memset_c1(s, c) ({ void *__s = (s); \
241 *((unsigned char *) __s) = (unsigned char) (c); \
244 # define __memset_gc(s, c, n) \
245 ({ void *__s = (s); \
248 unsigned short int __usi; \
249 unsigned char __uc; \
251 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
253 /* We apply a trick here. `gcc' would implement the following \
254 assignments using immediate operands. But this uses to much \
255 memory (7, instead of 4 bytes). So we force the value in a \
257 if ((n) == 3 || (n) >= 5) \
258 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
260 /* This `switch' statement will be removed at compile-time. */ \
265 __u = __extension__ ((void *) __u + 4); \
268 __u = __extension__ ((void *) __u + 4); \
271 __u = __extension__ ((void *) __u + 4); \
273 __u->__usi = (unsigned short int) __c; \
274 __u = __extension__ ((void *) __u + 2); \
275 __u->__uc = (unsigned char) __c; \
280 __u = __extension__ ((void *) __u + 4); \
283 __u = __extension__ ((void *) __u + 4); \
286 __u = __extension__ ((void *) __u + 4); \
288 __u->__usi = (unsigned short int) __c; \
293 __u = __extension__ ((void *) __u + 4); \
296 __u = __extension__ ((void *) __u + 4); \
299 __u = __extension__ ((void *) __u + 4); \
301 __u->__uc = (unsigned char) __c; \
306 __u = __extension__ ((void *) __u + 4); \
309 __u = __extension__ ((void *) __u + 4); \
312 __u = __extension__ ((void *) __u + 4); \
321 # define __memset_ccn(s, c, n) \
323 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
326 ? __memset_ccn_by2 (s, \
327 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
331 __STRING_INLINE
void *__memset_ccn_by4 (void *__s
, unsigned int __c
,
334 __STRING_INLINE
void *
335 __memset_ccn_by4 (void *__s
, unsigned int __c
, size_t __n
)
337 register void *__tmp
= __s
;
338 register unsigned long int __d0
;
343 : "=&a" (__c
), "=&D" (__tmp
), "=&c" (__d0
),
344 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
345 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
354 : "=&r" (__c
), "=&r" (__tmp
), "=&r" (__d0
),
355 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
356 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
362 __STRING_INLINE
void *__memset_ccn_by2 (void *__s
, unsigned int __c
,
365 __STRING_INLINE
void *
366 __memset_ccn_by2 (void *__s
, unsigned int __c
, size_t __n
)
368 register unsigned long int __d0
, __d1
;
369 register void *__tmp
= __s
;
375 : "=&a" (__d0
), "=&D" (__tmp
), "=&c" (__d1
),
376 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
377 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
381 ("1:\tmovl %0,(%1)\n\t"
386 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__d1
),
387 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
388 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
394 # define __memset_gcn(s, c, n) \
396 ? __memset_gcn_by4 (s, c, n) \
398 ? __memset_gcn_by2 (s, c, n) \
401 __STRING_INLINE
void *__memset_gcn_by4 (void *__s
, int __c
, size_t __n
);
403 __STRING_INLINE
void *
404 __memset_gcn_by4 (void *__s
, int __c
, size_t __n
)
406 register void *__tmp
= __s
;
407 register unsigned long int __d0
;
418 : "=&q" (__c
), "=&r" (__tmp
), "=&r" (__d0
),
419 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
420 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
425 __STRING_INLINE
void *__memset_gcn_by2 (void *__s
, int __c
, size_t __n
);
427 __STRING_INLINE
void *
428 __memset_gcn_by2 (void *__s
, int __c
, size_t __n
)
430 register unsigned long int __d0
, __d1
;
431 register void *__tmp
= __s
;
443 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__d1
),
444 "=m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
445 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
451 /* Search N bytes of S for C. */
452 # define _HAVE_STRING_ARCH_memchr 1
453 # ifndef _FORCE_INLINES
454 __STRING_INLINE
void *
455 memchr (const void *__s
, int __c
, size_t __n
)
457 register unsigned long int __d0
;
459 register unsigned long int __d1
;
461 register unsigned char *__res
;
469 : "=D" (__res
), "=&c" (__d0
), "=&r" (__d1
)
470 : "a" (__c
), "0" (__s
), "1" (__n
), "2" (1),
471 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
480 : "=D" (__res
), "=&c" (__d0
)
481 : "a" (__c
), "0" (__s
), "1" (__n
),
482 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
489 # define _HAVE_STRING_ARCH_memrchr 1
490 # ifndef _FORCE_INLINES
491 __STRING_INLINE
void *__memrchr (const void *__s
, int __c
, size_t __n
);
493 __STRING_INLINE
void *
494 __memrchr (const void *__s
, int __c
, size_t __n
)
496 register unsigned long int __d0
;
498 register unsigned long int __d1
;
500 register void *__res
;
510 : "=D" (__res
), "=&c" (__d0
), "=&r" (__d1
)
511 : "a" (__c
), "0" (__s
+ __n
- 1), "1" (__n
), "2" (-1),
512 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
522 : "=D" (__res
), "=&c" (__d0
)
523 : "a" (__c
), "0" (__s
+ __n
- 1), "1" (__n
),
524 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
530 # define memrchr(s, c, n) __memrchr ((s), (c), (n))
534 /* Return pointer to C in S. */
535 # define _HAVE_STRING_ARCH_rawmemchr 1
536 __STRING_INLINE
void *__rawmemchr (const void *__s
, int __c
);
538 # ifndef _FORCE_INLINES
539 __STRING_INLINE
void *
540 __rawmemchr (const void *__s
, int __c
)
542 register unsigned long int __d0
;
543 register unsigned char *__res
;
547 : "=D" (__res
), "=&c" (__d0
)
548 : "a" (__c
), "0" (__s
), "1" (0xffffffff),
549 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
554 __STRING_INLINE
void *
555 rawmemchr (const void *__s
, int __c
)
557 return __rawmemchr (__s
, __c
);
559 # endif /* use GNU */
563 /* Return the length of S. */
564 # define _HAVE_STRING_ARCH_strlen 1
565 # define strlen(str) \
566 (__extension__ (__builtin_constant_p (str) \
567 ? __builtin_strlen (str) \
569 __STRING_INLINE
size_t __strlen_g (const char *__str
);
571 __STRING_INLINE
size_t
572 __strlen_g (const char *__str
)
574 register char __dummy
;
575 register const char *__tmp
= __str
;
582 : "=r" (__tmp
), "=&q" (__dummy
)
584 "m" ( *(struct { char __x
[0xfffffff]; } *)__str
)
586 return __tmp
- __str
- 1;
590 /* Copy SRC to DEST. */
591 # define _HAVE_STRING_ARCH_strcpy 1
592 # define strcpy(dest, src) \
593 (__extension__ (__builtin_constant_p (src) \
594 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
595 ? __strcpy_a_small ((dest), (src), strlen (src) + 1) \
596 : (char *) memcpy ((char *) (dest), \
597 (const char *) (src), \
599 : __strcpy_g ((dest), (src))))
601 # define __strcpy_a_small(dest, src, srclen) \
602 (__extension__ ({ char *__dest = (dest); \
605 unsigned short int __usi; \
606 unsigned char __uc; \
608 } *__u = (void *) __dest; \
615 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
618 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
619 __u = __extension__ ((void *) __u + 2); \
623 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
626 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
627 __u = __extension__ ((void *) __u + 4); \
631 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
632 __u = __extension__ ((void *) __u + 4); \
633 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
636 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
637 __u = __extension__ ((void *) __u + 4); \
638 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
639 __u = __extension__ ((void *) __u + 2); \
643 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
644 __u = __extension__ ((void *) __u + 4); \
645 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
650 __STRING_INLINE
char *__strcpy_g (char *__dest
, const char *__src
);
652 __STRING_INLINE
char *
653 __strcpy_g (char *__dest
, const char *__src
)
655 register char *__tmp
= __dest
;
656 register char __dummy
;
666 : "=&r" (__src
), "=&r" (__tmp
), "=&q" (__dummy
),
667 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
668 : "0" (__src
), "1" (__tmp
),
669 "m" ( *(struct { char __x
[0xfffffff]; } *)__src
)
676 # define _HAVE_STRING_ARCH_stpcpy 1
677 /* Copy SRC to DEST. */
678 # define __stpcpy(dest, src) \
679 (__extension__ (__builtin_constant_p (src) \
680 ? (strlen (src) + 1 <= 8 \
681 ? __stpcpy_a_small ((dest), (src), strlen (src) + 1) \
682 : __stpcpy_c ((dest), (src), strlen (src) + 1)) \
683 : __stpcpy_g ((dest), (src))))
684 # define __stpcpy_c(dest, src, srclen) \
686 ? __mempcpy_by4 (dest, src, srclen) - 1 \
687 : ((srclen) % 2 == 0 \
688 ? __mempcpy_by2 (dest, src, srclen) - 1 \
689 : __mempcpy_byn (dest, src, srclen) - 1))
691 /* In glibc itself we use this symbol for namespace reasons. */
692 # define stpcpy(dest, src) __stpcpy ((dest), (src))
694 # define __stpcpy_a_small(dest, src, srclen) \
695 (__extension__ ({ union { \
697 unsigned short int __usi; \
698 unsigned char __uc; \
700 } *__u = (void *) (dest); \
707 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
708 __u = __extension__ ((void *) __u + 1); \
711 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
712 __u = __extension__ ((void *) __u + 2); \
716 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
717 __u = __extension__ ((void *) __u + 3); \
720 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
721 __u = __extension__ ((void *) __u + 4); \
725 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
726 __u = __extension__ ((void *) __u + 4); \
727 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
728 __u = __extension__ ((void *) __u + 1); \
731 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
732 __u = __extension__ ((void *) __u + 4); \
733 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
734 __u = __extension__ ((void *) __u + 2); \
738 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
739 __u = __extension__ ((void *) __u + 4); \
740 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
741 __u = __extension__ ((void *) __u + 3); \
746 __STRING_INLINE
char *__mempcpy_by4 (char *__dest
, const char *__src
,
749 __STRING_INLINE
char *
750 __mempcpy_by4 (char *__dest
, const char *__src
, size_t __srclen
)
752 register char *__tmp
= __dest
;
753 register unsigned long int __d0
, __d1
;
762 : "=&r" (__d0
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
763 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 4)
768 __STRING_INLINE
char *__mempcpy_by2 (char *__dest
, const char *__src
,
771 __STRING_INLINE
char *
772 __mempcpy_by2 (char *__dest
, const char *__src
, size_t __srclen
)
774 register char *__tmp
= __dest
;
775 register unsigned long int __d0
, __d1
;
778 "jz 2f\n" /* only a word */
789 : "=&q" (__d0
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__d1
),
790 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
791 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 2),
792 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
797 __STRING_INLINE
char *__mempcpy_byn (char *__dest
, const char *__src
,
800 __STRING_INLINE
char *
801 __mempcpy_byn (char *__dest
, const char *__src
, size_t __srclen
)
803 register unsigned long __d0
, __d1
;
804 register char *__tmp
= __dest
;
816 : "=D" (__tmp
), "=&c" (__d0
), "=&S" (__d1
),
817 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
818 : "0" (__tmp
), "1" (__srclen
), "2" (__src
),
819 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
824 __STRING_INLINE
char *__stpcpy_g (char *__dest
, const char *__src
);
826 __STRING_INLINE
char *
827 __stpcpy_g (char *__dest
, const char *__src
)
829 register char *__tmp
= __dest
;
830 register char __dummy
;
840 : "=&r" (__src
), "=r" (__tmp
), "=&q" (__dummy
),
841 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
842 : "0" (__src
), "1" (__tmp
),
843 "m" ( *(struct { char __x
[0xfffffff]; } *)__src
)
850 /* Copy no more than N characters of SRC to DEST. */
851 # define _HAVE_STRING_ARCH_strncpy 1
852 # define strncpy(dest, src, n) \
853 (__extension__ (__builtin_constant_p (src) \
854 ? ((strlen (src) + 1 >= ((size_t) (n)) \
855 ? (char *) memcpy ((char *) (dest), \
856 (const char *) (src), n) \
857 : __strncpy_cg ((dest), (src), strlen (src) + 1, n))) \
858 : __strncpy_gg ((dest), (src), n)))
859 # define __strncpy_cg(dest, src, srclen, n) \
860 (((srclen) % 4 == 0) \
861 ? __strncpy_by4 (dest, src, srclen, n) \
862 : (((srclen) % 2 == 0) \
863 ? __strncpy_by2 (dest, src, srclen, n) \
864 : __strncpy_byn (dest, src, srclen, n)))
866 __STRING_INLINE
char *__strncpy_by4 (char *__dest
, const char __src
[],
867 size_t __srclen
, size_t __n
);
869 __STRING_INLINE
char *
870 __strncpy_by4 (char *__dest
, const char __src
[], size_t __srclen
, size_t __n
)
872 register char *__tmp
= __dest
;
873 register int __dummy1
, __dummy2
;
882 : "=&r" (__dummy1
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__dummy2
),
883 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
884 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 4),
885 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
887 (void) memset (__tmp
, '\0', __n
- __srclen
);
891 __STRING_INLINE
char *__strncpy_by2 (char *__dest
, const char __src
[],
892 size_t __srclen
, size_t __n
);
894 __STRING_INLINE
char *
895 __strncpy_by2 (char *__dest
, const char __src
[], size_t __srclen
, size_t __n
)
897 register char *__tmp
= __dest
;
898 register int __dummy1
, __dummy2
;
901 "jz 2f\n" /* only a word */
912 : "=&q" (__dummy1
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__dummy2
),
913 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
914 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 2),
915 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
917 (void) memset (__tmp
+ 2, '\0', __n
- __srclen
);
921 __STRING_INLINE
char *__strncpy_byn (char *__dest
, const char __src
[],
922 size_t __srclen
, size_t __n
);
924 __STRING_INLINE
char *
925 __strncpy_byn (char *__dest
, const char __src
[], size_t __srclen
, size_t __n
)
927 register unsigned long int __d0
, __d1
;
928 register char *__tmp
= __dest
;
940 : "=D" (__tmp
), "=&c" (__d0
), "=&S" (__d1
),
941 "=m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__dest
)
942 : "1" (__srclen
), "0" (__tmp
),"2" (__src
),
943 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
945 (void) memset (__tmp
, '\0', __n
- __srclen
);
949 __STRING_INLINE
char *__strncpy_gg (char *__dest
, const char *__src
,
952 __STRING_INLINE
char *
953 __strncpy_gg (char *__dest
, const char *__src
, size_t __n
)
955 register char *__tmp
= __dest
;
956 register char __dummy
;
974 : "=&r" (__src
), "=&r" (__tmp
), "=&q" (__dummy
), "=&r" (__n
)
975 : "0" (__src
), "1" (__tmp
), "3" (__n
)
982 /* Append SRC onto DEST. */
983 # define _HAVE_STRING_ARCH_strcat 1
984 # define strcat(dest, src) \
985 (__extension__ (__builtin_constant_p (src) \
986 ? __strcat_c ((dest), (src), strlen (src) + 1) \
987 : __strcat_g ((dest), (src))))
989 __STRING_INLINE
char *__strcat_c (char *__dest
, const char __src
[],
992 __STRING_INLINE
char *
993 __strcat_c (char *__dest
, const char __src
[], size_t __srclen
)
996 register unsigned long int __d0
;
997 register char *__tmp
;
1000 : "=D" (__tmp
), "=&c" (__d0
),
1001 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
1002 : "0" (__dest
), "1" (0xffffffff), "a" (0),
1003 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
1007 register char *__tmp
= __dest
;
1008 __asm__ __volatile__
1015 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
1017 "m" ( *(struct { __extension__
char __x
[__srclen
]; } *)__src
)
1020 (void) memcpy (__tmp
, __src
, __srclen
);
1024 __STRING_INLINE
char *__strcat_g (char *__dest
, const char *__src
);
1026 __STRING_INLINE
char *
1027 __strcat_g (char *__dest
, const char *__src
)
1029 register char *__tmp
= __dest
;
1030 register char __dummy
;
1031 __asm__ __volatile__
1044 : "=&q" (__dummy
), "=&r" (__tmp
), "=&r" (__src
),
1045 "=m" ( *(struct { char __x
[0xfffffff]; } *)__dest
)
1046 : "1" (__tmp
), "2" (__src
),
1047 "m" ( *(struct { char __x
[0xfffffff]; } *)__src
)
1053 /* Append no more than N characters from SRC onto DEST. */
1054 # define _HAVE_STRING_ARCH_strncat 1
1055 # define strncat(dest, src, n) \
1056 (__extension__ ({ char *__dest = (dest); \
1057 __builtin_constant_p (src) && __builtin_constant_p (n) \
1058 ? (strlen (src) < ((size_t) (n)) \
1059 ? strcat (__dest, (src)) \
1060 : (*(char *)__mempcpy (strchr (__dest, '\0'), \
1061 (const char *) (src), \
1062 (n)) = 0, __dest)) \
1063 : __strncat_g (__dest, (src), (n)); }))
1065 __STRING_INLINE
char *__strncat_g (char *__dest
, const char __src
[],
1068 __STRING_INLINE
char *
1069 __strncat_g (char *__dest
, const char __src
[], size_t __n
)
1071 register char *__tmp
= __dest
;
1072 register char __dummy
;
1074 __asm__ __volatile__
1088 : "=&a" (__dummy
), "=&D" (__tmp
), "=&S" (__src
), "=&c" (__n
)
1089 : "g" (__n
), "0" (0), "1" (__tmp
), "2" (__src
), "3" (0xffffffff)
1092 __asm__ __volatile__
1109 : "=&q" (__dummy
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__n
)
1110 : "1" ((unsigned long) __tmp
- 1), "2" (__src
), "3" (__n
)
1117 /* Compare S1 and S2. */
1118 # define _HAVE_STRING_ARCH_strcmp 1
1119 # define strcmp(s1, s2) \
1120 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1121 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1122 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1123 ? memcmp ((const char *) (s1), (const char *) (s2), \
1124 (strlen (s1) < strlen (s2) \
1125 ? strlen (s1) : strlen (s2)) + 1) \
1126 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1127 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1128 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1129 ? __strcmp_cc ((const unsigned char *) (s1), \
1130 (const unsigned char *) (s2), \
1132 : __strcmp_cg ((const unsigned char *) (s1), \
1133 (const unsigned char *) (s2), \
1135 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1136 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1137 ? (__builtin_constant_p (s1) \
1138 ? __strcmp_cc ((const unsigned char *) (s1), \
1139 (const unsigned char *) (s2), \
1141 : __strcmp_gc ((const unsigned char *) (s1), \
1142 (const unsigned char *) (s2), \
1144 : __strcmp_gg ((s1), (s2))))))
1146 # define __strcmp_cc(s1, s2, l) \
1147 (__extension__ ({ register int __result = (s1)[0] - (s2)[0]; \
1148 if (l > 0 && __result == 0) \
1150 __result = (s1)[1] - (s2)[1]; \
1151 if (l > 1 && __result == 0) \
1153 __result = (s1)[2] - (s2)[2]; \
1154 if (l > 2 && __result == 0) \
1155 __result = (s1)[3] - (s2)[3]; \
1160 # define __strcmp_cg(s1, s2, l1) \
1161 (__extension__ ({ const unsigned char *__s2 = (s2); \
1162 register int __result = (s1)[0] - __s2[0]; \
1163 if (l1 > 0 && __result == 0) \
1165 __result = (s1)[1] - __s2[1]; \
1166 if (l1 > 1 && __result == 0) \
1168 __result = (s1)[2] - __s2[2]; \
1169 if (l1 > 2 && __result == 0) \
1170 __result = (s1)[3] - __s2[3]; \
1175 # define __strcmp_gc(s1, s2, l2) \
1176 (__extension__ ({ const unsigned char *__s1 = (s1); \
1177 register int __result = __s1[0] - (s2)[0]; \
1178 if (l2 > 0 && __result == 0) \
1180 __result = __s1[1] - (s2)[1]; \
1181 if (l2 > 1 && __result == 0) \
1183 __result = __s1[2] - (s2)[2]; \
1184 if (l2 > 2 && __result == 0) \
1185 __result = __s1[3] - (s2)[3]; \
1190 __STRING_INLINE
int __strcmp_gg (const char *__s1
, const char *__s2
);
1193 __strcmp_gg (const char *__s1
, const char *__s2
)
1196 __asm__ __volatile__
1212 : "=q" (__res
), "=&r" (__s1
), "=&r" (__s2
)
1213 : "1" (__s1
), "2" (__s2
),
1214 "m" ( *(struct { char __x
[0xfffffff]; } *)__s1
),
1215 "m" ( *(struct { char __x
[0xfffffff]; } *)__s2
)
1221 /* Compare N characters of S1 and S2. */
1222 # define _HAVE_STRING_ARCH_strncmp 1
1223 # define strncmp(s1, s2, n) \
1224 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1225 ? strcmp ((s1), (s2)) \
1226 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1227 ? strcmp ((s1), (s2)) \
1228 : __strncmp_g ((s1), (s2), (n)))))
1230 __STRING_INLINE
int __strncmp_g (const char *__s1
, const char *__s2
,
1234 __strncmp_g (const char *__s1
, const char *__s2
, size_t __n
)
1237 __asm__ __volatile__
1256 : "=q" (__res
), "=&r" (__s1
), "=&r" (__s2
), "=&r" (__n
)
1257 : "1" (__s1
), "2" (__s2
), "3" (__n
),
1258 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s1
),
1259 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s2
)
1265 /* Find the first occurrence of C in S. */
1266 # define _HAVE_STRING_ARCH_strchr 1
1267 # define _USE_STRING_ARCH_strchr 1
1268 # define strchr(s, c) \
1269 (__extension__ (__builtin_constant_p (c) \
1271 ? (char *) __rawmemchr ((s), (c)) \
1272 : __strchr_c ((s), ((c) & 0xff) << 8)) \
1273 : __strchr_g ((s), (c))))
1275 __STRING_INLINE
char *__strchr_c (const char *__s
, int __c
);
1277 __STRING_INLINE
char *
1278 __strchr_c (const char *__s
, int __c
)
1280 register unsigned long int __d0
;
1281 register char *__res
;
1282 __asm__ __volatile__
1284 "movb (%0),%%al\n\t"
1285 "cmpb %%ah,%%al\n\t"
1288 "testb %%al,%%al\n\t"
1292 : "=r" (__res
), "=&a" (__d0
)
1293 : "0" (__s
), "1" (__c
),
1294 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1299 __STRING_INLINE
char *__strchr_g (const char *__s
, int __c
);
1301 __STRING_INLINE
char *
1302 __strchr_g (const char *__s
, int __c
)
1304 register unsigned long int __d0
;
1305 register char *__res
;
1306 __asm__ __volatile__
1309 "movb (%0),%%al\n\t"
1310 "cmpb %%ah,%%al\n\t"
1313 "testb %%al,%%al\n\t"
1317 : "=r" (__res
), "=&a" (__d0
)
1318 : "0" (__s
), "1" (__c
),
1319 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1325 /* Find the first occurrence of C in S or the final NUL byte. */
1326 # define _HAVE_STRING_ARCH_strchrnul 1
1327 # define __strchrnul(s, c) \
1328 (__extension__ (__builtin_constant_p (c) \
1330 ? (char *) __rawmemchr ((s), c) \
1331 : __strchrnul_c ((s), ((c) & 0xff) << 8)) \
1332 : __strchrnul_g ((s), c)))
1334 __STRING_INLINE
char *__strchrnul_c (const char *__s
, int __c
);
1336 __STRING_INLINE
char *
1337 __strchrnul_c (const char *__s
, int __c
)
1339 register unsigned long int __d0
;
1340 register char *__res
;
1341 __asm__ __volatile__
1343 "movb (%0),%%al\n\t"
1344 "cmpb %%ah,%%al\n\t"
1347 "testb %%al,%%al\n\t"
1351 : "=r" (__res
), "=&a" (__d0
)
1352 : "0" (__s
), "1" (__c
),
1353 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1358 __STRING_INLINE
char *__strchrnul_g (const char *__s
, int __c
);
1360 __STRING_INLINE
char *
1361 __strchrnul_g (const char *__s
, int __c
)
1363 register unsigned long int __d0
;
1364 register char *__res
;
1365 __asm__ __volatile__
1368 "movb (%0),%%al\n\t"
1369 "cmpb %%ah,%%al\n\t"
1372 "testb %%al,%%al\n\t"
1376 : "=r" (__res
), "=&a" (__d0
)
1377 : "0" (__s
), "1" (__c
),
1378 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1383 # define strchrnul(s, c) __strchrnul ((s), (c))
1387 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1388 /* Find the first occurrence of C in S. This is the BSD name. */
1389 # define _HAVE_STRING_ARCH_index 1
1390 # define index(s, c) \
1391 (__extension__ (__builtin_constant_p (c) \
1392 ? __strchr_c ((s), ((c) & 0xff) << 8) \
1393 : __strchr_g ((s), (c))))
1397 /* Find the last occurrence of C in S. */
1398 # define _HAVE_STRING_ARCH_strrchr 1
1399 # define strrchr(s, c) \
1400 (__extension__ (__builtin_constant_p (c) \
1401 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1402 : __strrchr_g ((s), (c))))
1405 __STRING_INLINE
char *__strrchr_c (const char *__s
, int __c
);
1407 __STRING_INLINE
char *
1408 __strrchr_c (const char *__s
, int __c
)
1410 register unsigned long int __d0
, __d1
;
1411 register char *__res
;
1412 __asm__ __volatile__
1420 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1421 : "0" (1), "1" (__s
), "2" (__c
),
1422 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1427 __STRING_INLINE
char *__strrchr_g (const char *__s
, int __c
);
1429 __STRING_INLINE
char *
1430 __strrchr_g (const char *__s
, int __c
)
1432 register unsigned long int __d0
, __d1
;
1433 register char *__res
;
1434 __asm__ __volatile__
1443 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1444 : "0" (1), "1" (__s
), "2" (__c
),
1445 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1450 __STRING_INLINE
char *__strrchr_c (const char *__s
, int __c
);
1452 __STRING_INLINE
char *
1453 __strrchr_c (const char *__s
, int __c
)
1455 register unsigned long int __d0
, __d1
;
1456 register char *__res
;
1457 __asm__ __volatile__
1461 "cmpb %%ah,%%al\n\t"
1463 "leal -1(%%esi),%0\n"
1465 "testb %%al,%%al\n\t"
1467 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1468 : "0" (0), "1" (__s
), "2" (__c
),
1469 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1474 __STRING_INLINE
char *__strrchr_g (const char *__s
, int __c
);
1476 __STRING_INLINE
char *
1477 __strrchr_g (const char *__s
, int __c
)
1479 register unsigned long int __d0
, __d1
;
1480 register char *__res
;
1481 __asm__ __volatile__
1486 "cmpb %%ah,%%al\n\t"
1488 "leal -1(%%esi),%0\n"
1490 "testb %%al,%%al\n\t"
1492 : "=r" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1493 : "0" (0), "1" (__s
), "2" (__c
),
1494 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1501 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1502 /* Find the last occurrence of C in S. This is the BSD name. */
1503 # define _HAVE_STRING_ARCH_rindex 1
1504 # define rindex(s, c) \
1505 (__extension__ (__builtin_constant_p (c) \
1506 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1507 : __strrchr_g ((s), (c))))
1511 /* Return the length of the initial segment of S which
1512 consists entirely of characters not in REJECT. */
1513 # define _HAVE_STRING_ARCH_strcspn 1
1514 # define strcspn(s, reject) \
1515 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1516 ? ((reject)[0] == '\0' \
1518 : ((reject)[1] == '\0' \
1519 ? __strcspn_c1 ((s), (((reject)[0] << 8) & 0xff00)) \
1520 : __strcspn_cg ((s), (reject), strlen (reject)))) \
1521 : __strcspn_g ((s), (reject))))
1523 __STRING_INLINE
size_t __strcspn_c1 (const char *__s
, int __reject
);
1525 # ifndef _FORCE_INLINES
1526 __STRING_INLINE
size_t
1527 __strcspn_c1 (const char *__s
, int __reject
)
1529 register unsigned long int __d0
;
1530 register char *__res
;
1531 __asm__ __volatile__
1533 "movb (%0),%%al\n\t"
1535 "cmpb %%ah,%%al\n\t"
1537 "testb %%al,%%al\n\t"
1540 : "=r" (__res
), "=&a" (__d0
)
1541 : "0" (__s
), "1" (__reject
),
1542 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1544 return (__res
- 1) - __s
;
1548 __STRING_INLINE
size_t __strcspn_cg (const char *__s
, const char __reject
[],
1549 size_t __reject_len
);
1551 __STRING_INLINE
size_t
1552 __strcspn_cg (const char *__s
, const char __reject
[], size_t __reject_len
)
1554 register unsigned long int __d0
, __d1
, __d2
;
1555 register const char *__res
;
1556 __asm__ __volatile__
1560 "testb %%al,%%al\n\t"
1567 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1568 : "0" (__s
), "d" (__reject
), "g" (__reject_len
)
1570 return (__res
- 1) - __s
;
1573 __STRING_INLINE
size_t __strcspn_g (const char *__s
, const char *__reject
);
1576 __STRING_INLINE
size_t
1577 __strcspn_g (const char *__s
, const char *__reject
)
1579 register unsigned long int __d0
, __d1
, __d2
;
1580 register const char *__res
;
1581 __asm__ __volatile__
1587 "leal -1(%%ecx),%%ebx\n"
1590 "testb %%al,%%al\n\t"
1593 "movl %%ebx,%%ecx\n\t"
1598 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1599 : "r" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff)
1601 return (__res
- 1) - __s
;
1604 __STRING_INLINE
size_t
1605 __strcspn_g (const char *__s
, const char *__reject
)
1607 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1608 register const char *__res
;
1609 __asm__ __volatile__
1613 "leal -1(%%ecx),%%edx\n"
1616 "testb %%al,%%al\n\t"
1618 "movl %%ebx,%%edi\n\t"
1619 "movl %%edx,%%ecx\n\t"
1623 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1624 : "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__reject
), "b" (__reject
)
1625 /* Clobber memory, otherwise GCC cannot handle this. */
1627 return (__res
- 1) - __s
;
1632 /* Return the length of the initial segment of S which
1633 consists entirely of characters in ACCEPT. */
1634 # define _HAVE_STRING_ARCH_strspn 1
1635 # define strspn(s, accept) \
1636 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1637 ? ((accept)[0] == '\0' \
1639 : ((accept)[1] == '\0' \
1640 ? __strspn_c1 ((s), (((accept)[0] << 8 ) & 0xff00)) \
1641 : __strspn_cg ((s), (accept), strlen (accept)))) \
1642 : __strspn_g ((s), (accept))))
1644 # ifndef _FORCE_INLINES
1645 __STRING_INLINE
size_t __strspn_c1 (const char *__s
, int __accept
);
1647 __STRING_INLINE
size_t
1648 __strspn_c1 (const char *__s
, int __accept
)
1650 register unsigned long int __d0
;
1651 register char *__res
;
1652 /* Please note that __accept never can be '\0'. */
1653 __asm__ __volatile__
1659 : "=r" (__res
), "=&q" (__d0
)
1660 : "0" (__s
), "1" (__accept
),
1661 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
1663 return (__res
- 1) - __s
;
1667 __STRING_INLINE
size_t __strspn_cg (const char *__s
, const char __accept
[],
1668 size_t __accept_len
);
1670 __STRING_INLINE
size_t
1671 __strspn_cg (const char *__s
, const char __accept
[], size_t __accept_len
)
1673 register unsigned long int __d0
, __d1
, __d2
;
1674 register const char *__res
;
1675 __asm__ __volatile__
1679 "testb %%al,%%al\n\t"
1686 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1687 : "0" (__s
), "g" (__accept
), "g" (__accept_len
),
1688 /* Since we do not know how large the memory we access it, use a
1689 really large amount. */
1690 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
),
1691 "m" ( *(struct { __extension__
char __x
[__accept_len
]; } *)__accept
)
1693 return (__res
- 1) - __s
;
1696 __STRING_INLINE
size_t __strspn_g (const char *__s
, const char *__accept
);
1699 __STRING_INLINE
size_t
1700 __strspn_g (const char *__s
, const char *__accept
)
1702 register unsigned long int __d0
, __d1
, __d2
;
1703 register const char *__res
;
1704 __asm__ __volatile__
1709 "leal -1(%%ecx),%%ebx\n"
1712 "testb %%al,%%al\n\t"
1714 "movl %%edx,%%edi\n\t"
1715 "movl %%ebx,%%ecx\n\t"
1720 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1721 : "d" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__accept
)
1723 return (__res
- 1) - __s
;
1726 __STRING_INLINE
size_t
1727 __strspn_g (const char *__s
, const char *__accept
)
1729 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1730 register const char *__res
;
1731 __asm__ __volatile__
1735 "leal -1(%%ecx),%%edx\n"
1738 "testb %%al,%%al\n\t"
1740 "movl %%ebx,%%edi\n\t"
1741 "movl %%edx,%%ecx\n\t"
1745 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1746 : "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__accept
), "b" (__accept
)
1748 return (__res
- 1) - __s
;
1753 /* Find the first occurrence in S of any character in ACCEPT. */
1754 # define _HAVE_STRING_ARCH_strpbrk 1
1755 # define strpbrk(s, accept) \
1756 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1757 ? ((accept)[0] == '\0' \
1758 ? ((void) (s), (char *) 0) \
1759 : ((accept)[1] == '\0' \
1760 ? strchr ((s), (accept)[0]) \
1761 : __strpbrk_cg ((s), (accept), strlen (accept)))) \
1762 : __strpbrk_g ((s), (accept))))
1764 __STRING_INLINE
char *__strpbrk_cg (const char *__s
, const char __accept
[],
1765 size_t __accept_len
);
1767 __STRING_INLINE
char *
1768 __strpbrk_cg (const char *__s
, const char __accept
[], size_t __accept_len
)
1770 register unsigned long int __d0
, __d1
, __d2
;
1771 register char *__res
;
1772 __asm__ __volatile__
1776 "testb %%al,%%al\n\t"
1787 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1788 : "0" (__s
), "d" (__accept
), "g" (__accept_len
)
1793 __STRING_INLINE
char *__strpbrk_g (const char *__s
, const char *__accept
);
1796 __STRING_INLINE
char *
1797 __strpbrk_g (const char *__s
, const char *__accept
)
1799 register unsigned long int __d0
, __d1
, __d2
;
1800 register char *__res
;
1801 __asm__ __volatile__
1803 "movl %%edx,%%edi\n\t"
1807 "leal -1(%%ecx),%%ebx\n"
1810 "testb %%al,%%al\n\t"
1812 "movl %%edx,%%edi\n\t"
1813 "movl %%ebx,%%ecx\n\t"
1822 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1823 : "d" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
1828 __STRING_INLINE
char *
1829 __strpbrk_g (const char *__s
, const char *__accept
)
1831 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1832 register char *__res
;
1833 __asm__ __volatile__
1834 ("movl %%ebx,%%edi\n\t"
1838 "leal -1(%%ecx),%%edx\n"
1841 "testb %%al,%%al\n\t"
1843 "movl %%ebx,%%edi\n\t"
1844 "movl %%edx,%%ecx\n\t"
1852 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
1853 : "0" (__s
), "1" (0), "2" (0xffffffff), "b" (__accept
)
1860 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1861 # define _HAVE_STRING_ARCH_strstr 1
1862 # define strstr(haystack, needle) \
1863 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1864 ? ((needle)[0] == '\0' \
1866 : ((needle)[1] == '\0' \
1867 ? strchr ((haystack), (needle)[0]) \
1868 : __strstr_cg ((haystack), (needle), \
1869 strlen (needle)))) \
1870 : __strstr_g ((haystack), (needle))))
1872 /* Please note that this function need not handle NEEDLEs with a
1873 length shorter than two. */
1874 __STRING_INLINE
char *__strstr_cg (const char *__haystack
,
1875 const char __needle
[],
1876 size_t __needle_len
);
1878 __STRING_INLINE
char *
1879 __strstr_cg (const char *__haystack
, const char __needle
[],
1880 size_t __needle_len
)
1882 register unsigned long int __d0
, __d1
, __d2
;
1883 register char *__res
;
1884 __asm__ __volatile__
1892 "cmpb $0,-1(%%esi)\n\t"
1893 "leal 1(%%eax),%5\n\t"
1895 "xorl %%eax,%%eax\n"
1897 : "=&a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
1898 : "g" (__needle_len
), "1" (__haystack
), "d" (__needle
)
1903 __STRING_INLINE
char *__strstr_g (const char *__haystack
,
1904 const char *__needle
);
1907 __STRING_INLINE
char *
1908 __strstr_g (const char *__haystack
, const char *__needle
)
1910 register unsigned long int __d0
, __d1
, __d2
;
1911 register char *__res
;
1912 __asm__ __volatile__
1917 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1918 "movl %%ecx,%%ebx\n"
1920 "movl %%edx,%%edi\n\t"
1921 "movl %%esi,%%eax\n\t"
1922 "movl %%ebx,%%ecx\n\t"
1924 "je 2f\n\t" /* also works for empty string, see above */
1925 "cmpb $0,-1(%%esi)\n\t"
1926 "leal 1(%%eax),%%esi\n\t"
1928 "xorl %%eax,%%eax\n"
1931 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
1932 : "0" (0), "1" (0xffffffff), "2" (__haystack
), "3" (__needle
),
1938 __STRING_INLINE
char *
1939 __strstr_g (const char *__haystack
, const char *__needle
)
1941 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1942 register char *__res
;
1943 __asm__ __volatile__
1947 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1948 "movl %%ecx,%%edx\n"
1950 "movl %%ebx,%%edi\n\t"
1951 "movl %%esi,%%eax\n\t"
1952 "movl %%edx,%%ecx\n\t"
1954 "je 2f\n\t" /* also works for empty string, see above */
1955 "cmpb $0,-1(%%esi)\n\t"
1956 "leal 1(%%eax),%%esi\n\t"
1958 "xorl %%eax,%%eax\n"
1960 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1961 : "0" (0), "1" (0xffffffff), "2" (__haystack
), "3" (__needle
),
1969 /* Bit find functions. We define only the i686 version since for the other
1970 processors gcc generates good code. */
1971 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1973 # define _HAVE_STRING_ARCH_ffs 1
1974 # define ffs(word) (__builtin_constant_p (word) \
1975 ? __builtin_ffs (word) \
1976 : ({ int __cnt, __tmp; \
1977 __asm__ __volatile__ \
1980 : "=&r" (__cnt), "=r" (__tmp) \
1981 : "rm" (word), "1" (-1)); \
1985 # define ffsl(word) ffs(word)
1988 # endif /* Misc || X/Open */
1990 # ifndef _FORCE_INLINES
1991 # undef __STRING_INLINE
1994 # endif /* use string inlines && GNU CC */