1 /* Optimized, inlined string functions. i386 version.
2 Copyright (C) 1997,1998,1999,2000,2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
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 && !__BOUNDED_POINTERS__
33 #ifndef __STRING_INLINE
35 # define __STRING_INLINE inline
37 # define __STRING_INLINE extern __inline
42 /* Copy N bytes of SRC to DEST. */
43 #define _HAVE_STRING_ARCH_memcpy 1
44 #define memcpy(dest, src, n) \
45 (__extension__ (__builtin_constant_p (n) \
46 ? __memcpy_c ((dest), (src), (n)) \
47 : memcpy ((dest), (src), (n))))
48 /* This looks horribly ugly, but the compiler can optimize it totally,
49 as the count is constant. */
50 __STRING_INLINE
void *__memcpy_c (void *__dest
, __const
void *__src
,
53 __STRING_INLINE
void *
54 __memcpy_c (void *__dest
, __const
void *__src
, size_t __n
)
56 register unsigned long int __d0
, __d1
, __d2
;
59 unsigned short int __usi
;
67 __u
->__uc
= *(const unsigned char *) __src
;
70 __u
->__usi
= *(const unsigned short int *) __src
;
73 __u
->__usi
= *(const unsigned short int *) __src
;
74 __u
= (void *) __u
+ 2;
75 __u
->__uc
= *(2 + (const unsigned char *) __src
);
78 __u
->__ui
= *(const unsigned int *) __src
;
81 __u
->__ui
= *(const unsigned int *) __src
;
82 __u
= (void *) __u
+ 4;
83 __u
->__usi
= *(2 + (const unsigned short int *) __src
);
86 __u
->__ui
= *(const unsigned int *) __src
;
87 __u
= (void *) __u
+ 4;
88 __u
->__ui
= *(1 + (const unsigned int *) __src
);
91 __u
->__ui
= *(const unsigned int *) __src
;
92 __u
= (void *) __u
+ 4;
93 __u
->__ui
= *(1 + (const unsigned int *) __src
);
94 __u
= (void *) __u
+ 4;
95 __u
->__ui
= *(2 + (const unsigned int *) __src
);
98 __u
->__ui
= *(const unsigned int *) __src
;
99 __u
= (void *) __u
+ 4;
100 __u
->__ui
= *(1 + (const unsigned int *) __src
);
101 __u
= (void *) __u
+ 4;
102 __u
->__ui
= *(2 + (const unsigned int *) __src
);
103 __u
= (void *) __u
+ 4;
104 __u
->__ui
= *(3 + (const unsigned int *) __src
);
107 __u
->__ui
= *(const unsigned int *) __src
;
108 __u
= (void *) __u
+ 4;
109 __u
->__ui
= *(1 + (const unsigned int *) __src
);
110 __u
= (void *) __u
+ 4;
111 __u
->__ui
= *(2 + (const unsigned int *) __src
);
112 __u
= (void *) __u
+ 4;
113 __u
->__ui
= *(3 + (const unsigned int *) __src
);
114 __u
= (void *) __u
+ 4;
115 __u
->__ui
= *(4 + (const unsigned int *) __src
);
118 #define __COMMON_CODE(x) \
119 __asm__ __volatile__ \
123 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
124 : "0" (__n / 4), "1" (&__u->__uc), "2" (__src) \
133 __COMMON_CODE ("\n\tmovsb");
136 __COMMON_CODE ("\n\tmovsw");
139 __COMMON_CODE ("\n\tmovsw\n\tmovsb");
147 /* Copy N bytes of SRC to DEST, guaranteeing
148 correct behavior for overlapping strings. */
149 #define _HAVE_STRING_ARCH_memmove 1
150 #ifndef _FORCE_INLINES
151 __STRING_INLINE
void *
152 memmove (void *__dest
, __const
void *__src
, size_t __n
)
154 register unsigned long int __d0
, __d1
, __d2
;
160 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
161 : "0" (__n
), "1" (__src
), "2" (__dest
)
169 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
170 : "0" (__n
), "1" (__n
- 1 + (const char *) __src
),
171 "2" (__n
- 1 + (char *) __dest
)
177 /* Set N bytes of S to C. */
178 #define _HAVE_STRING_ARCH_memset 1
179 #define _USE_STRING_ARCH_memset 1
180 #define memset(s, c, n) \
181 (__extension__ (__builtin_constant_p (c) \
182 ? (__builtin_constant_p (n) \
183 ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
184 : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
185 : __memset_gg (s, c, n)))
187 __STRING_INLINE
void *__memset_cc (void *__s
, unsigned long int __pattern
,
190 __STRING_INLINE
void *
191 __memset_cc (void *__s
, unsigned long int __pattern
, size_t __n
)
193 register unsigned long int __d0
, __d1
;
196 unsigned short int __usi
;
204 __u
->__uc
= __pattern
;
207 __u
->__usi
= __pattern
;
210 __u
->__usi
= __pattern
;
211 __u
= __extension__ ((void *) __u
+ 2);
212 __u
->__uc
= __pattern
;
215 __u
->__ui
= __pattern
;
218 #define __COMMON_CODE(x) \
219 __asm__ __volatile__ \
223 : "=&c" (__d0), "=&D" (__d1) \
224 : "a" (__pattern), "0" (__n / 4), "1" (&__u->__uc) \
233 __COMMON_CODE ("\n\tstosb");
236 __COMMON_CODE ("\n\tstosw");
239 __COMMON_CODE ("\n\tstosw\n\tstosb");
246 __STRING_INLINE
void *__memset_cg (void *__s
, unsigned long __c
, size_t __n
);
248 __STRING_INLINE
void *
249 __memset_cg (void *__s
, unsigned long __c
, size_t __n
)
251 register unsigned long int __d0
, __d1
;
263 : "=&c" (__d0
), "=&D" (__d1
)
264 : "a" (__c
), "q" (__n
), "0" (__n
/ 4), "1" (__s
)
269 __STRING_INLINE
void *__memset_gg (void *__s
, char __c
, size_t __n
);
271 __STRING_INLINE
void *
272 __memset_gg (void *__s
, char __c
, size_t __n
)
274 register unsigned long int __d0
, __d1
;
278 : "=&D" (__d0
), "=&c" (__d1
)
279 : "a" (__c
), "0" (__s
), "1" (__n
)
287 /* Search N bytes of S for C. */
288 #define _HAVE_STRING_ARCH_memchr 1
289 #ifndef _FORCE_INLINES
290 __STRING_INLINE
void *
291 memchr (__const
void *__s
, int __c
, size_t __n
)
293 register unsigned long int __d0
;
294 register void *__res
;
303 : "=D" (__res
), "=&c" (__d0
)
304 : "a" (__c
), "0" (__s
), "1" (__n
),
305 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
311 #define _HAVE_STRING_ARCH_memrchr 1
312 #ifndef _FORCE_INLINES
313 __STRING_INLINE
void *
314 __memrchr (__const
void *__s
, int __c
, size_t __n
)
316 register unsigned long int __d0
;
317 register void *__res
;
327 : "=D" (__res
), "=&c" (__d0
)
328 : "a" (__c
), "0" (__s
+ __n
- 1), "1" (__n
),
329 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s
)
334 # define memrchr(s, c, n) __memrchr (s, c, n)
338 /* Return the length of S. */
339 #define _HAVE_STRING_ARCH_strlen 1
340 #ifndef _FORCE_INLINES
341 __STRING_INLINE
size_t
342 strlen (__const
char *__str
)
344 register unsigned long int __d0
;
345 register size_t __res
;
350 : "=c" (__res
), "=&D" (__d0
)
351 : "1" (__str
), "a" (0), "0" (0xffffffff),
352 "m" ( *(struct { char __x
[0xfffffff]; } *)__str
)
358 /* Copy SRC to DEST. */
359 #define _HAVE_STRING_ARCH_strcpy 1
360 #ifndef _FORCE_INLINES
361 __STRING_INLINE
char *
362 strcpy (char *__dest
, __const
char *__src
)
364 register unsigned long int __d0
, __d1
;
370 "testb %%al,%%al\n\t"
372 : "=&S" (__d0
), "=&D" (__d1
)
373 : "0" (__src
), "1" (__dest
)
374 : "ax", "memory", "cc");
379 /* Copy no more than N characters of SRC to DEST. */
380 #define _HAVE_STRING_ARCH_strncpy 1
381 #ifndef _FORCE_INLINES
382 __STRING_INLINE
char *
383 strncpy (char *__dest
, __const
char *__src
, size_t __n
)
385 register unsigned long int __d0
, __d1
, __d2
;
393 "testb %%al,%%al\n\t"
397 : "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
398 : "0" (__src
), "1" (__dest
), "2" (__n
)
399 : "ax", "memory", "cc");
404 /* Append SRC onto DEST. */
405 #define _HAVE_STRING_ARCH_strcat 1
406 #ifndef _FORCE_INLINES
407 __STRING_INLINE
char *
408 strcat (char *__dest
, __const
char *__src
)
410 register unsigned long int __d0
, __d1
, __d2
, __d3
;
418 "testb %%al,%%al\n\t"
420 : "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
), "=&a" (__d3
)
421 : "0" (__src
), "1" (__dest
), "2" (0xffffffff), "3" (0)
427 /* Append no more than N characters from SRC onto DEST. */
428 #define _HAVE_STRING_ARCH_strncat 1
429 #ifndef _FORCE_INLINES
430 __STRING_INLINE
char *
431 strncat (char *__dest
, __const
char *__src
, size_t __n
)
433 register unsigned long int __d0
, __d1
, __d2
, __d3
;
444 "testb %%al,%%al\n\t"
451 : "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
), "=&a" (__d3
)
452 : "g" (__n
), "0" (__src
), "1" (__dest
), "2" (0xffffffff), "3" (0)
458 /* Compare S1 and S2. */
459 #define _HAVE_STRING_ARCH_strcmp 1
460 #ifndef _FORCE_INLINES
462 strcmp (__const
char *__s1
, __const
char *__s2
)
464 register unsigned long int __d0
, __d1
;
472 "testb %%al,%%al\n\t"
474 "xorl %%eax,%%eax\n\t"
477 "sbbl %%eax,%%eax\n\t"
480 : "=a" (__res
), "=&S" (__d0
), "=&D" (__d1
)
481 : "1" (__s1
), "2" (__s2
),
482 "m" ( *(struct { char __x
[0xfffffff]; } *)__s1
),
483 "m" ( *(struct { char __x
[0xfffffff]; } *)__s2
)
489 /* Compare N characters of S1 and S2. */
490 #define _HAVE_STRING_ARCH_strncmp 1
491 #ifndef _FORCE_INLINES
493 strncmp (__const
char *__s1
, __const
char *__s2
, size_t __n
)
495 register unsigned long int __d0
, __d1
, __d2
;
505 "testb %%al,%%al\n\t"
508 "xorl %%eax,%%eax\n\t"
511 "sbbl %%eax,%%eax\n\t"
514 : "=a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
515 : "1" (__s1
), "2" (__s2
), "3" (__n
),
516 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s1
),
517 "m" ( *(struct { __extension__
char __x
[__n
]; } *)__s2
)
523 /* Find the first occurrence of C in S. */
524 #define _HAVE_STRING_ARCH_strchr 1
525 #define _USE_STRING_ARCH_strchr 1
526 #define strchr(s, c) \
527 (__extension__ (__builtin_constant_p (c) \
528 ? __strchr_c (s, ((c) & 0xff) << 8) \
529 : __strchr_g (s, c)))
531 __STRING_INLINE
char *__strchr_g (__const
char *__s
, int __c
);
533 __STRING_INLINE
char *
534 __strchr_g (__const
char *__s
, int __c
)
536 register unsigned long int __d0
;
537 register char *__res
;
545 "testb %%al,%%al\n\t"
550 : "=a" (__res
), "=&S" (__d0
)
551 : "0" (__c
), "1" (__s
),
552 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
557 __STRING_INLINE
char *__strchr_c (__const
char *__s
, int __c
);
559 __STRING_INLINE
char *
560 __strchr_c (__const
char *__s
, int __c
)
562 register unsigned long int __d0
;
563 register char *__res
;
570 "testb %%al,%%al\n\t"
575 : "=a" (__res
), "=&S" (__d0
)
576 : "0" (__c
), "1" (__s
),
577 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
583 /* Find the first occurrence of C in S or the final NUL byte. */
584 #define _HAVE_STRING_ARCH_strchrnul 1
585 #define __strchrnul(s, c) \
586 (__extension__ (__builtin_constant_p (c) \
588 ? (char *) __rawmemchr (s, c) \
589 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
590 : __strchrnul_g (s, c)))
592 __STRING_INLINE
char *__strchrnul_g (__const
char *__s
, int __c
);
594 __STRING_INLINE
char *
595 __strchrnul_g (__const
char *__s
, int __c
)
597 register unsigned long int __d0
;
598 register char *__res
;
606 "testb %%al,%%al\n\t"
610 : "=a" (__res
), "=&S" (__d0
)
611 : "0" (__c
), "1" (__s
),
612 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
617 __STRING_INLINE
char *__strchrnul_c (__const
char *__s
, int __c
);
619 __STRING_INLINE
char *
620 __strchrnul_c (__const
char *__s
, int __c
)
622 register unsigned long int __d0
;
623 register char *__res
;
630 "testb %%al,%%al\n\t"
634 : "=a" (__res
), "=&S" (__d0
)
635 : "0" (__c
), "1" (__s
),
636 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
641 # define strchrnul(s, c) __strchrnul (s, c)
645 /* Return the length of the initial segment of S which
646 consists entirely of characters not in REJECT. */
647 #define _HAVE_STRING_ARCH_strcspn 1
648 #ifndef _FORCE_INLINES
650 __STRING_INLINE
size_t
651 strcspn (__const
char *__s
, __const
char *__reject
)
653 register unsigned long int __d0
, __d1
, __d2
;
654 register char *__res
;
665 "testb %%al,%%al\n\t"
668 "movl %%ebx,%%ecx\n\t"
673 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
674 : "d" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff),
675 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
677 return (__res
- 1) - __s
;
680 __STRING_INLINE
size_t
681 strcspn (__const
char *__s
, __const
char *__reject
)
683 register unsigned long int __d0
, __d1
, __d2
, __d3
;
684 register char *__res
;
694 "testb %%al,%%al\n\t"
697 "movl %%edx,%%ecx\n\t"
701 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
702 : "g" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff),
703 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
705 return (__res
- 1) - __s
;
711 /* Return the length of the initial segment of S which
712 consists entirely of characters in ACCEPT. */
713 #define _HAVE_STRING_ARCH_strspn 1
714 #ifndef _FORCE_INLINES
716 __STRING_INLINE
size_t
717 strspn (__const
char *__s
, __const
char *__accept
)
719 register unsigned long int __d0
, __d1
, __d2
;
720 register char *__res
;
731 "testb %%al,%%al\n\t"
734 "movl %%ebx,%%ecx\n\t"
739 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
740 : "r" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff),
741 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
743 return (__res
- 1) - __s
;
746 __STRING_INLINE
size_t
747 strspn (__const
char *__s
, __const
char *__accept
)
749 register unsigned long int __d0
, __d1
, __d2
, __d3
;
750 register char *__res
;
760 "testb %%al,%%al\n\t"
763 "movl %%edx,%%ecx\n\t"
767 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
768 : "g" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff),
769 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
771 return (__res
- 1) - __s
;
777 /* Find the first occurrence in S of any character in ACCEPT. */
778 #define _HAVE_STRING_ARCH_strpbrk 1
779 #ifndef _FORCE_INLINES
781 __STRING_INLINE
char *
782 strpbrk (__const
char *__s
, __const
char *__accept
)
784 unsigned long int __d0
, __d1
, __d2
;
785 register char *__res
;
796 "testb %%al,%%al\n\t"
799 "movl %%ebx,%%ecx\n\t"
808 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
809 : "r" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff),
810 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
815 __STRING_INLINE
char *
816 strpbrk (__const
char *__s
, __const
char *__accept
)
818 register unsigned long int __d0
, __d1
, __d2
, __d3
;
819 register char *__res
;
829 "testb %%al,%%al\n\t"
832 "movl %%edx,%%ecx\n\t"
840 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
841 : "g" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff),
842 "m" ( *(struct { char __x
[0xfffffff]; } *)__s
)
850 /* Find the first occurrence of NEEDLE in HAYSTACK. */
851 #define _HAVE_STRING_ARCH_strstr 1
852 #ifndef _FORCE_INLINES
854 __STRING_INLINE
char *
855 strstr (__const
char *__haystack
, __const
char *__needle
)
857 register unsigned long int __d0
, __d1
, __d2
;
858 register char *__res
;
865 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
869 "movl %%esi,%%eax\n\t"
870 "movl %%ebx,%%ecx\n\t"
872 "je 2f\n\t" /* also works for empty string, see above */
873 "xchgl %%eax,%%esi\n\t"
875 "cmpb $0,-1(%%eax)\n\t"
877 "xorl %%eax,%%eax\n\t"
880 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
881 : "r" (__needle
), "0" (0), "1" (0xffffffff), "2" (__haystack
)
886 __STRING_INLINE
char *
887 strstr (__const
char *__haystack
, __const
char *__needle
)
889 register unsigned long int __d0
, __d1
, __d2
, __d3
;
890 register char *__res
;
896 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
900 "movl %%esi,%%eax\n\t"
901 "movl %%edx,%%ecx\n\t"
903 "je 2f\n\t" /* also works for empty string, see above */
904 "xchgl %%eax,%%esi\n\t"
906 "cmpb $0,-1(%%eax)\n\t"
908 "xorl %%eax,%%eax\n\t"
910 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
911 : "g" (__needle
), "0" (0), "1" (0xffffffff), "2" (__haystack
)
918 #ifndef _FORCE_INLINES
919 # undef __STRING_INLINE
922 #endif /* use string inlines && GNU CC */