1 /* Optimized, inlined string functions. i386 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
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 memset(s, c, n) \
180 (__extension__ (__builtin_constant_p (c) \
181 ? (__builtin_constant_p (n) \
182 ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
183 : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
184 : __memset_gg (s, c, n)))
186 __STRING_INLINE void *__memset_cc (void *__s, unsigned long int __pattern,
189 __STRING_INLINE void *
190 __memset_cc (void *__s, unsigned long int __pattern, size_t __n)
192 register unsigned long int __d0, __d1;
195 unsigned short int __usi;
203 __u->__uc = __pattern;
206 __u->__usi = __pattern;
209 __u->__usi = __pattern;
210 __u = __extension__ ((void *) __u + 2);
211 __u->__uc = __pattern;
214 __u->__ui = __pattern;
217 #define __COMMON_CODE(x) \
218 __asm__ __volatile__ \
222 : "=&c" (__d0), "=&D" (__d1) \
223 : "a" (__pattern), "0" (__n / 4), "1" (&__u->__uc) \
232 __COMMON_CODE ("\n\tstosb");
235 __COMMON_CODE ("\n\tstosw");
238 __COMMON_CODE ("\n\tstosw\n\tstosb");
245 __STRING_INLINE void *__memset_cg (void *__s, unsigned long __c, size_t __n);
247 __STRING_INLINE void *
248 __memset_cg (void *__s, unsigned long __c, size_t __n)
250 register unsigned long int __d0, __d1;
262 : "=&c" (__d0), "=&D" (__d1)
263 : "a" (__c), "q" (__n), "0" (__n / 4), "1" (__s)
268 __STRING_INLINE void *__memset_gg (void *__s, char __c, size_t __n);
270 __STRING_INLINE void *
271 __memset_gg (void *__s, char __c, size_t __n)
273 register unsigned long int __d0, __d1;
277 : "=&D" (__d0), "=&c" (__d1)
278 : "a" (__c), "0" (__s), "1" (__n)
286 /* Search N bytes of S for C. */
287 #define _HAVE_STRING_ARCH_memchr 1
288 #ifndef _FORCE_INLINES
289 __STRING_INLINE void *
290 memchr (__const void *__s, int __c, size_t __n)
292 register unsigned long int __d0;
293 register void *__res;
302 : "=D" (__res), "=&c" (__d0)
303 : "a" (__c), "0" (__s), "1" (__n)
309 #define _HAVE_STRING_ARCH_memrchr 1
310 #ifndef _FORCE_INLINES
311 __STRING_INLINE void *
312 __memrchr (__const void *__s, int __c, size_t __n)
314 register unsigned long int __d0;
315 register void *__res;
324 : "=D" (__res), "=&c" (__d0)
325 : "a" (__c), "0" (__s), "1" (__n)
331 /* Return the length of S. */
332 #define _HAVE_STRING_ARCH_strlen 1
333 #ifndef _FORCE_INLINES
334 __STRING_INLINE size_t
335 strlen (__const char *__str)
337 register unsigned long int __d0;
338 register size_t __res;
343 : "=c" (__res), "=&D" (__d0)
344 : "1" (__str), "a" (0), "0" (0xffffffff)
350 /* Copy SRC to DEST. */
351 #define _HAVE_STRING_ARCH_strcpy 1
352 #ifndef _FORCE_INLINES
353 __STRING_INLINE char *
354 strcpy (char *__dest, __const char *__src)
356 register unsigned long int __d0, __d1;
362 "testb %%al,%%al\n\t"
364 : "=&S" (__d0), "=&D" (__d1)
365 : "0" (__src), "1" (__dest)
366 : "ax", "memory", "cc");
371 /* Copy no more than N characters of SRC to DEST. */
372 #define _HAVE_STRING_ARCH_strncpy 1
373 #ifndef _FORCE_INLINES
374 __STRING_INLINE char *
375 strncpy (char *__dest, __const char *__src, size_t __n)
377 register unsigned long int __d0, __d1, __d2;
385 "testb %%al,%%al\n\t"
389 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
390 : "0" (__src), "1" (__dest), "2" (__n)
391 : "ax", "memory", "cc");
396 /* Append SRC onto DEST. */
397 #define _HAVE_STRING_ARCH_strcat 1
398 #ifndef _FORCE_INLINES
399 __STRING_INLINE char *
400 strcat (char *__dest, __const char *__src)
402 register unsigned long int __d0, __d1, __d2, __d3;
410 "testb %%al,%%al\n\t"
412 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
413 : "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
419 /* Append no more than N characters from SRC onto DEST. */
420 #define _HAVE_STRING_ARCH_strncat 1
421 #ifndef _FORCE_INLINES
422 __STRING_INLINE char *
423 strncat (char *__dest, __const char *__src, size_t __n)
425 register unsigned long int __d0, __d1, __d2, __d3;
436 "testb %%al,%%al\n\t"
443 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
444 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
450 /* Compare S1 and S2. */
451 #define _HAVE_STRING_ARCH_strcmp 1
452 #ifndef _FORCE_INLINES
454 strcmp (__const char *__s1, __const char *__s2)
456 register unsigned long int __d0, __d1;
464 "testb %%al,%%al\n\t"
466 "xorl %%eax,%%eax\n\t"
469 "sbbl %%eax,%%eax\n\t"
472 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
473 : "1" (__s1), "2" (__s2)
479 /* Compare N characters of S1 and S2. */
480 #define _HAVE_STRING_ARCH_strncmp 1
481 #ifndef _FORCE_INLINES
483 strncmp (__const char *__s1, __const char *__s2, size_t __n)
485 register unsigned long int __d0, __d1, __d2;
495 "testb %%al,%%al\n\t"
498 "xorl %%eax,%%eax\n\t"
501 "sbbl %%eax,%%eax\n\t"
504 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
505 : "1" (__s1), "2" (__s2), "3" (__n)
511 /* Find the first occurrence of C in S. */
512 #define _HAVE_STRING_ARCH_strchr 1
513 #define strchr(s, c) \
514 (__extension__ (__builtin_constant_p (c) \
515 ? __strchr_c (s, ((c) & 0xff) << 8) \
516 : __strchr_g (s, c)))
518 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
520 __STRING_INLINE char *
521 __strchr_g (__const char *__s, int __c)
523 register unsigned long int __d0;
524 register char *__res;
532 "testb %%al,%%al\n\t"
537 : "=a" (__res), "=&S" (__d0)
538 : "0" (__c), "1" (__s)
543 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
545 __STRING_INLINE char *
546 __strchr_c (__const char *__s, int __c)
548 register unsigned long int __d0;
549 register char *__res;
556 "testb %%al,%%al\n\t"
561 : "=a" (__res), "=&S" (__d0)
562 : "0" (__c), "1" (__s)
568 /* Find the first occurrence of C in S or the final NUL byte. */
569 #define _HAVE_STRING_ARCH_strchrnul 1
570 #define __strchrnul(s, c) \
571 (__extension__ (__builtin_constant_p (c) \
573 ? (char *) __rawmemchr (s, c) \
574 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
575 : __strchrnul_g (s, c)))
577 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
579 __STRING_INLINE char *
580 __strchrnul_g (__const char *__s, int __c)
582 register unsigned long int __d0;
583 register char *__res;
591 "testb %%al,%%al\n\t"
595 : "=a" (__res), "=&S" (__d0)
596 : "0" (__c), "1" (__s)
601 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
603 __STRING_INLINE char *
604 __strchrnul_c (__const char *__s, int __c)
606 register unsigned long int __d0;
607 register char *__res;
614 "testb %%al,%%al\n\t"
618 : "=a" (__res), "=&S" (__d0)
619 : "0" (__c), "1" (__s)
624 # define strchrnul(s, c) __strchrnul (s, c)
628 /* Return the length of the initial segment of S which
629 consists entirely of characters not in REJECT. */
630 #define _HAVE_STRING_ARCH_strcspn 1
631 #ifndef _FORCE_INLINES
633 __STRING_INLINE size_t
634 strcspn (__const char *__s, __const char *__reject)
636 register unsigned long int __d0, __d1, __d2;
637 register char *__res;
648 "testb %%al,%%al\n\t"
651 "movl %%ebx,%%ecx\n\t"
656 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
657 : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
659 return (__res - 1) - __s;
662 __STRING_INLINE size_t
663 strcspn (__const char *__s, __const char *__reject)
665 register unsigned long int __d0, __d1, __d2, __d3;
666 register char *__res;
676 "testb %%al,%%al\n\t"
679 "movl %%edx,%%ecx\n\t"
683 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
684 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
686 return (__res - 1) - __s;
692 /* Return the length of the initial segment of S which
693 consists entirely of characters in ACCEPT. */
694 #define _HAVE_STRING_ARCH_strspn 1
695 #ifndef _FORCE_INLINES
697 __STRING_INLINE size_t
698 strspn (__const char *__s, __const char *__accept)
700 register unsigned long int __d0, __d1, __d2;
701 register char *__res;
712 "testb %%al,%%al\n\t"
715 "movl %%ebx,%%ecx\n\t"
720 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
721 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
723 return (__res - 1) - __s;
726 __STRING_INLINE size_t
727 strspn (__const char *__s, __const char *__accept)
729 register unsigned long int __d0, __d1, __d2, __d3;
730 register char *__res;
740 "testb %%al,%%al\n\t"
743 "movl %%edx,%%ecx\n\t"
747 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
748 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
750 return (__res - 1) - __s;
756 /* Find the first occurrence in S of any character in ACCEPT. */
757 #define _HAVE_STRING_ARCH_strpbrk 1
758 #ifndef _FORCE_INLINES
760 __STRING_INLINE char *
761 strpbrk (__const char *__s, __const char *__accept)
763 unsigned long int __d0, __d1, __d2;
764 register char *__res;
775 "testb %%al,%%al\n\t"
778 "movl %%ebx,%%ecx\n\t"
787 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
788 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
793 __STRING_INLINE char *
794 strpbrk (__const char *__s, __const char *__accept)
796 register unsigned long int __d0, __d1, __d2, __d3;
797 register char *__res;
807 "testb %%al,%%al\n\t"
810 "movl %%edx,%%ecx\n\t"
818 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
819 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
827 /* Find the first occurrence of NEEDLE in HAYSTACK. */
828 #define _HAVE_STRING_ARCH_strstr 1
829 #ifndef _FORCE_INLINES
831 __STRING_INLINE char *
832 strstr (__const char *__haystack, __const char *__needle)
834 register unsigned long int __d0, __d1, __d2;
835 register char *__res;
842 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
846 "movl %%esi,%%eax\n\t"
847 "movl %%ebx,%%ecx\n\t"
849 "je 2f\n\t" /* also works for empty string, see above */
850 "xchgl %%eax,%%esi\n\t"
852 "cmpb $0,-1(%%eax)\n\t"
854 "xorl %%eax,%%eax\n\t"
857 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
858 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
863 __STRING_INLINE char *
864 strstr (__const char *__haystack, __const char *__needle)
866 register unsigned long int __d0, __d1, __d2, __d3;
867 register char *__res;
873 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
877 "movl %%esi,%%eax\n\t"
878 "movl %%edx,%%ecx\n\t"
880 "je 2f\n\t" /* also works for empty string, see above */
881 "xchgl %%eax,%%esi\n\t"
883 "cmpb $0,-1(%%eax)\n\t"
885 "xorl %%eax,%%eax\n\t"
887 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
888 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
895 #ifndef _FORCE_INLINES
896 # undef __STRING_INLINE
899 #endif /* use string inlines && GNU CC */