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 /* Return pointer to C in S. */
450 #define _HAVE_STRING_ARCH_rawmemchr 1
451 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
453 #ifndef _FORCE_INLINES
454 __STRING_INLINE void *
455 __rawmemchr (const void *__s, int __c)
457 register unsigned long int __d0;
458 register unsigned char *__res;
462 : "=D" (__res), "=&c" (__d0)
463 : "a" (__c), "0" (__s), "1" (0xffffffff)
468 __STRING_INLINE void *
469 rawmemchr (const void *__s, int __c)
471 return __rawmemchr (__s, __c);
473 # endif /* use GNU */
477 /* Return the length of S. */
478 #define _HAVE_STRING_ARCH_strlen 1
479 #define strlen(str) \
480 (__extension__ (__builtin_constant_p (str) \
481 ? __builtin_strlen (str) \
483 __STRING_INLINE size_t __strlen_g (__const char *__str);
485 __STRING_INLINE size_t
486 __strlen_g (__const char *__str)
488 register char __dummy;
489 register __const char *__tmp = __str;
496 : "=r" (__tmp), "=&q" (__dummy)
499 return __tmp - __str - 1;
503 /* Copy SRC to DEST. */
504 #define _HAVE_STRING_ARCH_strcpy 1
505 #define strcpy(dest, src) \
506 (__extension__ (__builtin_constant_p (src) \
507 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
508 ? __strcpy_small (dest, src, strlen (src) + 1) \
509 : (char *) memcpy ((char *) dest, \
510 (__const char *) src, \
512 : __strcpy_g (dest, src)))
514 #define __strcpy_small(dest, src, srclen) \
515 (__extension__ ({ char *__dest = (dest); \
518 unsigned short int __usi; \
519 unsigned char __uc; \
521 } *__u = (void *) __dest; \
528 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
531 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
532 __u = __extension__ ((void *) __u + 2); \
536 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
539 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
540 __u = __extension__ ((void *) __u + 4); \
544 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
545 __u = __extension__ ((void *) __u + 4); \
546 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
549 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
550 __u = __extension__ ((void *) __u + 4); \
551 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
552 __u = __extension__ ((void *) __u + 2); \
556 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
557 __u = __extension__ ((void *) __u + 4); \
558 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
563 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
565 __STRING_INLINE char *
566 __strcpy_g (char *__dest, __const char *__src)
568 register char *__tmp = __dest;
569 register char __dummy;
579 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
580 : "0" (__src), "1" (__tmp)
587 # define _HAVE_STRING_ARCH_stpcpy 1
588 /* Copy SRC to DEST. */
589 # define __stpcpy(dest, src) \
590 (__extension__ (__builtin_constant_p (src) \
591 ? (strlen (src) + 1 <= 8 \
592 ? __stpcpy_small (dest, src, strlen (src) + 1) \
593 : __stpcpy_c (dest, src, strlen (src) + 1)) \
594 : __stpcpy_g (dest, src)))
595 # define __stpcpy_c(dest, src, srclen) \
597 ? __mempcpy_by4 (dest, src, srclen) - 1 \
598 : ((srclen) % 2 == 0 \
599 ? __mempcpy_by2 (dest, src, srclen) - 1 \
600 : __mempcpy_byn (dest, src, srclen) - 1))
602 /* In glibc itself we use this symbol for namespace reasons. */
603 # define stpcpy(dest, src) __stpcpy (dest, src)
605 # define __stpcpy_small(dest, src, srclen) \
606 (__extension__ ({ union { \
608 unsigned short int __usi; \
609 unsigned char __uc; \
611 } *__u = (void *) (dest); \
618 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
619 __u = __extension__ ((void *) __u + 1); \
622 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
623 __u = __extension__ ((void *) __u + 2); \
627 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
628 __u = __extension__ ((void *) __u + 3); \
631 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
632 __u = __extension__ ((void *) __u + 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 + 1); \
642 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
643 __u = __extension__ ((void *) __u + 4); \
644 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
645 __u = __extension__ ((void *) __u + 2); \
649 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
650 __u = __extension__ ((void *) __u + 4); \
651 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
652 __u = __extension__ ((void *) __u + 3); \
657 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
660 __STRING_INLINE char *
661 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
663 register char *__tmp = __dest;
664 register unsigned long int __d0, __d1;
673 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
674 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
679 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
682 __STRING_INLINE char *
683 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
685 register char *__tmp = __dest;
686 register unsigned long int __d0, __d1;
689 "jz 2f\n" /* only a word */
700 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
701 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
706 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
709 __STRING_INLINE char *
710 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
712 register unsigned long __d0, __d1;
713 register char *__tmp = __dest;
725 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
726 : "0" (__tmp), "1" (__srclen), "2" (__src)
731 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
733 __STRING_INLINE char *
734 __stpcpy_g (char *__dest, __const char *__src)
736 register char *__tmp = __dest;
737 register char __dummy;
747 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
748 : "0" (__src), "1" (__tmp)
755 /* Copy no more than N characters of SRC to DEST. */
756 #define _HAVE_STRING_ARCH_strncpy 1
757 #define strncpy(dest, src, n) \
758 (__extension__ (__builtin_constant_p (src) \
759 ? ((strlen (src) + 1 >= ((size_t) (n)) \
760 ? (char *) memcpy ((char *) dest, \
761 (__const char *) src, n) \
762 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
763 : __strncpy_gg (dest, src, n)))
764 #define __strncpy_cg(dest, src, srclen, n) \
765 (((srclen) % 4 == 0) \
766 ? __strncpy_by4 (dest, src, srclen, n) \
767 : (((srclen) % 2 == 0) \
768 ? __strncpy_by2 (dest, src, srclen, n) \
769 : __strncpy_byn (dest, src, srclen, n)))
771 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
772 size_t __srclen, size_t __n);
774 __STRING_INLINE char *
775 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
777 register char *__tmp = __dest;
778 register int __dummy1, __dummy2;
787 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
788 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
790 (void) memset (__tmp, '\0', __n - __srclen);
794 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
795 size_t __srclen, size_t __n);
797 __STRING_INLINE char *
798 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
800 register char *__tmp = __dest;
801 register int __dummy1, __dummy2;
804 "jz 2f\n" /* only a word */
815 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
816 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
818 (void) memset (__tmp + 2, '\0', __n - __srclen);
822 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
823 size_t __srclen, size_t __n);
825 __STRING_INLINE char *
826 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
828 register unsigned long int __d0, __d1;
829 register char *__tmp = __dest;
841 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
842 : "1" (__srclen), "0" (__tmp),"2" (__src)
844 (void) memset (__tmp, '\0', __n - __srclen);
848 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
851 __STRING_INLINE char *
852 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
854 register char *__tmp = __dest;
855 register char __dummy;
873 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
874 : "0" (__src), "1" (__tmp), "3" (__n)
881 /* Append SRC onto DEST. */
882 #define _HAVE_STRING_ARCH_strcat 1
883 #define strcat(dest, src) \
884 (__extension__ (__builtin_constant_p (src) \
885 ? __strcat_c (dest, src, strlen (src) + 1) \
886 : __strcat_g (dest, src)))
888 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
891 __STRING_INLINE char *
892 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
895 register unsigned long int __d0;
896 register char *__tmp;
899 : "=D" (__tmp), "=&c" (__d0)
900 : "0" (__dest), "1" (0xffffffff), "a" (0)
904 register char *__tmp = __dest - 1;
914 (void) memcpy (__tmp, __src, __srclen);
918 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
920 __STRING_INLINE char *
921 __strcat_g (char *__dest, __const char *__src)
923 register char *__tmp = __dest - 1;
924 register char __dummy;
937 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
938 : "1" (__tmp), "2" (__src)
944 /* Append no more than N characters from SRC onto DEST. */
945 #define _HAVE_STRING_ARCH_strncat 1
946 #define strncat(dest, src, n) \
947 (__extension__ ({ char *__dest = (dest); \
948 __builtin_constant_p (src) && __builtin_constant_p (n) \
949 ? (strlen (src) < ((size_t) (n)) \
950 ? strcat (__dest, src) \
951 : (memcpy (strchr (__dest, '\0'), \
952 (__const char *) src, n), __dest)) \
953 : __strncat_g (__dest, src, n); }))
955 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
958 __STRING_INLINE char *
959 __strncat_g (char *__dest, __const char __src[], size_t __n)
961 register char *__tmp = __dest;
962 register char __dummy;
977 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
978 : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
999 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1000 : "1" (__tmp), "2" (__src), "3" (__n)
1007 /* Compare S1 and S2. */
1008 #define _HAVE_STRING_ARCH_strcmp 1
1009 #define strcmp(s1, s2) \
1010 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1011 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1012 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1013 ? memcmp ((__const char *) s1, (__const char *) s2, \
1014 (strlen (s1) < strlen (s2) \
1015 ? strlen (s1) : strlen (s2)) + 1) \
1016 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1017 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1018 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1019 ? __strcmp_cc (s1, s2, strlen (s1)) \
1020 : __strcmp_cg (s1, s2, strlen (s1))) \
1021 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1022 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1023 ? (__builtin_constant_p (s1) \
1024 ? __strcmp_cc (s1, s2, strlen (s2)) \
1025 : __strcmp_gc (s1, s2, strlen (s2))) \
1026 : __strcmp_gg (s1, s2)))))
1028 #define __strcmp_cc(s1, s2, l) \
1029 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
1030 - (unsigned char) (s2)[0]); \
1031 if (l > 0 && __result == 0) \
1033 __result = ((unsigned char) (s1)[1] \
1034 - (unsigned char) (s2)[1]); \
1035 if (l > 1 && __result == 0) \
1037 __result = ((unsigned char) (s1)[2] \
1038 - (unsigned char) (s2)[2]); \
1039 if (l > 2 && __result == 0) \
1040 __result = ((unsigned char) (s1)[3] \
1041 - (unsigned char) (s2)[3]); \
1046 #define __strcmp_cg(s1, s2, l1) \
1047 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
1048 register int __result = (unsigned char) (s1)[0] - __s2[0];\
1049 if (l1 > 0 && __result == 0) \
1051 __result = (unsigned char) (s1)[1] - __s2[1]; \
1052 if (l1 > 1 && __result == 0) \
1054 __result = (unsigned char) (s1)[2] - __s2[2]; \
1055 if (l1 > 2 && __result == 0) \
1056 __result = (unsigned char) (s1)[3] - __s2[3]; \
1061 #define __strcmp_gc(s1, s2, l2) \
1062 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
1063 register int __result = __s1[0] - (unsigned char) (s2)[0];\
1064 if (l2 > 0 && __result == 0) \
1066 __result = __s1[1] - (unsigned char) (s2)[1]; \
1067 if (l2 > 1 && __result == 0) \
1069 __result = __s1[2] - (unsigned char) (s2)[2]; \
1070 if (l2 > 2 && __result == 0) \
1071 __result = __s1[3] - (unsigned char) (s2)[3]; \
1076 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
1079 __strcmp_gg (__const char *__s1, __const char *__s2)
1082 __asm__ __volatile__
1098 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1099 : "1" (__s1), "2" (__s2)
1105 /* Compare N characters of S1 and S2. */
1106 #define _HAVE_STRING_ARCH_strncmp 1
1107 #define strncmp(s1, s2, n) \
1108 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1110 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1112 : __strncmp_g (s1, s2, n))))
1114 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1118 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1121 __asm__ __volatile__
1140 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1141 : "1" (__s1), "2" (__s2), "3" (__n)
1147 /* Find the first occurrence of C in S. */
1148 #define _HAVE_STRING_ARCH_strchr 1
1149 #define strchr(s, c) \
1150 (__extension__ (__builtin_constant_p (c) \
1152 ? (char *) __rawmemchr (s, c) \
1153 : __strchr_c (s, ((c) & 0xff) << 8)) \
1154 : __strchr_g (s, c)))
1156 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1158 __STRING_INLINE char *
1159 __strchr_c (__const char *__s, int __c)
1161 register unsigned long int __d0;
1162 register char *__res;
1163 __asm__ __volatile__
1165 "movb (%0),%%al\n\t"
1166 "cmpb %%ah,%%al\n\t"
1169 "testb %%al,%%al\n\t"
1173 : "=r" (__res), "=&a" (__d0)
1174 : "0" (__s), "1" (__c)
1179 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1181 __STRING_INLINE char *
1182 __strchr_g (__const char *__s, int __c)
1184 register unsigned long int __d0;
1185 register char *__res;
1186 __asm__ __volatile__
1189 "movb (%0),%%al\n\t"
1190 "cmpb %%ah,%%al\n\t"
1193 "testb %%al,%%al\n\t"
1197 : "=r" (__res), "=&a" (__d0)
1198 : "0" (__s), "1" (__c)
1204 /* Find the first occurrence of C in S or the final NUL byte. */
1205 #define _HAVE_STRING_ARCH_strchrnul 1
1206 #define __strchrnul(s, c) \
1207 (__extension__ (__builtin_constant_p (c) \
1209 ? (char *) __rawmemchr (s, c) \
1210 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
1211 : __strchrnul_g (s, c)))
1213 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
1215 __STRING_INLINE char *
1216 __strchrnul_c (__const char *__s, int __c)
1218 register unsigned long int __d0;
1219 register char *__res;
1220 __asm__ __volatile__
1222 "movb (%0),%%al\n\t"
1223 "cmpb %%ah,%%al\n\t"
1226 "testb %%al,%%al\n\t"
1230 : "=r" (__res), "=&a" (__d0)
1231 : "0" (__s), "1" (__c)
1236 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
1238 __STRING_INLINE char *
1239 __strchrnul_g (__const char *__s, int __c)
1241 register unsigned long int __d0;
1242 register char *__res;
1243 __asm__ __volatile__
1246 "movb (%0),%%al\n\t"
1247 "cmpb %%ah,%%al\n\t"
1250 "testb %%al,%%al\n\t"
1254 : "=r" (__res), "=&a" (__d0)
1255 : "0" (__s), "1" (__c)
1260 # define strchrnul(s, c) __strchrnul (s, c)
1264 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1265 /* Find the first occurrence of C in S. This is the BSD name. */
1266 # define _HAVE_STRING_ARCH_index 1
1267 # define index(s, c) \
1268 (__extension__ (__builtin_constant_p (c) \
1269 ? __strchr_c (s, ((c) & 0xff) << 8) \
1270 : __strchr_g (s, c)))
1274 /* Find the last occurrence of C in S. */
1275 #define _HAVE_STRING_ARCH_strrchr 1
1276 #define strrchr(s, c) \
1277 (__extension__ (__builtin_constant_p (c) \
1278 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1279 : __strrchr_g (s, c)))
1282 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1284 __STRING_INLINE char *
1285 __strrchr_c (__const char *__s, int __c)
1287 register unsigned long int __d0, __d1;
1288 register char *__res;
1289 __asm__ __volatile__
1297 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1298 : "0" (1), "1" (__s), "2" (__c)
1303 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1305 __STRING_INLINE char *
1306 __strrchr_g (__const char *__s, int __c)
1308 register unsigned long int __d0, __d1;
1309 register char *__res;
1310 __asm__ __volatile__
1319 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1320 : "0" (1), "1" (__s), "2" (__c)
1325 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1327 __STRING_INLINE char *
1328 __strrchr_c (__const char *__s, int __c)
1330 register unsigned long int __d0, __d1;
1331 register char *__res;
1332 __asm__ __volatile__
1336 "cmpb %%ah,%%al\n\t"
1338 "leal -1(%%esi),%0\n"
1340 "testb %%al,%%al\n\t"
1342 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1343 : "0" (0), "1" (__s), "2" (__c)
1348 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1350 __STRING_INLINE char *
1351 __strrchr_g (__const char *__s, int __c)
1353 register unsigned long int __d0, __d1;
1354 register char *__res;
1355 __asm__ __volatile__
1360 "cmpb %%ah,%%al\n\t"
1362 "leal -1(%%esi),%0\n"
1364 "testb %%al,%%al\n\t"
1366 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1367 : "0" (0), "1" (__s), "2" (__c)
1374 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1375 /* Find the last occurrence of C in S. This is the BSD name. */
1376 # define _HAVE_STRING_ARCH_rindex 1
1377 # define rindex(s, c) \
1378 (__extension__ (__builtin_constant_p (c) \
1379 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1380 : __strrchr_g (s, c)))
1384 /* Return the length of the initial segment of S which
1385 consists entirely of characters not in REJECT. */
1386 #define _HAVE_STRING_ARCH_strcspn 1
1387 #define strcspn(s, reject) \
1388 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1389 ? ((reject)[0] == '\0' \
1391 : ((reject)[1] == '\0' \
1392 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1393 : __strcspn_cg (s, reject, strlen (reject)))) \
1394 : __strcspn_g (s, reject)))
1396 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1398 __STRING_INLINE size_t
1399 __strcspn_c1 (__const char *__s, int __reject)
1401 register unsigned long int __d0;
1402 register char *__res;
1403 __asm__ __volatile__
1405 "movb (%0),%%al\n\t"
1407 "cmpb %%ah,%%al\n\t"
1409 "testb %%al,%%al\n\t"
1412 : "=r" (__res), "=&a" (__d0)
1413 : "0" (__s), "1" (__reject)
1415 return (__res - 1) - __s;
1418 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1419 size_t __reject_len);
1421 __STRING_INLINE size_t
1422 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1424 register unsigned long int __d0, __d1, __d2;
1425 register __const char *__res;
1426 __asm__ __volatile__
1430 "testb %%al,%%al\n\t"
1437 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1438 : "0" (__s), "d" (__reject), "g" (__reject_len)
1440 return (__res - 1) - __s;
1443 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1446 __STRING_INLINE size_t
1447 __strcspn_g (__const char *__s, __const char *__reject)
1449 register unsigned long int __d0, __d1, __d2;
1450 register __const char *__res;
1451 __asm__ __volatile__
1457 "leal -1(%%ecx),%%ebx\n"
1460 "testb %%al,%%al\n\t"
1463 "movl %%ebx,%%ecx\n\t"
1468 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1469 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1471 return (__res - 1) - __s;
1474 __STRING_INLINE size_t
1475 __strcspn_g (__const char *__s, __const char *__reject)
1477 register unsigned long int __d0, __d1, __d2, __d3;
1478 register __const char *__res;
1479 __asm__ __volatile__
1483 "leal -1(%%ecx),%%edx\n"
1486 "testb %%al,%%al\n\t"
1488 "movl %%ebx,%%edi\n\t"
1489 "movl %%edx,%%ecx\n\t"
1493 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1494 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1496 return (__res - 1) - __s;
1501 /* Return the length of the initial segment of S which
1502 consists entirely of characters in ACCEPT. */
1503 #define _HAVE_STRING_ARCH_strspn 1
1504 #define strspn(s, accept) \
1505 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1506 ? ((accept)[0] == '\0' \
1508 : ((accept)[1] == '\0' \
1509 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1510 : __strspn_cg (s, accept, strlen (accept)))) \
1511 : __strspn_g (s, accept)))
1513 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1515 __STRING_INLINE size_t
1516 __strspn_c1 (__const char *__s, int __accept)
1518 register unsigned long int __d0;
1519 register char *__res;
1520 /* Please note that __accept never can be '\0'. */
1521 __asm__ __volatile__
1527 : "=r" (__res), "=&q" (__d0)
1528 : "0" (__s), "1" (__accept)
1530 return (__res - 1) - __s;
1533 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1534 size_t __accept_len);
1536 __STRING_INLINE size_t
1537 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1539 register unsigned long int __d0, __d1, __d2;
1540 register __const char *__res;
1541 __asm__ __volatile__
1545 "testb %%al,%%al\n\t"
1552 : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1553 : "0" (__s), "1" (__accept), "g" (__accept_len)
1555 return (__res - 1) - __s;
1558 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1561 __STRING_INLINE size_t
1562 __strspn_g (__const char *__s, __const char *__accept)
1564 register unsigned long int __d0, __d1, __d2;
1565 register __const char *__res;
1566 __asm__ __volatile__
1571 "leal -1(%%ecx),%%ebx\n"
1574 "testb %%al,%%al\n\t"
1576 "movl %%edx,%%edi\n\t"
1577 "movl %%ebx,%%ecx\n\t"
1582 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1583 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1585 return (__res - 1) - __s;
1588 __STRING_INLINE size_t
1589 __strspn_g (__const char *__s, __const char *__accept)
1591 register unsigned long int __d0, __d1, __d2, __d3;
1592 register __const char *__res;
1593 __asm__ __volatile__
1597 "leal -1(%%ecx),%%edx\n"
1600 "testb %%al,%%al\n\t"
1602 "movl %%ebx,%%edi\n\t"
1603 "movl %%edx,%%ecx\n\t"
1607 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1608 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1610 return (__res - 1) - __s;
1615 /* Find the first occurrence in S of any character in ACCEPT. */
1616 #define _HAVE_STRING_ARCH_strpbrk 1
1617 #define strpbrk(s, accept) \
1618 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1619 ? ((accept)[0] == '\0' \
1621 : ((accept)[1] == '\0' \
1622 ? strchr (s, (accept)[0]) \
1623 : __strpbrk_cg (s, accept, strlen (accept)))) \
1624 : __strpbrk_g (s, accept)))
1626 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1627 size_t __accept_len);
1629 __STRING_INLINE char *
1630 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1632 register unsigned long int __d0, __d1, __d2;
1633 register char *__res;
1634 __asm__ __volatile__
1638 "testb %%al,%%al\n\t"
1649 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1650 : "0" (__s), "d" (__accept), "g" (__accept_len)
1655 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1658 __STRING_INLINE char *
1659 __strpbrk_g (__const char *__s, __const char *__accept)
1661 register unsigned long int __d0, __d1, __d2;
1662 register char *__res;
1663 __asm__ __volatile__
1665 "movl %%edx,%%edi\n\t"
1669 "leal -1(%%ecx),%%ebx\n"
1672 "testb %%al,%%al\n\t"
1674 "movl %%edx,%%edi\n\t"
1675 "movl %%ebx,%%ecx\n\t"
1684 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1685 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1690 __STRING_INLINE char *
1691 __strpbrk_g (__const char *__s, __const char *__accept)
1693 register unsigned long int __d0, __d1, __d2, __d3;
1694 register char *__res;
1695 __asm__ __volatile__
1696 ("movl %%ebx,%%edi\n\t"
1700 "leal -1(%%ecx),%%edx\n"
1703 "testb %%al,%%al\n\t"
1705 "movl %%ebx,%%edi\n\t"
1706 "movl %%edx,%%ecx\n\t"
1714 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1715 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1722 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1723 #define _HAVE_STRING_ARCH_strstr 1
1724 #define strstr(haystack, needle) \
1725 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1726 ? ((needle)[0] == '\0' \
1728 : ((needle)[1] == '\0' \
1729 ? strchr (haystack, (needle)[0]) \
1730 : __strstr_cg (haystack, needle, strlen (needle)))) \
1731 : __strstr_g (haystack, needle)))
1733 /* Please note that this function need not handle NEEDLEs with a
1734 length shorter than two. */
1735 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1736 size_t __needle_len);
1738 __STRING_INLINE char *
1739 __strstr_cg (__const char *__haystack, __const char __needle[],
1740 size_t __needle_len)
1742 register unsigned long int __d0, __d1, __d2;
1743 register char *__res;
1744 __asm__ __volatile__
1752 "cmpb $0,-1(%%esi)\n\t"
1753 "leal 1(%%eax),%5\n\t"
1755 "xorl %%eax,%%eax\n"
1757 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1758 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1763 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1766 __STRING_INLINE char *
1767 __strstr_g (__const char *__haystack, __const char *__needle)
1769 register unsigned long int __d0, __d1, __d2;
1770 register char *__res;
1771 __asm__ __volatile__
1776 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1777 "movl %%ecx,%%ebx\n"
1779 "movl %%edx,%%edi\n\t"
1780 "movl %%esi,%%eax\n\t"
1781 "movl %%ebx,%%ecx\n\t"
1783 "je 2f\n\t" /* also works for empty string, see above */
1784 "cmpb $0,-1(%%esi)\n\t"
1785 "leal 1(%%eax),%%esi\n\t"
1787 "xorl %%eax,%%eax\n"
1790 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1791 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1797 __STRING_INLINE char *
1798 __strstr_g (__const char *__haystack, __const char *__needle)
1800 register unsigned long int __d0, __d1, __d2, __d3;
1801 register char *__res;
1802 __asm__ __volatile__
1806 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1807 "movl %%ecx,%%edx\n"
1809 "movl %%ebx,%%edi\n\t"
1810 "movl %%esi,%%eax\n\t"
1811 "movl %%edx,%%ecx\n\t"
1813 "je 2f\n\t" /* also works for empty string, see above */
1814 "cmpb $0,-1(%%esi)\n\t"
1815 "leal 1(%%eax),%%esi\n\t"
1817 "xorl %%eax,%%eax\n"
1819 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1820 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1828 /* Bit find functions. We define only the i686 version since for the other
1829 processors gcc generates good code. */
1830 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1832 # define _HAVE_STRING_ARCH_ffs 1
1833 # define ffs(word) (__builtin_constant_p (word) \
1834 ? __builtin_ffs (word) \
1835 : ({ int __cnt, __tmp; \
1836 __asm__ __volatile__ \
1839 : "=&r" (__cnt), "=r" (__tmp) \
1840 : "rm" (word), "1" (-1)); \
1844 # define ffsl(word) ffs(word)
1847 #endif /* BSD || X/Open */
1849 #ifndef _FORCE_INLINES
1850 # undef __STRING_INLINE
1853 #endif /* use string inlines && GNU CC */