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
34 # define __STRING_INLINE inline
36 # define __STRING_INLINE extern __inline
39 /* The macros are used in some of the optimized implementations below. */
40 #define __STRING_SMALL_GET16(src, idx) \
41 (((src)[idx + 1] << 8) | (src)[idx])
42 #define __STRING_SMALL_GET32(src, idx) \
43 ((((src)[idx + 3] << 8 | (src)[idx + 2]) << 8 \
44 | (src)[idx + 1]) << 8 | (src)[idx])
47 /* Copy N bytes of SRC to DEST. */
48 #define _HAVE_STRING_ARCH_memcpy 1
49 #define memcpy(dest, src, n) \
50 (__extension__ (__builtin_constant_p (n) \
51 ? __memcpy_c (dest, src, n) \
52 : __memcpy_g (dest, src, n)))
53 #define __memcpy_c(dest, src, n) \
57 ? __memcpy_by4 (dest, src, n) \
59 ? __memcpy_by2 (dest, src, n) \
60 : __memcpy_g (dest, src, n))))
62 __STRING_INLINE void *__memcpy_by4 (void *__dest, __const void *__src,
65 __STRING_INLINE void *
66 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
68 register unsigned long int __d0, __d1;
69 register void *__tmp = __dest;
78 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
79 : "1" (__tmp), "2" (__src), "3" (__n / 4)
84 __STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src,
87 __STRING_INLINE void *
88 __memcpy_by2 (void *__dest, __const void *__src, size_t __n)
90 register unsigned long int __d0, __d1;
91 register void *__tmp = __dest;
94 "jz 2f\n" /* only a word */
105 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
106 : "1" (__tmp), "2" (__src), "3" (__n / 2)
111 __STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src,
114 __STRING_INLINE void *
115 __memcpy_g (void *__dest, __const void *__src, size_t __n)
117 register unsigned long int __d0, __d1, __d2;
118 register void *__tmp = __dest;
130 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
131 : "0" (__n), "1" (__tmp), "2" (__src)
137 /* Copy N bytes of SRC to DEST, guaranteeing
138 correct behavior for overlapping strings. */
139 __STRING_INLINE void *
140 memmove (void *__dest, __const void *__src, size_t __n)
142 register unsigned long int __d0, __d1, __d2;
143 register void *__tmp = __dest;
148 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
149 : "0" (__n), "1" (__src), "2" (__tmp)
156 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
157 : "0" (__n), "1" (__n - 1 + (__const char *) __src),
158 "2" (__n - 1 + (char *) __tmp)
164 /* Compare N bytes of S1 and S2. */
165 #define _HAVE_STRING_ARCH_memcmp 1
167 /* gcc has problems to spill registers when using PIC. */
169 memcmp (__const void *__s1, __const void *__s2, size_t __n)
171 register unsigned long int __d0, __d1, __d2;
181 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
182 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n)
189 /* Set N bytes of S to C. */
190 #define _HAVE_STRING_ARCH_memset 1
191 #define memset(s, c, n) \
192 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
194 ? __memset_c1 (s, c) \
195 : __memset_gc (s, c, n)) \
196 : (__builtin_constant_p (c) \
197 ? (__builtin_constant_p (n) \
198 ? __memset_ccn (s, c, n) \
199 : memset (s, c, n)) \
200 : (__builtin_constant_p (n) \
201 ? __memset_gcn (s, c, n) \
202 : memset (s, c, n)))))
204 #define __memset_c1(s, c) ({ void *__s = (s); \
205 *((unsigned char *) __s) = (unsigned char) (c); \
208 #define __memset_gc(s, c, n) \
209 ({ void *__s = (s); \
210 unsigned int *__ts = (unsigned int *) __s; \
211 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
213 /* We apply a trick here. `gcc' would implement the following \
214 assignments using absolute operands. But this uses to much \
215 memory (7, instead of 4 bytes). */ \
216 if (n == 3 || n >= 5) \
217 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
219 /* This `switch' statement will be removed at compile-time. */ \
229 *((unsigned short int *) __ts)++ = (unsigned short int) __c; \
230 *((unsigned char *) __ts) = (unsigned char) __c; \
240 *((unsigned short int *) __ts) = (unsigned short int) __c; \
250 *((unsigned char *) __ts) = (unsigned char) __c; \
267 #define __memset_ccn(s, c, n) \
269 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
272 ? __memset_ccn_by2 (s, \
273 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
277 __STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
280 __STRING_INLINE void *
281 __memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
283 register void *__tmp = __s;
284 register unsigned long int __d0;
289 : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0)
290 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
299 : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0)
300 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
306 __STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
309 __STRING_INLINE void *
310 __memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
312 register unsigned long int __d0, __d1;
313 register void *__tmp = __s;
319 : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1)
320 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
324 ("1:\tmovl %0,(%1)\n\t"
329 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
330 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
336 #define __memset_gcn(s, c, n) \
338 ? __memset_gcn_by4 (s, c, n) \
340 ? __memset_gcn_by2 (s, c, n) \
343 __STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
345 __STRING_INLINE void *
346 __memset_gcn_by4 (void *__s, int __c, size_t __n)
348 register void *__tmp = __s;
349 register unsigned long int __d0;
360 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0)
361 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
366 __STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
368 __STRING_INLINE void *
369 __memset_gcn_by2 (void *__s, int __c, size_t __n)
371 register unsigned long int __d0, __d1;
372 register void *__tmp = __s;
384 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
385 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
391 /* Search N bytes of S for C. */
392 #define _HAVE_STRING_ARCH_memchr 1
393 __STRING_INLINE void *
394 memchr (__const void *__s, int __c, size_t __n)
396 register unsigned long int __d0;
398 register unsigned long int __d1;
400 register unsigned char *__res;
408 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
409 : "a" (__c), "0" (__s), "1" (__n), "2" (1)
418 : "=D" (__res), "=&c" (__d0)
419 : "a" (__c), "0" (__s), "1" (__n)
426 /* Return pointer to C in S. */
427 #define _HAVE_STRING_ARCH_rawmemchr 1
428 __STRING_INLINE void *
429 __rawmemchr (const void *__s, int __c)
431 register unsigned long int __d0;
432 register unsigned char *__res;
436 : "=D" (__res), "=&c" (__d0)
437 : "a" (__c), "0" (__s), "1" (0xffffffff)
442 __STRING_INLINE void *
443 rawmemchr (const void *__s, int __c)
445 return __rawmemchr (__s, __c);
450 /* Return the length of S. */
451 #define _HAVE_STRING_ARCH_strlen 1
452 #define strlen(str) \
453 (__extension__ (__builtin_constant_p (str) \
454 ? __builtin_strlen (str) \
456 __STRING_INLINE size_t __strlen_g (__const char *__str);
458 __STRING_INLINE size_t
459 __strlen_g (__const char *__str)
461 register char __dummy;
462 register __const char *__tmp = __str;
469 : "=r" (__tmp), "=&q" (__dummy)
472 return __tmp - __str - 1;
476 /* Copy SRC to DEST. */
477 #define _HAVE_STRING_ARCH_strcpy 1
478 #define strcpy(dest, src) \
479 (__extension__ (__builtin_constant_p (src) \
480 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
481 ? __strcpy_small (dest, src, strlen (src) + 1) \
482 : (char *) memcpy ((char *) dest, \
483 (__const char *) src, \
485 : __strcpy_g (dest, src)))
487 #define __strcpy_small(dest, src, srclen) \
488 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
495 *((unsigned short int *) __dest) = \
496 __STRING_SMALL_GET16 (src, 0); \
499 *((unsigned short int *) __dest) = \
500 __STRING_SMALL_GET16 (src, 0); \
501 *(__dest + 2) = '\0'; \
504 *((unsigned int *) __dest) = \
505 __STRING_SMALL_GET32 (src, 0); \
508 *((unsigned int *) __dest) = \
509 __STRING_SMALL_GET32 (src, 0); \
510 *(__dest + 4) = '\0'; \
513 *((unsigned int *) __dest) = \
514 __STRING_SMALL_GET32 (src, 0); \
515 *((unsigned short int *) (__dest + 4)) = \
516 __STRING_SMALL_GET16 (src, 4); \
519 *((unsigned int *) __dest) = \
520 __STRING_SMALL_GET32 (src, 0); \
521 *((unsigned short int *) (__dest + 4)) = \
522 __STRING_SMALL_GET16 (src, 4); \
523 *(__dest + 6) = '\0'; \
526 *((unsigned int *) __dest) = \
527 __STRING_SMALL_GET32 (src, 0); \
528 *((unsigned int *) (__dest + 4)) = \
529 __STRING_SMALL_GET32 (src, 4); \
534 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
536 __STRING_INLINE char *
537 __strcpy_g (char *__dest, __const char *__src)
539 register char *__tmp = __dest;
540 register char __dummy;
550 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
551 : "0" (__src), "1" (__tmp)
558 # define _HAVE_STRING_ARCH_stpcpy 1
559 /* Copy SRC to DEST. */
560 # define __stpcpy(dest, src) \
561 (__extension__ (__builtin_constant_p (src) \
562 ? (strlen (src) + 1 <= 8 \
563 ? __stpcpy_small (dest, src, strlen (src) + 1) \
564 : __stpcpy_c (dest, src, strlen (src) + 1)) \
565 : __stpcpy_g (dest, src)))
566 # define __stpcpy_c(dest, src, srclen) \
568 ? __mempcpy_by4 (dest, src, srclen) - 1 \
569 : ((srclen) % 2 == 0 \
570 ? __mempcpy_by2 (dest, src, srclen) - 1 \
571 : __mempcpy_byn (dest, src, srclen) - 1))
573 /* In glibc itself we use this symbol for namespace reasons. */
574 # define stpcpy(dest, src) __stpcpy (dest, src)
576 # define __stpcpy_small(dest, src, srclen) \
577 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
584 *((unsigned short int *) __dest) = \
585 __STRING_SMALL_GET16 (src, 0); \
589 *((unsigned short int *) __dest)++ = \
590 __STRING_SMALL_GET16 (src, 0); \
594 *((unsigned int *) __dest) = \
595 __STRING_SMALL_GET32 (src, 0); \
599 *((unsigned int *) __dest)++ = \
600 __STRING_SMALL_GET32 (src, 0); \
604 *((unsigned int *) __dest) = \
605 __STRING_SMALL_GET32 (src, 0); \
606 *((unsigned short int *) (__dest + 4)) = \
607 __STRING_SMALL_GET16 (src, 4); \
611 *((unsigned int *) __dest) = \
612 __STRING_SMALL_GET32 (src, 0); \
613 *((unsigned short int *) (__dest + 4)) = \
614 __STRING_SMALL_GET16 (src, 4); \
619 *((unsigned int *) __dest) = \
620 __STRING_SMALL_GET32 (src, 0); \
621 *((unsigned int *) (__dest + 4)) = \
622 __STRING_SMALL_GET32 (src, 4); \
628 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
631 __STRING_INLINE char *
632 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
634 register char *__tmp = __dest;
635 register unsigned long int __d0, __d1;
644 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
645 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
650 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
653 __STRING_INLINE char *
654 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
656 register char *__tmp = __dest;
657 register unsigned long int __d0, __d1;
660 "jz 2f\n" /* only a word */
671 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
672 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
677 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
680 __STRING_INLINE char *
681 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
683 register unsigned long __d0, __d1;
684 register char *__tmp = __dest;
696 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
697 : "0" (__tmp), "1" (__srclen), "2" (__src)
702 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
704 __STRING_INLINE char *
705 __stpcpy_g (char *__dest, __const char *__src)
707 register char *__tmp = __dest;
708 register char __dummy;
718 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
719 : "0" (__src), "1" (__tmp)
726 /* Copy no more than N characters of SRC to DEST. */
727 #define _HAVE_STRING_ARCH_strncpy 1
728 #define strncpy(dest, src, n) \
729 (__extension__ (__builtin_constant_p (src) \
730 ? ((strlen (src) + 1 >= ((size_t) (n)) \
731 ? (char *) memcpy ((char *) dest, \
732 (__const char *) src, n) \
733 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
734 : __strncpy_gg (dest, src, n)))
735 #define __strncpy_cg(dest, src, srclen, n) \
736 (((srclen) % 4 == 0) \
737 ? __strncpy_by4 (dest, src, srclen, n) \
738 : (((srclen) % 2 == 0) \
739 ? __strncpy_by2 (dest, src, srclen, n) \
740 : __strncpy_byn (dest, src, srclen, n)))
742 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
743 size_t __srclen, size_t __n);
745 __STRING_INLINE char *
746 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
748 register char *__tmp = __dest;
749 register int __dummy1, __dummy2;
758 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
759 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
761 (void) memset (__tmp, '\0', __n - __srclen);
765 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
766 size_t __srclen, size_t __n);
768 __STRING_INLINE char *
769 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
771 register char *__tmp = __dest;
772 register int __dummy1, __dummy2;
775 "jz 2f\n" /* only a word */
786 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
787 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
789 (void) memset (__tmp + 2, '\0', __n - __srclen);
793 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
794 size_t __srclen, size_t __n);
796 __STRING_INLINE char *
797 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
799 register unsigned long int __d0, __d1;
800 register char *__tmp = __dest;
812 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
813 : "1" (__srclen), "0" (__tmp),"2" (__src)
815 (void) memset (__tmp, '\0', __n - __srclen);
819 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
822 __STRING_INLINE char *
823 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
825 register char *__tmp = __dest;
826 register char __dummy;
844 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
845 : "0" (__src), "1" (__tmp), "3" (__n)
852 /* Append SRC onto DEST. */
853 #define _HAVE_STRING_ARCH_strcat 1
854 #define strcat(dest, src) \
855 (__extension__ (__builtin_constant_p (src) \
856 ? __strcat_c (dest, src, strlen (src) + 1) \
857 : __strcat_g (dest, src)))
859 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
862 __STRING_INLINE char *
863 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
866 register unsigned long int __d0;
867 register char *__tmp;
870 : "=D" (__tmp), "=&c" (__d0)
871 : "0" (__dest), "1" (0xffffffff), "a" (0)
875 register char *__tmp = __dest - 1;
885 (void) memcpy (__tmp, __src, __srclen);
889 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
891 __STRING_INLINE char *
892 __strcat_g (char *__dest, __const char *__src)
894 register char *__tmp = __dest - 1;
895 register char __dummy;
908 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
909 : "1" (__tmp), "2" (__src)
915 /* Append no more than N characters from SRC onto DEST. */
916 #define _HAVE_STRING_ARCH_strncat 1
917 #define strncat(dest, src, n) \
918 (__extension__ ({ char *__dest = (dest); \
919 __builtin_constant_p (src) && __builtin_constant_p (n) \
920 ? (strlen (src) < ((size_t) (n)) \
921 ? strcat (__dest, src) \
922 : (memcpy (strchr (__dest, '\0'), \
923 (__const char *) src, n), __dest)) \
924 : __strncat_g (__dest, src, n); }))
926 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
929 __STRING_INLINE char *
930 __strncat_g (char *__dest, __const char __src[], size_t __n)
932 register char *__tmp = __dest;
933 register char __dummy;
948 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
949 : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
970 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
971 : "1" (__tmp), "2" (__src), "3" (__n)
978 /* Compare S1 and S2. */
979 #define _HAVE_STRING_ARCH_strcmp 1
980 #define strcmp(s1, s2) \
981 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
982 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
983 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
984 ? memcmp ((__const char *) s1, (__const char *) s2, \
985 (strlen (s1) < strlen (s2) \
986 ? strlen (s1) : strlen (s2)) + 1) \
987 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
988 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
989 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
990 ? __strcmp_cc (s1, s2, strlen (s1)) \
991 : __strcmp_cg (s1, s2, strlen (s1))) \
992 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
993 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
994 ? (__builtin_constant_p (s1) \
995 ? __strcmp_cc (s1, s2, strlen (s2)) \
996 : __strcmp_gc (s1, s2, strlen (s2))) \
997 : __strcmp_gg (s1, s2)))))
999 #define __strcmp_cc(s1, s2, l) \
1000 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
1001 - (unsigned char) (s2)[0]); \
1002 if (l > 0 && __result == 0) \
1004 __result = ((unsigned char) (s1)[1] \
1005 - (unsigned char) (s2)[1]); \
1006 if (l > 1 && __result == 0) \
1008 __result = ((unsigned char) (s1)[2] \
1009 - (unsigned char) (s2)[2]); \
1010 if (l > 2 && __result == 0) \
1011 __result = ((unsigned char) (s1)[3] \
1012 - (unsigned char) (s2)[3]); \
1017 #define __strcmp_cg(s1, s2, l1) \
1018 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
1019 register int __result = (unsigned char) (s1)[0] - __s2[0];\
1020 if (l1 > 0 && __result == 0) \
1022 __result = (unsigned char) (s1)[1] - __s2[1]; \
1023 if (l1 > 1 && __result == 0) \
1025 __result = (unsigned char) (s1)[2] - __s2[2]; \
1026 if (l1 > 2 && __result == 0) \
1027 __result = (unsigned char) (s1)[3] - __s2[3]; \
1032 #define __strcmp_gc(s1, s2, l2) \
1033 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
1034 register int __result = __s1[0] - (unsigned char) (s2)[0];\
1035 if (l2 > 0 && __result == 0) \
1037 __result = __s1[1] - (unsigned char) (s2)[1]; \
1038 if (l2 > 1 && __result == 0) \
1040 __result = __s1[2] - (unsigned char) (s2)[2]; \
1041 if (l2 > 2 && __result == 0) \
1042 __result = __s1[3] - (unsigned char) (s2)[3]; \
1047 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
1050 __strcmp_gg (__const char *__s1, __const char *__s2)
1053 __asm__ __volatile__
1069 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1070 : "1" (__s1), "2" (__s2)
1076 /* Compare N characters of S1 and S2. */
1077 #define _HAVE_STRING_ARCH_strncmp 1
1078 #define strncmp(s1, s2, n) \
1079 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1081 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1083 : __strncmp_g (s1, s2, n))))
1085 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1089 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1092 __asm__ __volatile__
1111 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1112 : "1" (__s1), "2" (__s2), "3" (__n)
1118 /* Find the first occurrence of C in S. */
1119 #define _HAVE_STRING_ARCH_strchr 1
1120 #define strchr(s, c) \
1121 (__extension__ (__builtin_constant_p (c) \
1123 ? (char *) __rawmemchr (s, c) \
1124 : __strchr_c (s, ((c) & 0xff) << 8)) \
1125 : __strchr_g (s, c)))
1127 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1129 __STRING_INLINE char *
1130 __strchr_c (__const char *__s, int __c)
1132 register unsigned long int __d0;
1133 register char *__res;
1134 __asm__ __volatile__
1136 "movb (%0),%%al\n\t"
1137 "cmpb %%ah,%%al\n\t"
1140 "testb %%al,%%al\n\t"
1144 : "=r" (__res), "=&a" (__d0)
1145 : "0" (__s), "1" (__c)
1150 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1152 __STRING_INLINE char *
1153 __strchr_g (__const char *__s, int __c)
1155 register unsigned long int __d0;
1156 register char *__res;
1157 __asm__ __volatile__
1160 "movb (%0),%%al\n\t"
1161 "cmpb %%ah,%%al\n\t"
1164 "testb %%al,%%al\n\t"
1168 : "=r" (__res), "=&a" (__d0)
1169 : "0" (__s), "1" (__c)
1175 /* Find the first occurrence of C in S or the final NUL byte. */
1176 #define _HAVE_STRING_ARCH_strchrnul 1
1177 #define __strchrnul(s, c) \
1178 (__extension__ (__builtin_constant_p (c) \
1180 ? (char *) __rawmemchr (s, c) \
1181 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
1182 : __strchrnul_g (s, c)))
1184 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
1186 __STRING_INLINE char *
1187 __strchrnul_c (__const char *__s, int __c)
1189 register unsigned long int __d0;
1190 register char *__res;
1191 __asm__ __volatile__
1193 "movb (%0),%%al\n\t"
1194 "cmpb %%ah,%%al\n\t"
1197 "testb %%al,%%al\n\t"
1201 : "=r" (__res), "=&a" (__d0)
1202 : "0" (__s), "1" (__c)
1207 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
1209 __STRING_INLINE char *
1210 __strchrnul_g (__const char *__s, int __c)
1212 register unsigned long int __d0;
1213 register char *__res;
1214 __asm__ __volatile__
1217 "movb (%0),%%al\n\t"
1218 "cmpb %%ah,%%al\n\t"
1221 "testb %%al,%%al\n\t"
1225 : "=r" (__res), "=&a" (__d0)
1226 : "0" (__s), "1" (__c)
1231 # define strchrnul(s, c) __strchrnul (s, c)
1235 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1236 /* Find the first occurrence of C in S. This is the BSD name. */
1237 # define _HAVE_STRING_ARCH_index 1
1238 # define index(s, c) \
1239 (__extension__ (__builtin_constant_p (c) \
1240 ? __strchr_c (s, ((c) & 0xff) << 8) \
1241 : __strchr_g (s, c)))
1245 /* Find the last occurrence of C in S. */
1246 #define _HAVE_STRING_ARCH_strrchr 1
1247 #define strrchr(s, c) \
1248 (__extension__ (__builtin_constant_p (c) \
1249 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1250 : __strrchr_g (s, c)))
1253 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1255 __STRING_INLINE char *
1256 __strrchr_c (__const char *__s, int __c)
1258 register unsigned long int __d0, __d1;
1259 register char *__res;
1260 __asm__ __volatile__
1268 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1269 : "0" (1), "1" (__s), "2" (__c)
1274 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1276 __STRING_INLINE char *
1277 __strrchr_g (__const char *__s, int __c)
1279 register unsigned long int __d0, __d1;
1280 register char *__res;
1281 __asm__ __volatile__
1290 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1291 : "0" (1), "1" (__s), "2" (__c)
1296 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1298 __STRING_INLINE char *
1299 __strrchr_c (__const char *__s, int __c)
1301 register unsigned long int __d0, __d1;
1302 register char *__res;
1303 __asm__ __volatile__
1307 "cmpb %%ah,%%al\n\t"
1309 "leal -1(%%esi),%0\n"
1311 "testb %%al,%%al\n\t"
1313 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1314 : "0" (0), "1" (__s), "2" (__c)
1319 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1321 __STRING_INLINE char *
1322 __strrchr_g (__const char *__s, int __c)
1324 register unsigned long int __d0, __d1;
1325 register char *__res;
1326 __asm__ __volatile__
1331 "cmpb %%ah,%%al\n\t"
1333 "leal -1(%%esi),%0\n"
1335 "testb %%al,%%al\n\t"
1337 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1338 : "0" (0), "1" (__s), "2" (__c)
1345 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1346 /* Find the last occurrence of C in S. This is the BSD name. */
1347 # define _HAVE_STRING_ARCH_rindex 1
1348 # define rindex(s, c) \
1349 (__extension__ (__builtin_constant_p (c) \
1350 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1351 : __strrchr_g (s, c)))
1355 /* Return the length of the initial segment of S which
1356 consists entirely of characters not in REJECT. */
1357 #define _HAVE_STRING_ARCH_strcspn 1
1358 #define strcspn(s, reject) \
1359 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1360 ? ((reject)[0] == '\0' \
1362 : ((reject)[1] == '\0' \
1363 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1364 : __strcspn_cg (s, reject, strlen (reject)))) \
1365 : __strcspn_g (s, reject)))
1367 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1369 __STRING_INLINE size_t
1370 __strcspn_c1 (__const char *__s, int __reject)
1372 register unsigned long int __d0;
1373 register char *__res;
1374 __asm__ __volatile__
1376 "movb (%0),%%al\n\t"
1378 "cmpb %%ah,%%al\n\t"
1380 "testb %%al,%%al\n\t"
1383 : "=r" (__res), "=&a" (__d0)
1384 : "0" (__s), "1" (__reject)
1386 return (__res - 1) - __s;
1389 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1390 size_t __reject_len);
1392 __STRING_INLINE size_t
1393 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1395 register unsigned long int __d0, __d1, __d2;
1396 register __const char *__res;
1397 __asm__ __volatile__
1401 "testb %%al,%%al\n\t"
1408 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1409 : "0" (__s), "d" (__reject), "g" (__reject_len)
1411 return (__res - 1) - __s;
1414 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1417 __STRING_INLINE size_t
1418 __strcspn_g (__const char *__s, __const char *__reject)
1420 register unsigned long int __d0, __d1, __d2;
1421 register __const char *__res;
1422 __asm__ __volatile__
1428 "leal -1(%%ecx),%%ebx\n"
1431 "testb %%al,%%al\n\t"
1434 "movl %%ebx,%%ecx\n\t"
1439 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1440 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1442 return (__res - 1) - __s;
1445 __STRING_INLINE size_t
1446 __strcspn_g (__const char *__s, __const char *__reject)
1448 register unsigned long int __d0, __d1, __d2, __d3;
1449 register __const char *__res;
1450 __asm__ __volatile__
1454 "leal -1(%%ecx),%%edx\n"
1457 "testb %%al,%%al\n\t"
1459 "movl %%ebx,%%edi\n\t"
1460 "movl %%edx,%%ecx\n\t"
1464 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1465 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1467 return (__res - 1) - __s;
1472 /* Return the length of the initial segment of S which
1473 consists entirely of characters in ACCEPT. */
1474 #define _HAVE_STRING_ARCH_strspn 1
1475 #define strspn(s, accept) \
1476 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1477 ? ((accept)[0] == '\0' \
1479 : ((accept)[1] == '\0' \
1480 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1481 : __strspn_cg (s, accept, strlen (accept)))) \
1482 : __strspn_g (s, accept)))
1484 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1486 __STRING_INLINE size_t
1487 __strspn_c1 (__const char *__s, int __accept)
1489 register unsigned long int __d0;
1490 register char *__res;
1491 /* Please note that __accept never can be '\0'. */
1492 __asm__ __volatile__
1498 : "=r" (__res), "=&q" (__d0)
1499 : "0" (__s), "1" (__accept)
1501 return (__res - 1) - __s;
1504 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1505 size_t __accept_len);
1507 __STRING_INLINE size_t
1508 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1510 register unsigned long int __d0, __d1, __d2;
1511 register __const char *__res;
1512 __asm__ __volatile__
1516 "testb %%al,%%al\n\t"
1523 : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1524 : "0" (__s), "1" (__accept), "g" (__accept_len)
1526 return (__res - 1) - __s;
1529 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1532 __STRING_INLINE size_t
1533 __strspn_g (__const char *__s, __const char *__accept)
1535 register unsigned long int __d0, __d1, __d2;
1536 register __const char *__res;
1537 __asm__ __volatile__
1542 "leal -1(%%ecx),%%ebx\n"
1545 "testb %%al,%%al\n\t"
1547 "movl %%edx,%%edi\n\t"
1548 "movl %%ebx,%%ecx\n\t"
1553 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1554 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1556 return (__res - 1) - __s;
1559 __STRING_INLINE size_t
1560 __strspn_g (__const char *__s, __const char *__accept)
1562 register unsigned long int __d0, __d1, __d2, __d3;
1563 register __const char *__res;
1564 __asm__ __volatile__
1568 "leal -1(%%ecx),%%edx\n"
1571 "testb %%al,%%al\n\t"
1573 "movl %%ebx,%%edi\n\t"
1574 "movl %%edx,%%ecx\n\t"
1578 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1579 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1581 return (__res - 1) - __s;
1586 /* Find the first occurrence in S of any character in ACCEPT. */
1587 #define _HAVE_STRING_ARCH_strpbrk 1
1588 #define strpbrk(s, accept) \
1589 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1590 ? ((accept)[0] == '\0' \
1592 : ((accept)[1] == '\0' \
1593 ? strchr (s, (accept)[0]) \
1594 : __strpbrk_cg (s, accept, strlen (accept)))) \
1595 : __strpbrk_g (s, accept)))
1597 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1598 size_t __accept_len);
1600 __STRING_INLINE char *
1601 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1603 register unsigned long int __d0, __d1, __d2;
1604 register char *__res;
1605 __asm__ __volatile__
1609 "testb %%al,%%al\n\t"
1620 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1621 : "0" (__s), "d" (__accept), "g" (__accept_len)
1626 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1629 __STRING_INLINE char *
1630 __strpbrk_g (__const char *__s, __const char *__accept)
1632 register unsigned long int __d0, __d1, __d2;
1633 register char *__res;
1634 __asm__ __volatile__
1636 "movl %%edx,%%edi\n\t"
1640 "leal -1(%%ecx),%%ebx\n"
1643 "testb %%al,%%al\n\t"
1645 "movl %%edx,%%edi\n\t"
1646 "movl %%ebx,%%ecx\n\t"
1655 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1656 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1661 __STRING_INLINE char *
1662 __strpbrk_g (__const char *__s, __const char *__accept)
1664 register unsigned long int __d0, __d1, __d2, __d3;
1665 register char *__res;
1666 __asm__ __volatile__
1667 ("movl %%ebx,%%edi\n\t"
1671 "leal -1(%%ecx),%%edx\n"
1674 "testb %%al,%%al\n\t"
1676 "movl %%ebx,%%edi\n\t"
1677 "movl %%edx,%%ecx\n\t"
1685 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1686 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1693 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1694 #define _HAVE_STRING_ARCH_strstr 1
1695 #define strstr(haystack, needle) \
1696 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1697 ? ((needle)[0] == '\0' \
1699 : ((needle)[1] == '\0' \
1700 ? strchr (haystack, (needle)[0]) \
1701 : __strstr_cg (haystack, needle, strlen (needle)))) \
1702 : __strstr_g (haystack, needle)))
1704 /* Please note that this function need not handle NEEDLEs with a
1705 length shorter than two. */
1706 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1707 size_t __needle_len);
1709 __STRING_INLINE char *
1710 __strstr_cg (__const char *__haystack, __const char __needle[],
1711 size_t __needle_len)
1713 register unsigned long int __d0, __d1, __d2;
1714 register char *__res;
1715 __asm__ __volatile__
1723 "cmpb $0,-1(%%esi)\n\t"
1724 "leal 1(%%eax),%5\n\t"
1726 "xorl %%eax,%%eax\n"
1728 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1729 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1734 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1737 __STRING_INLINE char *
1738 __strstr_g (__const char *__haystack, __const char *__needle)
1740 register unsigned long int __d0, __d1, __d2;
1741 register char *__res;
1742 __asm__ __volatile__
1747 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1748 "movl %%ecx,%%ebx\n"
1750 "movl %%edx,%%edi\n\t"
1751 "movl %%esi,%%eax\n\t"
1752 "movl %%ebx,%%ecx\n\t"
1754 "je 2f\n\t" /* also works for empty string, see above */
1755 "cmpb $0,-1(%%esi)\n\t"
1756 "leal 1(%%eax),%%esi\n\t"
1758 "xorl %%eax,%%eax\n"
1761 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1762 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1768 __STRING_INLINE char *
1769 __strstr_g (__const char *__haystack, __const char *__needle)
1771 register unsigned long int __d0, __d1, __d2, __d3;
1772 register char *__res;
1773 __asm__ __volatile__
1777 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1778 "movl %%ecx,%%edx\n"
1780 "movl %%ebx,%%edi\n\t"
1781 "movl %%esi,%%eax\n\t"
1782 "movl %%edx,%%ecx\n\t"
1784 "je 2f\n\t" /* also works for empty string, see above */
1785 "cmpb $0,-1(%%esi)\n\t"
1786 "leal 1(%%eax),%%esi\n\t"
1788 "xorl %%eax,%%eax\n"
1790 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1791 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1799 /* Bit find functions. We define only the i686 version since for the other
1800 processors gcc generates good code. */
1801 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1803 # define _HAVE_STRING_ARCH_ffs 1
1804 # define ffs(word) (__builtin_constant_p (word) \
1805 ? __builtin_ffs (word) \
1806 : ({ int __cnt, __tmp; \
1807 __asm__ __volatile__ \
1810 : "=&r" (__cnt), "=r" (__tmp) \
1811 : "rm" (word), "1" (-1)); \
1815 # define ffsl(word) ffs(word)
1818 #endif /* BSD || X/Open */
1820 #undef __STRING_INLINE
1822 #endif /* use string inlines && GNU CC */