1 /* Optimized, inlined string functions. i486 version.
2 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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.
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.
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. */
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
24 /* The ix86 processors can access unaligned multi-byte variables. */
25 #define _STRING_ARCH_unaligned 1
28 /* We only provide optimizations if the user selects them and if
30 #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
31 && defined __GNUC__ && __GNUC__ >= 2
33 #ifndef __STRING_INLINE
35 # define __STRING_INLINE inline
37 # define __STRING_INLINE extern __inline
41 /* The macros are used in some of the optimized implementations below. */
42 #define __STRING_SMALL_GET16(src, idx) \
43 (((src)[idx + 1] << 8) | (src)[idx])
44 #define __STRING_SMALL_GET32(src, idx) \
45 ((((src)[idx + 3] << 8 | (src)[idx + 2]) << 8 \
46 | (src)[idx + 1]) << 8 | (src)[idx])
49 /* Copy N bytes of SRC to DEST. */
50 #define _HAVE_STRING_ARCH_memcpy 1
51 #define memcpy(dest, src, n) \
52 (__extension__ (__builtin_constant_p (n) \
53 ? __memcpy_c (dest, src, n) \
54 : __memcpy_g (dest, src, n)))
55 #define __memcpy_c(dest, src, n) \
59 ? __memcpy_by4 (dest, src, n) \
61 ? __memcpy_by2 (dest, src, n) \
62 : __memcpy_g (dest, src, n))))
64 __STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src,
67 __STRING_INLINE void *
68 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
70 register unsigned long int __d0, __d1;
71 register void *__tmp = __dest;
80 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
81 : "1" (__tmp), "2" (__src), "3" (__n / 4)
86 __STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src,
89 __STRING_INLINE void *
90 __memcpy_by2 (void *__dest, __const void *__src, size_t __n)
92 register unsigned long int __d0, __d1;
93 register void *__tmp = __dest;
96 "jz 2f\n" /* only a word */
107 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
108 : "1" (__tmp), "2" (__src), "3" (__n / 2)
113 __STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src,
116 __STRING_INLINE void *
117 __memcpy_g (void *__dest, __const void *__src, size_t __n)
119 register unsigned long int __d0, __d1, __d2;
120 register void *__tmp = __dest;
132 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
133 : "0" (__n), "1" (__tmp), "2" (__src)
138 #define _HAVE_STRING_ARCH_memmove 1
139 #ifndef _FORCE_INLINES
140 /* Copy N bytes of SRC to DEST, guaranteeing
141 correct behavior for overlapping strings. */
142 __STRING_INLINE void *
143 memmove (void *__dest, __const void *__src, size_t __n)
145 register unsigned long int __d0, __d1, __d2;
146 register void *__tmp = __dest;
151 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
152 : "0" (__n), "1" (__src), "2" (__tmp)
159 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
160 : "0" (__n), "1" (__n - 1 + (__const char *) __src),
161 "2" (__n - 1 + (char *) __tmp)
167 /* Compare N bytes of S1 and S2. */
168 #define _HAVE_STRING_ARCH_memcmp 1
169 #ifndef _FORCE_INLINES
171 /* gcc has problems to spill registers when using PIC. */
173 memcmp (__const void *__s1, __const void *__s2, size_t __n)
175 register unsigned long int __d0, __d1, __d2;
185 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
186 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n)
193 /* Set N bytes of S to C. */
194 #define _HAVE_STRING_ARCH_memset 1
195 #define memset(s, c, n) \
196 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
198 ? __memset_c1 (s, c) \
199 : __memset_gc (s, c, n)) \
200 : (__builtin_constant_p (c) \
201 ? (__builtin_constant_p (n) \
202 ? __memset_ccn (s, c, n) \
203 : memset (s, c, n)) \
204 : (__builtin_constant_p (n) \
205 ? __memset_gcn (s, c, n) \
206 : memset (s, c, n)))))
208 #define __memset_c1(s, c) ({ void *__s = (s); \
209 *((unsigned char *) __s) = (unsigned char) (c); \
212 #define __memset_gc(s, c, n) \
213 ({ void *__s = (s); \
216 unsigned short int __usi; \
217 unsigned char __uc; \
219 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
221 /* We apply a trick here. `gcc' would implement the following \
222 assignments using immediate operands. But this uses to much \
223 memory (7, instead of 4 bytes). So we force the value in a \
225 if (n == 3 || n >= 5) \
226 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
228 /* This `switch' statement will be removed at compile-time. */ \
233 __u = __extension__ ((void *) __u + 4); \
236 __u = __extension__ ((void *) __u + 4); \
239 __u = __extension__ ((void *) __u + 4); \
241 __u->__usi = (unsigned short int) __c; \
242 __u = __extension__ ((void *) __u + 2); \
243 __u->__uc = (unsigned char) __c; \
248 __u = __extension__ ((void *) __u + 4); \
251 __u = __extension__ ((void *) __u + 4); \
254 __u = __extension__ ((void *) __u + 4); \
256 __u->__usi = (unsigned short int) __c; \
261 __u = __extension__ ((void *) __u + 4); \
264 __u = __extension__ ((void *) __u + 4); \
267 __u = __extension__ ((void *) __u + 4); \
269 __u->__uc = (unsigned char) __c; \
274 __u = __extension__ ((void *) __u + 4); \
277 __u = __extension__ ((void *) __u + 4); \
280 __u = __extension__ ((void *) __u + 4); \
289 #define __memset_ccn(s, c, n) \
291 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
294 ? __memset_ccn_by2 (s, \
295 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
299 __STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
302 __STRING_INLINE void *
303 __memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
305 register void *__tmp = __s;
306 register unsigned long int __d0;
311 : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0)
312 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
321 : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0)
322 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
328 __STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
331 __STRING_INLINE void *
332 __memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
334 register unsigned long int __d0, __d1;
335 register void *__tmp = __s;
341 : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1)
342 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
346 ("1:\tmovl %0,(%1)\n\t"
351 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
352 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
358 #define __memset_gcn(s, c, n) \
360 ? __memset_gcn_by4 (s, c, n) \
362 ? __memset_gcn_by2 (s, c, n) \
365 __STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
367 __STRING_INLINE void *
368 __memset_gcn_by4 (void *__s, int __c, size_t __n)
370 register void *__tmp = __s;
371 register unsigned long int __d0;
382 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0)
383 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
388 __STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
390 __STRING_INLINE void *
391 __memset_gcn_by2 (void *__s, int __c, size_t __n)
393 register unsigned long int __d0, __d1;
394 register void *__tmp = __s;
406 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
407 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
413 /* Search N bytes of S for C. */
414 #define _HAVE_STRING_ARCH_memchr 1
415 #ifndef _FORCE_INLINES
416 __STRING_INLINE void *
417 memchr (__const void *__s, int __c, size_t __n)
419 register unsigned long int __d0;
421 register unsigned long int __d1;
423 register unsigned char *__res;
431 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
432 : "a" (__c), "0" (__s), "1" (__n), "2" (1)
441 : "=D" (__res), "=&c" (__d0)
442 : "a" (__c), "0" (__s), "1" (__n)
449 #define _HAVE_STRING_ARCH_memrchr 1
450 #ifndef _FORCE_INLINES
451 __STRING_INLINE void *
452 __memrchr (__const void *__s, int __c, size_t __n)
454 register unsigned long int __d0;
456 register unsigned long int __d1;
458 register void *__res;
467 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
468 : "a" (__c), "0" (__s), "1" (__n), "2" (1)
477 : "=D" (__res), "=&c" (__d0)
478 : "a" (__c), "0" (__s), "1" (__n)
485 /* Return pointer to C in S. */
486 #define _HAVE_STRING_ARCH_rawmemchr 1
487 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
489 #ifndef _FORCE_INLINES
490 __STRING_INLINE void *
491 __rawmemchr (const void *__s, int __c)
493 register unsigned long int __d0;
494 register unsigned char *__res;
498 : "=D" (__res), "=&c" (__d0)
499 : "a" (__c), "0" (__s), "1" (0xffffffff)
504 __STRING_INLINE void *
505 rawmemchr (const void *__s, int __c)
507 return __rawmemchr (__s, __c);
509 # endif /* use GNU */
513 /* Return the length of S. */
514 #define _HAVE_STRING_ARCH_strlen 1
515 #define strlen(str) \
516 (__extension__ (__builtin_constant_p (str) \
517 ? __builtin_strlen (str) \
519 __STRING_INLINE size_t __strlen_g (__const char *__str);
521 __STRING_INLINE size_t
522 __strlen_g (__const char *__str)
524 register char __dummy;
525 register __const char *__tmp = __str;
532 : "=r" (__tmp), "=&q" (__dummy)
535 return __tmp - __str - 1;
539 /* Copy SRC to DEST. */
540 #define _HAVE_STRING_ARCH_strcpy 1
541 #define strcpy(dest, src) \
542 (__extension__ (__builtin_constant_p (src) \
543 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
544 ? __strcpy_small (dest, src, strlen (src) + 1) \
545 : (char *) memcpy ((char *) dest, \
546 (__const char *) src, \
548 : __strcpy_g (dest, src)))
550 #define __strcpy_small(dest, src, srclen) \
551 (__extension__ ({ char *__dest = (dest); \
554 unsigned short int __usi; \
555 unsigned char __uc; \
557 } *__u = (void *) __dest; \
564 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
567 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
568 __u = __extension__ ((void *) __u + 2); \
572 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
575 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
576 __u = __extension__ ((void *) __u + 4); \
580 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
581 __u = __extension__ ((void *) __u + 4); \
582 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
585 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
586 __u = __extension__ ((void *) __u + 4); \
587 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
588 __u = __extension__ ((void *) __u + 2); \
592 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
593 __u = __extension__ ((void *) __u + 4); \
594 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
599 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
601 __STRING_INLINE char *
602 __strcpy_g (char *__dest, __const char *__src)
604 register char *__tmp = __dest;
605 register char __dummy;
615 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
616 : "0" (__src), "1" (__tmp)
623 # define _HAVE_STRING_ARCH_stpcpy 1
624 /* Copy SRC to DEST. */
625 # define __stpcpy(dest, src) \
626 (__extension__ (__builtin_constant_p (src) \
627 ? (strlen (src) + 1 <= 8 \
628 ? __stpcpy_small (dest, src, strlen (src) + 1) \
629 : __stpcpy_c (dest, src, strlen (src) + 1)) \
630 : __stpcpy_g (dest, src)))
631 # define __stpcpy_c(dest, src, srclen) \
633 ? __mempcpy_by4 (dest, src, srclen) - 1 \
634 : ((srclen) % 2 == 0 \
635 ? __mempcpy_by2 (dest, src, srclen) - 1 \
636 : __mempcpy_byn (dest, src, srclen) - 1))
638 /* In glibc itself we use this symbol for namespace reasons. */
639 # define stpcpy(dest, src) __stpcpy (dest, src)
641 # define __stpcpy_small(dest, src, srclen) \
642 (__extension__ ({ union { \
644 unsigned short int __usi; \
645 unsigned char __uc; \
647 } *__u = (void *) (dest); \
654 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
655 __u = __extension__ ((void *) __u + 1); \
658 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
659 __u = __extension__ ((void *) __u + 2); \
663 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
664 __u = __extension__ ((void *) __u + 3); \
667 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
668 __u = __extension__ ((void *) __u + 4); \
672 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
673 __u = __extension__ ((void *) __u + 4); \
674 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
675 __u = __extension__ ((void *) __u + 1); \
678 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
679 __u = __extension__ ((void *) __u + 4); \
680 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
681 __u = __extension__ ((void *) __u + 2); \
685 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
686 __u = __extension__ ((void *) __u + 4); \
687 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
688 __u = __extension__ ((void *) __u + 3); \
693 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
696 __STRING_INLINE char *
697 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
699 register char *__tmp = __dest;
700 register unsigned long int __d0, __d1;
709 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
710 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
715 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
718 __STRING_INLINE char *
719 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
721 register char *__tmp = __dest;
722 register unsigned long int __d0, __d1;
725 "jz 2f\n" /* only a word */
736 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
737 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
742 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
745 __STRING_INLINE char *
746 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
748 register unsigned long __d0, __d1;
749 register char *__tmp = __dest;
761 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
762 : "0" (__tmp), "1" (__srclen), "2" (__src)
767 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
769 __STRING_INLINE char *
770 __stpcpy_g (char *__dest, __const char *__src)
772 register char *__tmp = __dest;
773 register char __dummy;
783 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
784 : "0" (__src), "1" (__tmp)
791 /* Copy no more than N characters of SRC to DEST. */
792 #define _HAVE_STRING_ARCH_strncpy 1
793 #define strncpy(dest, src, n) \
794 (__extension__ (__builtin_constant_p (src) \
795 ? ((strlen (src) + 1 >= ((size_t) (n)) \
796 ? (char *) memcpy ((char *) dest, \
797 (__const char *) src, n) \
798 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
799 : __strncpy_gg (dest, src, n)))
800 #define __strncpy_cg(dest, src, srclen, n) \
801 (((srclen) % 4 == 0) \
802 ? __strncpy_by4 (dest, src, srclen, n) \
803 : (((srclen) % 2 == 0) \
804 ? __strncpy_by2 (dest, src, srclen, n) \
805 : __strncpy_byn (dest, src, srclen, n)))
807 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
808 size_t __srclen, size_t __n);
810 __STRING_INLINE char *
811 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
813 register char *__tmp = __dest;
814 register int __dummy1, __dummy2;
823 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
824 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
826 (void) memset (__tmp, '\0', __n - __srclen);
830 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
831 size_t __srclen, size_t __n);
833 __STRING_INLINE char *
834 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
836 register char *__tmp = __dest;
837 register int __dummy1, __dummy2;
840 "jz 2f\n" /* only a word */
851 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
852 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
854 (void) memset (__tmp + 2, '\0', __n - __srclen);
858 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
859 size_t __srclen, size_t __n);
861 __STRING_INLINE char *
862 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
864 register unsigned long int __d0, __d1;
865 register char *__tmp = __dest;
877 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
878 : "1" (__srclen), "0" (__tmp),"2" (__src)
880 (void) memset (__tmp, '\0', __n - __srclen);
884 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
887 __STRING_INLINE char *
888 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
890 register char *__tmp = __dest;
891 register char __dummy;
909 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
910 : "0" (__src), "1" (__tmp), "3" (__n)
917 /* Append SRC onto DEST. */
918 #define _HAVE_STRING_ARCH_strcat 1
919 #define strcat(dest, src) \
920 (__extension__ (__builtin_constant_p (src) \
921 ? __strcat_c (dest, src, strlen (src) + 1) \
922 : __strcat_g (dest, src)))
924 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
927 __STRING_INLINE char *
928 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
931 register unsigned long int __d0;
932 register char *__tmp;
935 : "=D" (__tmp), "=&c" (__d0)
936 : "0" (__dest), "1" (0xffffffff), "a" (0)
940 register char *__tmp = __dest - 1;
950 (void) memcpy (__tmp, __src, __srclen);
954 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
956 __STRING_INLINE char *
957 __strcat_g (char *__dest, __const char *__src)
959 register char *__tmp = __dest - 1;
960 register char __dummy;
973 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
974 : "1" (__tmp), "2" (__src)
980 /* Append no more than N characters from SRC onto DEST. */
981 #define _HAVE_STRING_ARCH_strncat 1
982 #define strncat(dest, src, n) \
983 (__extension__ ({ char *__dest = (dest); \
984 __builtin_constant_p (src) && __builtin_constant_p (n) \
985 ? (strlen (src) < ((size_t) (n)) \
986 ? strcat (__dest, src) \
987 : (memcpy (strchr (__dest, '\0'), \
988 (__const char *) src, n), __dest)) \
989 : __strncat_g (__dest, src, n); }))
991 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
994 __STRING_INLINE char *
995 __strncat_g (char *__dest, __const char __src[], size_t __n)
997 register char *__tmp = __dest;
998 register char __dummy;
1000 __asm__ __volatile__
1013 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
1014 : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
1018 __asm__ __volatile__
1035 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1036 : "1" (__tmp), "2" (__src), "3" (__n)
1043 /* Compare S1 and S2. */
1044 #define _HAVE_STRING_ARCH_strcmp 1
1045 #define strcmp(s1, s2) \
1046 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1047 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1048 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1049 ? memcmp ((__const char *) s1, (__const char *) s2, \
1050 (strlen (s1) < strlen (s2) \
1051 ? strlen (s1) : strlen (s2)) + 1) \
1052 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1053 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1054 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1055 ? __strcmp_cc (s1, s2, strlen (s1)) \
1056 : __strcmp_cg (s1, s2, strlen (s1))) \
1057 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1058 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1059 ? (__builtin_constant_p (s1) \
1060 ? __strcmp_cc (s1, s2, strlen (s2)) \
1061 : __strcmp_gc (s1, s2, strlen (s2))) \
1062 : __strcmp_gg (s1, s2)))))
1064 #define __strcmp_cc(s1, s2, l) \
1065 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
1066 - (unsigned char) (s2)[0]); \
1067 if (l > 0 && __result == 0) \
1069 __result = ((unsigned char) (s1)[1] \
1070 - (unsigned char) (s2)[1]); \
1071 if (l > 1 && __result == 0) \
1073 __result = ((unsigned char) (s1)[2] \
1074 - (unsigned char) (s2)[2]); \
1075 if (l > 2 && __result == 0) \
1076 __result = ((unsigned char) (s1)[3] \
1077 - (unsigned char) (s2)[3]); \
1082 #define __strcmp_cg(s1, s2, l1) \
1083 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
1084 register int __result = (unsigned char) (s1)[0] - __s2[0];\
1085 if (l1 > 0 && __result == 0) \
1087 __result = (unsigned char) (s1)[1] - __s2[1]; \
1088 if (l1 > 1 && __result == 0) \
1090 __result = (unsigned char) (s1)[2] - __s2[2]; \
1091 if (l1 > 2 && __result == 0) \
1092 __result = (unsigned char) (s1)[3] - __s2[3]; \
1097 #define __strcmp_gc(s1, s2, l2) \
1098 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
1099 register int __result = __s1[0] - (unsigned char) (s2)[0];\
1100 if (l2 > 0 && __result == 0) \
1102 __result = __s1[1] - (unsigned char) (s2)[1]; \
1103 if (l2 > 1 && __result == 0) \
1105 __result = __s1[2] - (unsigned char) (s2)[2]; \
1106 if (l2 > 2 && __result == 0) \
1107 __result = __s1[3] - (unsigned char) (s2)[3]; \
1112 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
1115 __strcmp_gg (__const char *__s1, __const char *__s2)
1118 __asm__ __volatile__
1134 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1135 : "1" (__s1), "2" (__s2)
1141 /* Compare N characters of S1 and S2. */
1142 #define _HAVE_STRING_ARCH_strncmp 1
1143 #define strncmp(s1, s2, n) \
1144 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1146 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1148 : __strncmp_g (s1, s2, n))))
1150 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1154 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1157 __asm__ __volatile__
1176 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1177 : "1" (__s1), "2" (__s2), "3" (__n)
1183 /* Find the first occurrence of C in S. */
1184 #define _HAVE_STRING_ARCH_strchr 1
1185 #define strchr(s, c) \
1186 (__extension__ (__builtin_constant_p (c) \
1188 ? (char *) __rawmemchr (s, c) \
1189 : __strchr_c (s, ((c) & 0xff) << 8)) \
1190 : __strchr_g (s, c)))
1192 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1194 __STRING_INLINE char *
1195 __strchr_c (__const char *__s, int __c)
1197 register unsigned long int __d0;
1198 register char *__res;
1199 __asm__ __volatile__
1201 "movb (%0),%%al\n\t"
1202 "cmpb %%ah,%%al\n\t"
1205 "testb %%al,%%al\n\t"
1209 : "=r" (__res), "=&a" (__d0)
1210 : "0" (__s), "1" (__c)
1215 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1217 __STRING_INLINE char *
1218 __strchr_g (__const char *__s, int __c)
1220 register unsigned long int __d0;
1221 register char *__res;
1222 __asm__ __volatile__
1225 "movb (%0),%%al\n\t"
1226 "cmpb %%ah,%%al\n\t"
1229 "testb %%al,%%al\n\t"
1233 : "=r" (__res), "=&a" (__d0)
1234 : "0" (__s), "1" (__c)
1240 /* Find the first occurrence of C in S or the final NUL byte. */
1241 #define _HAVE_STRING_ARCH_strchrnul 1
1242 #define __strchrnul(s, c) \
1243 (__extension__ (__builtin_constant_p (c) \
1245 ? (char *) __rawmemchr (s, c) \
1246 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
1247 : __strchrnul_g (s, c)))
1249 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
1251 __STRING_INLINE char *
1252 __strchrnul_c (__const char *__s, int __c)
1254 register unsigned long int __d0;
1255 register char *__res;
1256 __asm__ __volatile__
1258 "movb (%0),%%al\n\t"
1259 "cmpb %%ah,%%al\n\t"
1262 "testb %%al,%%al\n\t"
1266 : "=r" (__res), "=&a" (__d0)
1267 : "0" (__s), "1" (__c)
1272 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
1274 __STRING_INLINE char *
1275 __strchrnul_g (__const char *__s, int __c)
1277 register unsigned long int __d0;
1278 register char *__res;
1279 __asm__ __volatile__
1282 "movb (%0),%%al\n\t"
1283 "cmpb %%ah,%%al\n\t"
1286 "testb %%al,%%al\n\t"
1290 : "=r" (__res), "=&a" (__d0)
1291 : "0" (__s), "1" (__c)
1296 # define strchrnul(s, c) __strchrnul (s, c)
1300 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1301 /* Find the first occurrence of C in S. This is the BSD name. */
1302 # define _HAVE_STRING_ARCH_index 1
1303 # define index(s, c) \
1304 (__extension__ (__builtin_constant_p (c) \
1305 ? __strchr_c (s, ((c) & 0xff) << 8) \
1306 : __strchr_g (s, c)))
1310 /* Find the last occurrence of C in S. */
1311 #define _HAVE_STRING_ARCH_strrchr 1
1312 #define strrchr(s, c) \
1313 (__extension__ (__builtin_constant_p (c) \
1314 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1315 : __strrchr_g (s, c)))
1318 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1320 __STRING_INLINE char *
1321 __strrchr_c (__const char *__s, int __c)
1323 register unsigned long int __d0, __d1;
1324 register char *__res;
1325 __asm__ __volatile__
1333 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1334 : "0" (1), "1" (__s), "2" (__c)
1339 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1341 __STRING_INLINE char *
1342 __strrchr_g (__const char *__s, int __c)
1344 register unsigned long int __d0, __d1;
1345 register char *__res;
1346 __asm__ __volatile__
1355 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1356 : "0" (1), "1" (__s), "2" (__c)
1361 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1363 __STRING_INLINE char *
1364 __strrchr_c (__const char *__s, int __c)
1366 register unsigned long int __d0, __d1;
1367 register char *__res;
1368 __asm__ __volatile__
1372 "cmpb %%ah,%%al\n\t"
1374 "leal -1(%%esi),%0\n"
1376 "testb %%al,%%al\n\t"
1378 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1379 : "0" (0), "1" (__s), "2" (__c)
1384 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1386 __STRING_INLINE char *
1387 __strrchr_g (__const char *__s, int __c)
1389 register unsigned long int __d0, __d1;
1390 register char *__res;
1391 __asm__ __volatile__
1396 "cmpb %%ah,%%al\n\t"
1398 "leal -1(%%esi),%0\n"
1400 "testb %%al,%%al\n\t"
1402 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1403 : "0" (0), "1" (__s), "2" (__c)
1410 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1411 /* Find the last occurrence of C in S. This is the BSD name. */
1412 # define _HAVE_STRING_ARCH_rindex 1
1413 # define rindex(s, c) \
1414 (__extension__ (__builtin_constant_p (c) \
1415 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1416 : __strrchr_g (s, c)))
1420 /* Return the length of the initial segment of S which
1421 consists entirely of characters not in REJECT. */
1422 #define _HAVE_STRING_ARCH_strcspn 1
1423 #define strcspn(s, reject) \
1424 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1425 ? ((reject)[0] == '\0' \
1427 : ((reject)[1] == '\0' \
1428 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1429 : __strcspn_cg (s, reject, strlen (reject)))) \
1430 : __strcspn_g (s, reject)))
1432 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1434 __STRING_INLINE size_t
1435 __strcspn_c1 (__const char *__s, int __reject)
1437 register unsigned long int __d0;
1438 register char *__res;
1439 __asm__ __volatile__
1441 "movb (%0),%%al\n\t"
1443 "cmpb %%ah,%%al\n\t"
1445 "testb %%al,%%al\n\t"
1448 : "=r" (__res), "=&a" (__d0)
1449 : "0" (__s), "1" (__reject)
1451 return (__res - 1) - __s;
1454 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1455 size_t __reject_len);
1457 __STRING_INLINE size_t
1458 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1460 register unsigned long int __d0, __d1, __d2;
1461 register __const char *__res;
1462 __asm__ __volatile__
1466 "testb %%al,%%al\n\t"
1473 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1474 : "0" (__s), "d" (__reject), "g" (__reject_len)
1476 return (__res - 1) - __s;
1479 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1482 __STRING_INLINE size_t
1483 __strcspn_g (__const char *__s, __const char *__reject)
1485 register unsigned long int __d0, __d1, __d2;
1486 register __const char *__res;
1487 __asm__ __volatile__
1493 "leal -1(%%ecx),%%ebx\n"
1496 "testb %%al,%%al\n\t"
1499 "movl %%ebx,%%ecx\n\t"
1504 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1505 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1507 return (__res - 1) - __s;
1510 __STRING_INLINE size_t
1511 __strcspn_g (__const char *__s, __const char *__reject)
1513 register unsigned long int __d0, __d1, __d2, __d3;
1514 register __const char *__res;
1515 __asm__ __volatile__
1519 "leal -1(%%ecx),%%edx\n"
1522 "testb %%al,%%al\n\t"
1524 "movl %%ebx,%%edi\n\t"
1525 "movl %%edx,%%ecx\n\t"
1529 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1530 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1532 return (__res - 1) - __s;
1537 /* Return the length of the initial segment of S which
1538 consists entirely of characters in ACCEPT. */
1539 #define _HAVE_STRING_ARCH_strspn 1
1540 #define strspn(s, accept) \
1541 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1542 ? ((accept)[0] == '\0' \
1544 : ((accept)[1] == '\0' \
1545 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1546 : __strspn_cg (s, accept, strlen (accept)))) \
1547 : __strspn_g (s, accept)))
1549 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1551 __STRING_INLINE size_t
1552 __strspn_c1 (__const char *__s, int __accept)
1554 register unsigned long int __d0;
1555 register char *__res;
1556 /* Please note that __accept never can be '\0'. */
1557 __asm__ __volatile__
1563 : "=r" (__res), "=&q" (__d0)
1564 : "0" (__s), "1" (__accept)
1566 return (__res - 1) - __s;
1569 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1570 size_t __accept_len);
1572 __STRING_INLINE size_t
1573 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1575 register unsigned long int __d0, __d1, __d2;
1576 register __const char *__res;
1577 __asm__ __volatile__
1581 "testb %%al,%%al\n\t"
1588 : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1589 : "0" (__s), "1" (__accept), "g" (__accept_len)
1591 return (__res - 1) - __s;
1594 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1597 __STRING_INLINE size_t
1598 __strspn_g (__const char *__s, __const char *__accept)
1600 register unsigned long int __d0, __d1, __d2;
1601 register __const char *__res;
1602 __asm__ __volatile__
1607 "leal -1(%%ecx),%%ebx\n"
1610 "testb %%al,%%al\n\t"
1612 "movl %%edx,%%edi\n\t"
1613 "movl %%ebx,%%ecx\n\t"
1618 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1619 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1621 return (__res - 1) - __s;
1624 __STRING_INLINE size_t
1625 __strspn_g (__const char *__s, __const char *__accept)
1627 register unsigned long int __d0, __d1, __d2, __d3;
1628 register __const char *__res;
1629 __asm__ __volatile__
1633 "leal -1(%%ecx),%%edx\n"
1636 "testb %%al,%%al\n\t"
1638 "movl %%ebx,%%edi\n\t"
1639 "movl %%edx,%%ecx\n\t"
1643 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1644 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1646 return (__res - 1) - __s;
1651 /* Find the first occurrence in S of any character in ACCEPT. */
1652 #define _HAVE_STRING_ARCH_strpbrk 1
1653 #define strpbrk(s, accept) \
1654 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1655 ? ((accept)[0] == '\0' \
1657 : ((accept)[1] == '\0' \
1658 ? strchr (s, (accept)[0]) \
1659 : __strpbrk_cg (s, accept, strlen (accept)))) \
1660 : __strpbrk_g (s, accept)))
1662 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1663 size_t __accept_len);
1665 __STRING_INLINE char *
1666 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1668 register unsigned long int __d0, __d1, __d2;
1669 register char *__res;
1670 __asm__ __volatile__
1674 "testb %%al,%%al\n\t"
1685 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1686 : "0" (__s), "d" (__accept), "g" (__accept_len)
1691 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1694 __STRING_INLINE char *
1695 __strpbrk_g (__const char *__s, __const char *__accept)
1697 register unsigned long int __d0, __d1, __d2;
1698 register char *__res;
1699 __asm__ __volatile__
1701 "movl %%edx,%%edi\n\t"
1705 "leal -1(%%ecx),%%ebx\n"
1708 "testb %%al,%%al\n\t"
1710 "movl %%edx,%%edi\n\t"
1711 "movl %%ebx,%%ecx\n\t"
1720 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1721 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1726 __STRING_INLINE char *
1727 __strpbrk_g (__const char *__s, __const char *__accept)
1729 register unsigned long int __d0, __d1, __d2, __d3;
1730 register char *__res;
1731 __asm__ __volatile__
1732 ("movl %%ebx,%%edi\n\t"
1736 "leal -1(%%ecx),%%edx\n"
1739 "testb %%al,%%al\n\t"
1741 "movl %%ebx,%%edi\n\t"
1742 "movl %%edx,%%ecx\n\t"
1750 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1751 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1758 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1759 #define _HAVE_STRING_ARCH_strstr 1
1760 #define strstr(haystack, needle) \
1761 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1762 ? ((needle)[0] == '\0' \
1764 : ((needle)[1] == '\0' \
1765 ? strchr (haystack, (needle)[0]) \
1766 : __strstr_cg (haystack, needle, strlen (needle)))) \
1767 : __strstr_g (haystack, needle)))
1769 /* Please note that this function need not handle NEEDLEs with a
1770 length shorter than two. */
1771 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1772 size_t __needle_len);
1774 __STRING_INLINE char *
1775 __strstr_cg (__const char *__haystack, __const char __needle[],
1776 size_t __needle_len)
1778 register unsigned long int __d0, __d1, __d2;
1779 register char *__res;
1780 __asm__ __volatile__
1788 "cmpb $0,-1(%%esi)\n\t"
1789 "leal 1(%%eax),%5\n\t"
1791 "xorl %%eax,%%eax\n"
1793 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1794 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1799 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1802 __STRING_INLINE char *
1803 __strstr_g (__const char *__haystack, __const char *__needle)
1805 register unsigned long int __d0, __d1, __d2;
1806 register char *__res;
1807 __asm__ __volatile__
1812 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1813 "movl %%ecx,%%ebx\n"
1815 "movl %%edx,%%edi\n\t"
1816 "movl %%esi,%%eax\n\t"
1817 "movl %%ebx,%%ecx\n\t"
1819 "je 2f\n\t" /* also works for empty string, see above */
1820 "cmpb $0,-1(%%esi)\n\t"
1821 "leal 1(%%eax),%%esi\n\t"
1823 "xorl %%eax,%%eax\n"
1826 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1827 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1833 __STRING_INLINE char *
1834 __strstr_g (__const char *__haystack, __const char *__needle)
1836 register unsigned long int __d0, __d1, __d2, __d3;
1837 register char *__res;
1838 __asm__ __volatile__
1842 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1843 "movl %%ecx,%%edx\n"
1845 "movl %%ebx,%%edi\n\t"
1846 "movl %%esi,%%eax\n\t"
1847 "movl %%edx,%%ecx\n\t"
1849 "je 2f\n\t" /* also works for empty string, see above */
1850 "cmpb $0,-1(%%esi)\n\t"
1851 "leal 1(%%eax),%%esi\n\t"
1853 "xorl %%eax,%%eax\n"
1855 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1856 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1864 /* Bit find functions. We define only the i686 version since for the other
1865 processors gcc generates good code. */
1866 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1868 # define _HAVE_STRING_ARCH_ffs 1
1869 # define ffs(word) (__builtin_constant_p (word) \
1870 ? __builtin_ffs (word) \
1871 : ({ int __cnt, __tmp; \
1872 __asm__ __volatile__ \
1875 : "=&r" (__cnt), "=r" (__tmp) \
1876 : "rm" (word), "1" (-1)); \
1880 # define ffsl(word) ffs(word)
1883 #endif /* BSD || X/Open */
1885 #ifndef _FORCE_INLINES
1886 # undef __STRING_INLINE
1889 #endif /* use string inlines && GNU CC */