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 \
193 ? (__builtin_constant_p (c) \
194 ? __memset_gc (s, ((unsigned char) (c)) * 0x01010101, n) \
196 ? __memset_c1 (s, c) \
197 : __memset_gc (s, c, n))) \
198 : (__builtin_constant_p (c) \
199 ? (__builtin_constant_p (n) \
200 ? __memset_ccn (s, c, n) \
201 : __memset_gg (s, c, n)) \
202 : (__builtin_constant_p (n) \
203 ? __memset_gcn (s, c, n) \
204 : __memset_gg (s, c, n)))))
206 #define __memset_c1(s, c) ({ void *__s = (s); \
207 *((unsigned char *) __s) = (unsigned char) (c); \
210 #define __memset_gc(s, c, n) \
211 ({ void *__s = (s); \
212 unsigned int *__ts = (unsigned int *) __s; \
213 unsigned int __c = ((unsigned char) (c)) * 0x01010101; \
215 /* We apply a trick here. `gcc' would implement the following \
216 assignments using absolute operands. But this uses to much \
217 memory (7, instead of 4 bytes). */ \
218 if (n == 3 || n >= 5) \
219 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
221 /* This `switch' statement will be removed at compile-time. */ \
231 *((unsigned short int *) __ts)++ = (unsigned short int) __c; \
232 *((unsigned char *) __ts) = (unsigned char) __c; \
242 *((unsigned short int *) __ts) = (unsigned short int) __c; \
252 *((unsigned char *) __ts) = (unsigned char) __c; \
269 #define __memset_ccn(s, c, n) \
271 ? __memset_ccn_by4 (s, ((unsigned char) (c)) * 0x01010101, n) \
273 ? __memset_ccn_by2 (s, ((unsigned char) (c)) * 0x01010101, n) \
274 : __memset_gg (s, c, n)))
276 __STRING_INLINE
void *__memset_ccn_by4 (void *__s
, int __c
, size_t __n
);
278 __STRING_INLINE
void *
279 __memset_ccn_by4 (void *__s
, int __c
, size_t __n
)
281 register void *__tmp
= __s
;
282 register unsigned long int __d0
;
287 : "=&a" (__c
), "=&D" (__tmp
), "=&c" (__d0
)
288 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
297 : "=&q" (__c
), "=&r" (__tmp
), "=&r" (__d0
)
298 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
304 __STRING_INLINE
void *__memset_ccn_by2 (void *__s
, int __c
, size_t __n
);
306 __STRING_INLINE
void *
307 __memset_ccn_by2 (void *__s
, int __c
, size_t __n
)
309 register unsigned long int __d0
, __d1
;
310 register void *__tmp
= __s
;
316 : "=&a" (__d0
), "=&D" (__tmp
), "=&c" (__d1
)
317 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
321 ("1:\tmovl %0,(%1)\n\t"
326 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__d1
)
327 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
333 #define __memset_gcn(s, c, n) \
335 ? __memset_gcn_by4 (s, c, n) \
337 ? __memset_gcn_by2 (s, c, n) \
338 : __memset_gg (s, c, n)))
340 __STRING_INLINE
void *__memset_gcn_by4 (void *__s
, int __c
, size_t __n
);
342 __STRING_INLINE
void *
343 __memset_gcn_by4 (void *__s
, int __c
, size_t __n
)
345 register void *__tmp
= __s
;
346 register unsigned long int __d0
;
357 : "=&q" (__c
), "=&r" (__tmp
), "=&r" (__d0
)
358 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
363 __STRING_INLINE
void *__memset_gcn_by2 (void *__s
, int __c
, size_t __n
);
365 __STRING_INLINE
void *
366 __memset_gcn_by2 (void *__s
, int __c
, size_t __n
)
368 register unsigned long int __d0
, __d1
;
369 register void *__tmp
= __s
;
381 : "=&q" (__d0
), "=&r" (__tmp
), "=&r" (__d1
)
382 : "0" ((unsigned int) __c
), "1" (__tmp
), "2" (__n
/ 4)
387 __STRING_INLINE
void *__memset_gg (void *__s
, int __c
, size_t __n
);
389 __STRING_INLINE
void *
390 __memset_gg (void *__s
, int __c
, size_t __n
)
392 register unsigned long int __d0
, __d1
;
393 register void *__tmp
= __s
;
400 "movb %%al,(%%edi)\n"
402 : "=&c" (__d0
), "=&D" (__d1
)
403 : "0" (__n
), "1" (__tmp
), "a" (__c
)
409 /* Search N bytes of S for C. */
410 #define _HAVE_STRING_ARCH_memchr 1
411 __STRING_INLINE
void *
412 memchr (__const
void *__s
, int __c
, size_t __n
)
414 register unsigned long int __d0
;
416 register unsigned long int __d1
;
418 register unsigned char *__res
;
426 : "=D" (__res
), "=&c" (__d0
), "=&r" (__d1
)
427 : "a" (__c
), "0" (__s
), "1" (__n
), "2" (1)
436 : "=D" (__res
), "=&c" (__d0
)
437 : "a" (__c
), "0" (__s
), "1" (__n
)
444 /* Return pointer to C in S. */
445 #define _HAVE_STRING_ARCH_rawmemchr 1
446 __STRING_INLINE
void *
447 __rawmemchr (const void *__s
, int __c
)
449 register unsigned long int __d0
;
450 register unsigned char *__res
;
454 : "=D" (__res
), "=&c" (__d0
)
455 : "a" (__c
), "0" (__s
), "1" (0xffffffff)
460 __STRING_INLINE
void *
461 rawmemchr (const void *__s
, int __c
)
463 return __rawmemchr (__s
, __c
);
468 /* Return the length of S. */
469 #define _HAVE_STRING_ARCH_strlen 1
470 #define strlen(str) \
471 (__extension__ (__builtin_constant_p (str) \
472 ? __builtin_strlen (str) \
474 __STRING_INLINE
size_t __strlen_g (__const
char *__str
);
476 __STRING_INLINE
size_t
477 __strlen_g (__const
char *__str
)
479 register char __dummy
;
480 register __const
char *__tmp
= __str
;
487 : "=r" (__tmp
), "=&q" (__dummy
)
490 return __tmp
- __str
- 1;
494 /* Copy SRC to DEST. */
495 #define _HAVE_STRING_ARCH_strcpy 1
496 #define strcpy(dest, src) \
497 (__extension__ (__builtin_constant_p (src) \
498 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
499 ? __strcpy_small (dest, src, strlen (src) + 1) \
500 : (char *) memcpy ((char *) dest, \
501 (__const char *) src, \
503 : __strcpy_g (dest, src)))
505 #define __strcpy_small(dest, src, srclen) \
506 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
513 *((unsigned short int *) __dest) = \
514 __STRING_SMALL_GET16 (src, 0); \
517 *((unsigned short int *) __dest) = \
518 __STRING_SMALL_GET16 (src, 0); \
519 *(__dest + 2) = '\0'; \
522 *((unsigned int *) __dest) = \
523 __STRING_SMALL_GET32 (src, 0); \
526 *((unsigned int *) __dest) = \
527 __STRING_SMALL_GET32 (src, 0); \
528 *(__dest + 4) = '\0'; \
531 *((unsigned int *) __dest) = \
532 __STRING_SMALL_GET32 (src, 0); \
533 *((unsigned short int *) (__dest + 4)) = \
534 __STRING_SMALL_GET16 (src, 4); \
537 *((unsigned int *) __dest) = \
538 __STRING_SMALL_GET32 (src, 0); \
539 *((unsigned short int *) (__dest + 4)) = \
540 __STRING_SMALL_GET16 (src, 4); \
541 *(__dest + 6) = '\0'; \
544 *((unsigned int *) __dest) = \
545 __STRING_SMALL_GET32 (src, 0); \
546 *((unsigned int *) (__dest + 4)) = \
547 __STRING_SMALL_GET32 (src, 4); \
552 __STRING_INLINE
char *__strcpy_g (char *__dest
, __const
char *__src
);
554 __STRING_INLINE
char *
555 __strcpy_g (char *__dest
, __const
char *__src
)
557 register char *__tmp
= __dest
;
558 register char __dummy
;
568 : "=&r" (__src
), "=&r" (__tmp
), "=&q" (__dummy
)
569 : "0" (__src
), "1" (__tmp
)
576 # define _HAVE_STRING_ARCH_stpcpy 1
577 /* Copy SRC to DEST. */
578 # define __stpcpy(dest, src) \
579 (__extension__ (__builtin_constant_p (src) \
580 ? (strlen (src) + 1 <= 8 \
581 ? __stpcpy_small (dest, src, strlen (src) + 1) \
582 : __stpcpy_c (dest, src, strlen (src) + 1)) \
583 : __stpcpy_g (dest, src)))
584 # define __stpcpy_c(dest, src, srclen) \
586 ? __mempcpy_by4 (dest, src, srclen) - 1 \
587 : ((srclen) % 2 == 0 \
588 ? __mempcpy_by2 (dest, src, srclen) - 1 \
589 : __mempcpy_byn (dest, src, srclen) - 1))
591 /* In glibc itself we use this symbol for namespace reasons. */
592 # define stpcpy(dest, src) __stpcpy (dest, src)
594 # define __stpcpy_small(dest, src, srclen) \
595 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
602 *((unsigned short int *) __dest) = \
603 __STRING_SMALL_GET16 (src, 0); \
607 *((unsigned short int *) __dest)++ = \
608 __STRING_SMALL_GET16 (src, 0); \
612 *((unsigned int *) __dest) = \
613 __STRING_SMALL_GET32 (src, 0); \
617 *((unsigned int *) __dest)++ = \
618 __STRING_SMALL_GET32 (src, 0); \
622 *((unsigned int *) __dest) = \
623 __STRING_SMALL_GET32 (src, 0); \
624 *((unsigned short int *) (__dest + 4)) = \
625 __STRING_SMALL_GET16 (src, 4); \
629 *((unsigned int *) __dest) = \
630 __STRING_SMALL_GET32 (src, 0); \
631 *((unsigned short int *) (__dest + 4)) = \
632 __STRING_SMALL_GET16 (src, 4); \
637 *((unsigned int *) __dest) = \
638 __STRING_SMALL_GET32 (src, 0); \
639 *((unsigned int *) (__dest + 4)) = \
640 __STRING_SMALL_GET32 (src, 4); \
646 __STRING_INLINE
char *__mempcpy_by4 (char *__dest
, __const
char *__src
,
649 __STRING_INLINE
char *
650 __mempcpy_by4 (char *__dest
, __const
char *__src
, size_t __srclen
)
652 register char *__tmp
= __dest
;
653 register unsigned long int __d0
, __d1
;
662 : "=&r" (__d0
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
663 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 4)
668 __STRING_INLINE
char *__mempcpy_by2 (char *__dest
, __const
char *__src
,
671 __STRING_INLINE
char *
672 __mempcpy_by2 (char *__dest
, __const
char *__src
, size_t __srclen
)
674 register char *__tmp
= __dest
;
675 register unsigned long int __d0
, __d1
;
678 "jz 2f\n" /* only a word */
689 : "=&q" (__d0
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__d1
)
690 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 2)
695 __STRING_INLINE
char *__mempcpy_byn (char *__dest
, __const
char *__src
,
698 __STRING_INLINE
char *
699 __mempcpy_byn (char *__dest
, __const
char *__src
, size_t __srclen
)
701 register unsigned long __d0
, __d1
;
702 register char *__tmp
= __dest
;
714 : "=D" (__tmp
), "=&c" (__d0
), "=&S" (__d1
)
715 : "0" (__tmp
), "1" (__srclen
), "2" (__src
)
720 __STRING_INLINE
char *__stpcpy_g (char *__dest
, __const
char *__src
);
722 __STRING_INLINE
char *
723 __stpcpy_g (char *__dest
, __const
char *__src
)
725 register char *__tmp
= __dest
;
726 register char __dummy
;
736 : "=&r" (__src
), "=r" (__tmp
), "=&q" (__dummy
)
737 : "0" (__src
), "1" (__tmp
)
744 /* Copy no more than N characters of SRC to DEST. */
745 #define _HAVE_STRING_ARCH_strncpy 1
746 #define strncpy(dest, src, n) \
747 (__extension__ (__builtin_constant_p (src) \
748 ? ((strlen (src) + 1 >= ((size_t) (n)) \
749 ? (char *) memcpy ((char *) dest, \
750 (__const char *) src, n) \
751 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
752 : __strncpy_gg (dest, src, n)))
753 #define __strncpy_cg(dest, src, srclen, n) \
754 (((srclen) % 4 == 0) \
755 ? __strncpy_by4 (dest, src, srclen, n) \
756 : (((srclen) % 2 == 0) \
757 ? __strncpy_by2 (dest, src, srclen, n) \
758 : __strncpy_byn (dest, src, srclen, n)))
760 __STRING_INLINE
char *__strncpy_by4 (char *__dest
, __const
char __src
[],
761 size_t __srclen
, size_t __n
);
763 __STRING_INLINE
char *
764 __strncpy_by4 (char *__dest
, __const
char __src
[], size_t __srclen
, size_t __n
)
766 register char *__tmp
= __dest
;
767 register int __dummy1
, __dummy2
;
776 : "=&r" (__dummy1
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__dummy2
)
777 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 4)
779 (void) memset (__tmp
, '\0', __n
- __srclen
);
783 __STRING_INLINE
char *__strncpy_by2 (char *__dest
, __const
char __src
[],
784 size_t __srclen
, size_t __n
);
786 __STRING_INLINE
char *
787 __strncpy_by2 (char *__dest
, __const
char __src
[], size_t __srclen
, size_t __n
)
789 register char *__tmp
= __dest
;
790 register int __dummy1
, __dummy2
;
793 "jz 2f\n" /* only a word */
804 : "=&q" (__dummy1
), "=r" (__tmp
), "=&r" (__src
), "=&r" (__dummy2
)
805 : "1" (__tmp
), "2" (__src
), "3" (__srclen
/ 2)
807 (void) memset (__tmp
+ 2, '\0', __n
- __srclen
);
811 __STRING_INLINE
char *__strncpy_byn (char *__dest
, __const
char __src
[],
812 size_t __srclen
, size_t __n
);
814 __STRING_INLINE
char *
815 __strncpy_byn (char *__dest
, __const
char __src
[], size_t __srclen
, size_t __n
)
817 register unsigned long int __d0
, __d1
;
818 register char *__tmp
= __dest
;
830 : "=D" (__tmp
), "=&c" (__d0
), "=&S" (__d1
)
831 : "1" (__srclen
), "0" (__tmp
),"2" (__src
)
833 (void) memset (__tmp
, '\0', __n
- __srclen
);
837 __STRING_INLINE
char *__strncpy_gg (char *__dest
, __const
char *__src
,
840 __STRING_INLINE
char *
841 __strncpy_gg (char *__dest
, __const
char *__src
, size_t __n
)
843 register char *__tmp
= __dest
;
844 register char __dummy
;
862 : "=&r" (__src
), "=&r" (__tmp
), "=&q" (__dummy
), "=&r" (__n
)
863 : "0" (__src
), "1" (__tmp
), "3" (__n
)
870 /* Append SRC onto DEST. */
871 #define _HAVE_STRING_ARCH_strcat 1
872 #define strcat(dest, src) \
873 (__extension__ (__builtin_constant_p (src) \
874 ? __strcat_c (dest, src, strlen (src) + 1) \
875 : __strcat_g (dest, src)))
877 __STRING_INLINE
char *__strcat_c (char *__dest
, __const
char __src
[],
880 __STRING_INLINE
char *
881 __strcat_c (char *__dest
, __const
char __src
[], size_t __srclen
)
884 register unsigned long int __d0
;
885 register char *__tmp
;
888 : "=D" (__tmp
), "=&c" (__d0
)
889 : "0" (__dest
), "1" (0xffffffff), "a" (0)
893 register char *__tmp
= __dest
- 1;
903 (void) memcpy (__tmp
, __src
, __srclen
);
907 __STRING_INLINE
char *__strcat_g (char *__dest
, __const
char *__src
);
909 __STRING_INLINE
char *
910 __strcat_g (char *__dest
, __const
char *__src
)
912 register char *__tmp
= __dest
- 1;
913 register char __dummy
;
926 : "=&q" (__dummy
), "=&r" (__tmp
), "=&r" (__src
)
927 : "1" (__tmp
), "2" (__src
)
933 /* Append no more than N characters from SRC onto DEST. */
934 #define _HAVE_STRING_ARCH_strncat 1
935 #define strncat(dest, src, n) \
936 (__extension__ ({ char *__dest = (dest); \
937 __builtin_constant_p (src) && __builtin_constant_p (n) \
938 ? (strlen (src) < ((size_t) (n)) \
939 ? strcat (__dest, src) \
940 : (memcpy (strchr (__dest, '\0'), \
941 (__const char *) src, n), __dest)) \
942 : __strncat_g (__dest, src, n); }))
944 __STRING_INLINE
char *__strncat_g (char *__dest
, __const
char __src
[],
947 __STRING_INLINE
char *
948 __strncat_g (char *__dest
, __const
char __src
[], size_t __n
)
950 register char *__tmp
= __dest
;
951 register char __dummy
;
966 : "=&a" (__dummy
), "=&D" (__tmp
), "=&S" (__src
), "=&r" (__n
)
967 : "0" (0), "1" (__tmp
), "2" (__src
), "3" (__n
)
988 : "=&q" (__dummy
), "=&r" (__tmp
), "=&r" (__src
), "=&r" (__n
)
989 : "1" (__tmp
), "2" (__src
), "3" (__n
)
996 /* Compare S1 and S2. */
997 #define _HAVE_STRING_ARCH_strcmp 1
998 #define strcmp(s1, s2) \
999 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1000 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1001 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1002 ? memcmp ((__const char *) s1, (__const char *) s2, \
1003 (strlen (s1) < strlen (s2) \
1004 ? strlen (s1) : strlen (s2)) + 1) \
1005 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1006 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1007 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1008 ? __strcmp_cc (s1, s2, strlen (s1)) \
1009 : __strcmp_cg (s1, s2, strlen (s1))) \
1010 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1011 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1012 ? (__builtin_constant_p (s1) \
1013 ? __strcmp_cc (s1, s2, strlen (s2)) \
1014 : __strcmp_gc (s1, s2, strlen (s2))) \
1015 : __strcmp_gg (s1, s2)))))
1017 #define __strcmp_cc(s1, s2, l) \
1018 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
1019 - (unsigned char) (s2)[0]); \
1020 if (l > 0 && __result == 0) \
1022 __result = ((unsigned char) (s1)[1] \
1023 - (unsigned char) (s2)[1]); \
1024 if (l > 1 && __result == 0) \
1026 __result = ((unsigned char) (s1)[2] \
1027 - (unsigned char) (s2)[2]); \
1028 if (l > 2 && __result == 0) \
1029 __result = ((unsigned char) (s1)[3] \
1030 - (unsigned char) (s2)[3]); \
1035 #define __strcmp_cg(s1, s2, l1) \
1036 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
1037 register int __result = (unsigned char) (s1)[0] - __s2[0];\
1038 if (l1 > 0 && __result == 0) \
1040 __result = (unsigned char) (s1)[1] - __s2[1]; \
1041 if (l1 > 1 && __result == 0) \
1043 __result = (unsigned char) (s1)[2] - __s2[2]; \
1044 if (l1 > 2 && __result == 0) \
1045 __result = (unsigned char) (s1)[3] - __s2[3]; \
1050 #define __strcmp_gc(s1, s2, l2) \
1051 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
1052 register int __result = __s1[0] - (unsigned char) (s2)[0];\
1053 if (l2 > 0 && __result == 0) \
1055 __result = __s1[1] - (unsigned char) (s2)[1]; \
1056 if (l2 > 1 && __result == 0) \
1058 __result = __s1[2] - (unsigned char) (s2)[2]; \
1059 if (l2 > 2 && __result == 0) \
1060 __result = __s1[3] - (unsigned char) (s2)[3]; \
1065 __STRING_INLINE
int __strcmp_gg (__const
char *__s1
, __const
char *__s2
);
1068 __strcmp_gg (__const
char *__s1
, __const
char *__s2
)
1071 __asm__ __volatile__
1087 : "=q" (__res
), "=&r" (__s1
), "=&r" (__s2
)
1088 : "1" (__s1
), "2" (__s2
)
1094 /* Compare N characters of S1 and S2. */
1095 #define _HAVE_STRING_ARCH_strncmp 1
1096 #define strncmp(s1, s2, n) \
1097 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1099 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1101 : __strncmp_g (s1, s2, n))))
1103 __STRING_INLINE
int __strncmp_g (__const
char *__s1
, __const
char *__s2
,
1107 __strncmp_g (__const
char *__s1
, __const
char *__s2
, size_t __n
)
1110 __asm__ __volatile__
1129 : "=q" (__res
), "=&r" (__s1
), "=&r" (__s2
), "=&r" (__n
)
1130 : "1" (__s1
), "2" (__s2
), "3" (__n
)
1136 /* Find the first occurrence of C in S. */
1137 #define _HAVE_STRING_ARCH_strchr 1
1138 #define strchr(s, c) \
1139 (__extension__ (__builtin_constant_p (c) \
1141 ? (char *) __rawmemchr (s, c) \
1142 : __strchr_c (s, ((c) & 0xff) << 8)) \
1143 : __strchr_g (s, c)))
1145 __STRING_INLINE
char *__strchr_c (__const
char *__s
, int __c
);
1147 __STRING_INLINE
char *
1148 __strchr_c (__const
char *__s
, int __c
)
1150 register unsigned long int __d0
;
1151 register char *__res
;
1152 __asm__ __volatile__
1154 "movb (%0),%%al\n\t"
1155 "cmpb %%ah,%%al\n\t"
1158 "testb %%al,%%al\n\t"
1162 : "=r" (__res
), "=&a" (__d0
)
1163 : "0" (__s
), "1" (__c
)
1168 __STRING_INLINE
char *__strchr_g (__const
char *__s
, int __c
);
1170 __STRING_INLINE
char *
1171 __strchr_g (__const
char *__s
, int __c
)
1173 register unsigned long int __d0
;
1174 register char *__res
;
1175 __asm__ __volatile__
1178 "movb (%0),%%al\n\t"
1179 "cmpb %%ah,%%al\n\t"
1182 "testb %%al,%%al\n\t"
1186 : "=r" (__res
), "=&a" (__d0
)
1187 : "0" (__s
), "1" (__c
)
1193 /* Find the first occurrence of C in S or the final NUL byte. */
1194 #define _HAVE_STRING_ARCH_strchrnul 1
1195 #define __strchrnul(s, c) \
1196 (__extension__ (__builtin_constant_p (c) \
1198 ? (char *) __rawmemchr (s, c) \
1199 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
1200 : __strchrnul_g (s, c)))
1202 __STRING_INLINE
char *__strchrnul_c (__const
char *__s
, int __c
);
1204 __STRING_INLINE
char *
1205 __strchrnul_c (__const
char *__s
, int __c
)
1207 register unsigned long int __d0
;
1208 register char *__res
;
1209 __asm__ __volatile__
1211 "movb (%0),%%al\n\t"
1212 "cmpb %%ah,%%al\n\t"
1215 "testb %%al,%%al\n\t"
1219 : "=r" (__res
), "=&a" (__d0
)
1220 : "0" (__s
), "1" (__c
)
1225 __STRING_INLINE
char *__strchrnul_g (__const
char *__s
, int __c
);
1227 __STRING_INLINE
char *
1228 __strchrnul_g (__const
char *__s
, int __c
)
1230 register unsigned long int __d0
;
1231 register char *__res
;
1232 __asm__ __volatile__
1235 "movb (%0),%%al\n\t"
1236 "cmpb %%ah,%%al\n\t"
1239 "testb %%al,%%al\n\t"
1243 : "=r" (__res
), "=&a" (__d0
)
1244 : "0" (__s
), "1" (__c
)
1249 # define strchrnul(s, c) __strchrnul (s, c)
1253 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1254 /* Find the first occurrence of C in S. This is the BSD name. */
1255 # define _HAVE_STRING_ARCH_index 1
1256 # define index(s, c) \
1257 (__extension__ (__builtin_constant_p (c) \
1258 ? __strchr_c (s, ((c) & 0xff) << 8) \
1259 : __strchr_g (s, c)))
1263 /* Find the last occurrence of C in S. */
1264 #define _HAVE_STRING_ARCH_strrchr 1
1265 #define strrchr(s, c) \
1266 (__extension__ (__builtin_constant_p (c) \
1267 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1268 : __strrchr_g (s, c)))
1271 __STRING_INLINE
char *__strrchr_c (__const
char *__s
, int __c
);
1273 __STRING_INLINE
char *
1274 __strrchr_c (__const
char *__s
, int __c
)
1276 register unsigned long int __d0
, __d1
;
1277 register char *__res
;
1278 __asm__ __volatile__
1286 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1287 : "0" (1), "1" (__s
), "2" (__c
)
1292 __STRING_INLINE
char *__strrchr_g (__const
char *__s
, int __c
);
1294 __STRING_INLINE
char *
1295 __strrchr_g (__const
char *__s
, int __c
)
1297 register unsigned long int __d0
, __d1
;
1298 register char *__res
;
1299 __asm__ __volatile__
1308 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1309 : "0" (1), "1" (__s
), "2" (__c
)
1314 __STRING_INLINE
char *__strrchr_c (__const
char *__s
, int __c
);
1316 __STRING_INLINE
char *
1317 __strrchr_c (__const
char *__s
, int __c
)
1319 register unsigned long int __d0
, __d1
;
1320 register char *__res
;
1321 __asm__ __volatile__
1325 "cmpb %%ah,%%al\n\t"
1327 "leal -1(%%esi),%0\n"
1329 "testb %%al,%%al\n\t"
1331 : "=d" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1332 : "0" (0), "1" (__s
), "2" (__c
)
1337 __STRING_INLINE
char *__strrchr_g (__const
char *__s
, int __c
);
1339 __STRING_INLINE
char *
1340 __strrchr_g (__const
char *__s
, int __c
)
1342 register unsigned long int __d0
, __d1
;
1343 register char *__res
;
1344 __asm__ __volatile__
1349 "cmpb %%ah,%%al\n\t"
1351 "leal -1(%%esi),%0\n"
1353 "testb %%al,%%al\n\t"
1355 : "=r" (__res
), "=&S" (__d0
), "=&a" (__d1
)
1356 : "0" (0), "1" (__s
), "2" (__c
)
1363 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1364 /* Find the last occurrence of C in S. This is the BSD name. */
1365 # define _HAVE_STRING_ARCH_rindex 1
1366 # define rindex(s, c) \
1367 (__extension__ (__builtin_constant_p (c) \
1368 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1369 : __strrchr_g (s, c)))
1373 /* Return the length of the initial segment of S which
1374 consists entirely of characters not in REJECT. */
1375 #define _HAVE_STRING_ARCH_strcspn 1
1376 #define strcspn(s, reject) \
1377 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1378 ? ((reject)[0] == '\0' \
1380 : ((reject)[1] == '\0' \
1381 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1382 : __strcspn_cg (s, reject, strlen (reject)))) \
1383 : __strcspn_g (s, reject)))
1385 __STRING_INLINE
size_t __strcspn_c1 (__const
char *__s
, int __reject
);
1387 __STRING_INLINE
size_t
1388 __strcspn_c1 (__const
char *__s
, int __reject
)
1390 register unsigned long int __d0
;
1391 register char *__res
;
1392 __asm__ __volatile__
1394 "movb (%0),%%al\n\t"
1396 "cmpb %%ah,%%al\n\t"
1398 "testb %%al,%%al\n\t"
1401 : "=r" (__res
), "=&a" (__d0
)
1402 : "0" (__s
), "1" (__reject
)
1404 return (__res
- 1) - __s
;
1407 __STRING_INLINE
size_t __strcspn_cg (__const
char *__s
, __const
char __reject
[],
1408 size_t __reject_len
);
1410 __STRING_INLINE
size_t
1411 __strcspn_cg (__const
char *__s
, __const
char __reject
[], size_t __reject_len
)
1413 register unsigned long int __d0
, __d1
, __d2
;
1414 register __const
char *__res
;
1415 __asm__ __volatile__
1419 "testb %%al,%%al\n\t"
1426 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1427 : "0" (__s
), "d" (__reject
), "g" (__reject_len
)
1429 return (__res
- 1) - __s
;
1432 __STRING_INLINE
size_t __strcspn_g (__const
char *__s
, __const
char *__reject
);
1435 __STRING_INLINE
size_t
1436 __strcspn_g (__const
char *__s
, __const
char *__reject
)
1438 register unsigned long int __d0
, __d1
, __d2
;
1439 register __const
char *__res
;
1440 __asm__ __volatile__
1446 "leal -1(%%ecx),%%ebx\n"
1449 "testb %%al,%%al\n\t"
1452 "movl %%ebx,%%ecx\n\t"
1457 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1458 : "r" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff)
1460 return (__res
- 1) - __s
;
1463 __STRING_INLINE
size_t
1464 __strcspn_g (__const
char *__s
, __const
char *__reject
)
1466 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1467 register __const
char *__res
;
1468 __asm__ __volatile__
1472 "leal -1(%%ecx),%%edx\n"
1475 "testb %%al,%%al\n\t"
1477 "movl %%ebx,%%edi\n\t"
1478 "movl %%edx,%%ecx\n\t"
1482 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1483 : "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__reject
), "b" (__reject
)
1485 return (__res
- 1) - __s
;
1490 /* Return the length of the initial segment of S which
1491 consists entirely of characters in ACCEPT. */
1492 #define _HAVE_STRING_ARCH_strspn 1
1493 #define strspn(s, accept) \
1494 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1495 ? ((accept)[0] == '\0' \
1497 : ((accept)[1] == '\0' \
1498 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1499 : __strspn_cg (s, accept, strlen (accept)))) \
1500 : __strspn_g (s, accept)))
1502 __STRING_INLINE
size_t __strspn_c1 (__const
char *__s
, int __accept
);
1504 __STRING_INLINE
size_t
1505 __strspn_c1 (__const
char *__s
, int __accept
)
1507 register unsigned long int __d0
;
1508 register char *__res
;
1509 /* Please note that __accept never can be '\0'. */
1510 __asm__ __volatile__
1516 : "=r" (__res
), "=&q" (__d0
)
1517 : "0" (__s
), "1" (__accept
)
1519 return (__res
- 1) - __s
;
1522 __STRING_INLINE
size_t __strspn_cg (__const
char *__s
, __const
char __accept
[],
1523 size_t __accept_len
);
1525 __STRING_INLINE
size_t
1526 __strspn_cg (__const
char *__s
, __const
char __accept
[], size_t __accept_len
)
1528 register unsigned long int __d0
, __d1
, __d2
;
1529 register __const
char *__res
;
1530 __asm__ __volatile__
1534 "testb %%al,%%al\n\t"
1541 : "=S" (__res
), "=&d" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1542 : "0" (__s
), "1" (__accept
), "g" (__accept_len
)
1544 return (__res
- 1) - __s
;
1547 __STRING_INLINE
size_t __strspn_g (__const
char *__s
, __const
char *__accept
);
1550 __STRING_INLINE
size_t
1551 __strspn_g (__const
char *__s
, __const
char *__accept
)
1553 register unsigned long int __d0
, __d1
, __d2
;
1554 register __const
char *__res
;
1555 __asm__ __volatile__
1560 "leal -1(%%ecx),%%ebx\n"
1563 "testb %%al,%%al\n\t"
1565 "movl %%edx,%%edi\n\t"
1566 "movl %%ebx,%%ecx\n\t"
1571 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1572 : "d" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__accept
)
1574 return (__res
- 1) - __s
;
1577 __STRING_INLINE
size_t
1578 __strspn_g (__const
char *__s
, __const
char *__accept
)
1580 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1581 register __const
char *__res
;
1582 __asm__ __volatile__
1586 "leal -1(%%ecx),%%edx\n"
1589 "testb %%al,%%al\n\t"
1591 "movl %%ebx,%%edi\n\t"
1592 "movl %%edx,%%ecx\n\t"
1596 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1597 : "0" (__s
), "1" (0), "2" (0xffffffff), "3" (__accept
), "b" (__accept
)
1599 return (__res
- 1) - __s
;
1604 /* Find the first occurrence in S of any character in ACCEPT. */
1605 #define _HAVE_STRING_ARCH_strpbrk 1
1606 #define strpbrk(s, accept) \
1607 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1608 ? ((accept)[0] == '\0' \
1610 : ((accept)[1] == '\0' \
1611 ? strchr (s, (accept)[0]) \
1612 : __strpbrk_cg (s, accept, strlen (accept)))) \
1613 : __strpbrk_g (s, accept)))
1615 __STRING_INLINE
char *__strpbrk_cg (__const
char *__s
, __const
char __accept
[],
1616 size_t __accept_len
);
1618 __STRING_INLINE
char *
1619 __strpbrk_cg (__const
char *__s
, __const
char __accept
[], size_t __accept_len
)
1621 register unsigned long int __d0
, __d1
, __d2
;
1622 register char *__res
;
1623 __asm__ __volatile__
1627 "testb %%al,%%al\n\t"
1638 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1639 : "0" (__s
), "d" (__accept
), "g" (__accept_len
)
1644 __STRING_INLINE
char *__strpbrk_g (__const
char *__s
, __const
char *__accept
);
1647 __STRING_INLINE
char *
1648 __strpbrk_g (__const
char *__s
, __const
char *__accept
)
1650 register unsigned long int __d0
, __d1
, __d2
;
1651 register char *__res
;
1652 __asm__ __volatile__
1654 "movl %%edx,%%edi\n\t"
1658 "leal -1(%%ecx),%%ebx\n"
1661 "testb %%al,%%al\n\t"
1663 "movl %%edx,%%edi\n\t"
1664 "movl %%ebx,%%ecx\n\t"
1673 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
1674 : "d" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
1679 __STRING_INLINE
char *
1680 __strpbrk_g (__const
char *__s
, __const
char *__accept
)
1682 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1683 register char *__res
;
1684 __asm__ __volatile__
1685 ("movl %%ebx,%%edi\n\t"
1689 "leal -1(%%ecx),%%edx\n"
1692 "testb %%al,%%al\n\t"
1694 "movl %%ebx,%%edi\n\t"
1695 "movl %%edx,%%ecx\n\t"
1703 : "=S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
1704 : "0" (__s
), "1" (0), "2" (0xffffffff), "b" (__accept
)
1711 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1712 #define _HAVE_STRING_ARCH_strstr 1
1713 #define strstr(haystack, needle) \
1714 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1715 ? ((needle)[0] == '\0' \
1717 : ((needle)[1] == '\0' \
1718 ? strchr (haystack, (needle)[0]) \
1719 : __strstr_cg (haystack, needle, strlen (needle)))) \
1720 : __strstr_g (haystack, needle)))
1722 /* Please note that this function need not handle NEEDLEs with a
1723 length shorter than two. */
1724 __STRING_INLINE
char *__strstr_cg (__const
char *__haystack
, __const
char __needle
[],
1725 size_t __needle_len
);
1727 __STRING_INLINE
char *
1728 __strstr_cg (__const
char *__haystack
, __const
char __needle
[],
1729 size_t __needle_len
)
1731 register unsigned long int __d0
, __d1
, __d2
;
1732 register char *__res
;
1733 __asm__ __volatile__
1741 "cmpb $0,-1(%%esi)\n\t"
1742 "leal 1(%%eax),%5\n\t"
1744 "xorl %%eax,%%eax\n"
1746 : "=a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
1747 : "g" (__needle_len
), "1" (__haystack
), "d" (__needle
)
1752 __STRING_INLINE
char *__strstr_g (__const
char *__haystack
, __const
char *__needle
);
1755 __STRING_INLINE
char *
1756 __strstr_g (__const
char *__haystack
, __const
char *__needle
)
1758 register unsigned long int __d0
, __d1
, __d2
;
1759 register char *__res
;
1760 __asm__ __volatile__
1765 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1766 "movl %%ecx,%%ebx\n"
1768 "movl %%edx,%%edi\n\t"
1769 "movl %%esi,%%eax\n\t"
1770 "movl %%ebx,%%ecx\n\t"
1772 "je 2f\n\t" /* also works for empty string, see above */
1773 "cmpb $0,-1(%%esi)\n\t"
1774 "leal 1(%%eax),%%esi\n\t"
1776 "xorl %%eax,%%eax\n"
1779 : "=a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
1780 : "0" (0), "1" (0xffffffff), "2" (__haystack
), "3" (__needle
),
1786 __STRING_INLINE
char *
1787 __strstr_g (__const
char *__haystack
, __const
char *__needle
)
1789 register unsigned long int __d0
, __d1
, __d2
, __d3
;
1790 register char *__res
;
1791 __asm__ __volatile__
1795 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1796 "movl %%ecx,%%edx\n"
1798 "movl %%ebx,%%edi\n\t"
1799 "movl %%esi,%%eax\n\t"
1800 "movl %%edx,%%ecx\n\t"
1802 "je 2f\n\t" /* also works for empty string, see above */
1803 "cmpb $0,-1(%%esi)\n\t"
1804 "leal 1(%%eax),%%esi\n\t"
1806 "xorl %%eax,%%eax\n"
1808 : "=a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
), "=&d" (__d3
)
1809 : "0" (0), "1" (0xffffffff), "2" (__haystack
), "3" (__needle
),
1817 /* Bit find functions. We define only the i686 version since for the other
1818 processors gcc generates good code. */
1819 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1821 # define _HAVE_STRING_ARCH_ffs 1
1822 # define ffs(word) (__builtin_constant_p (word) \
1823 ? __builtin_ffs (word) \
1824 : ({ int __cnt, __tmp; \
1825 __asm__ __volatile__ \
1828 : "=&r" (__cnt), "=r" (__tmp) \
1829 : "rm" (word), "1" (-1)); \
1833 # define ffsl(word) ffs(word)
1836 #endif /* BSD || X/Open */
1838 #undef __STRING_INLINE
1840 #endif /* use string inlines && GNU CC */