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 + __n - 1), "1" (__n)
330 # define memrchr(s, c, n) __memrchr (s, c, n)
334 /* Return the length of S. */
335 #define _HAVE_STRING_ARCH_strlen 1
336 #ifndef _FORCE_INLINES
337 __STRING_INLINE size_t
338 strlen (__const char *__str)
340 register unsigned long int __d0;
341 register size_t __res;
346 : "=c" (__res), "=&D" (__d0)
347 : "1" (__str), "a" (0), "0" (0xffffffff)
353 /* Copy SRC to DEST. */
354 #define _HAVE_STRING_ARCH_strcpy 1
355 #ifndef _FORCE_INLINES
356 __STRING_INLINE char *
357 strcpy (char *__dest, __const char *__src)
359 register unsigned long int __d0, __d1;
365 "testb %%al,%%al\n\t"
367 : "=&S" (__d0), "=&D" (__d1)
368 : "0" (__src), "1" (__dest)
369 : "ax", "memory", "cc");
374 /* Copy no more than N characters of SRC to DEST. */
375 #define _HAVE_STRING_ARCH_strncpy 1
376 #ifndef _FORCE_INLINES
377 __STRING_INLINE char *
378 strncpy (char *__dest, __const char *__src, size_t __n)
380 register unsigned long int __d0, __d1, __d2;
388 "testb %%al,%%al\n\t"
392 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
393 : "0" (__src), "1" (__dest), "2" (__n)
394 : "ax", "memory", "cc");
399 /* Append SRC onto DEST. */
400 #define _HAVE_STRING_ARCH_strcat 1
401 #ifndef _FORCE_INLINES
402 __STRING_INLINE char *
403 strcat (char *__dest, __const char *__src)
405 register unsigned long int __d0, __d1, __d2, __d3;
413 "testb %%al,%%al\n\t"
415 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
416 : "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
422 /* Append no more than N characters from SRC onto DEST. */
423 #define _HAVE_STRING_ARCH_strncat 1
424 #ifndef _FORCE_INLINES
425 __STRING_INLINE char *
426 strncat (char *__dest, __const char *__src, size_t __n)
428 register unsigned long int __d0, __d1, __d2, __d3;
439 "testb %%al,%%al\n\t"
446 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
447 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
453 /* Compare S1 and S2. */
454 #define _HAVE_STRING_ARCH_strcmp 1
455 #ifndef _FORCE_INLINES
457 strcmp (__const char *__s1, __const char *__s2)
459 register unsigned long int __d0, __d1;
467 "testb %%al,%%al\n\t"
469 "xorl %%eax,%%eax\n\t"
472 "sbbl %%eax,%%eax\n\t"
475 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
476 : "1" (__s1), "2" (__s2)
482 /* Compare N characters of S1 and S2. */
483 #define _HAVE_STRING_ARCH_strncmp 1
484 #ifndef _FORCE_INLINES
486 strncmp (__const char *__s1, __const char *__s2, size_t __n)
488 register unsigned long int __d0, __d1, __d2;
498 "testb %%al,%%al\n\t"
501 "xorl %%eax,%%eax\n\t"
504 "sbbl %%eax,%%eax\n\t"
507 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
508 : "1" (__s1), "2" (__s2), "3" (__n)
514 /* Find the first occurrence of C in S. */
515 #define _HAVE_STRING_ARCH_strchr 1
516 #define strchr(s, c) \
517 (__extension__ (__builtin_constant_p (c) \
518 ? __strchr_c (s, ((c) & 0xff) << 8) \
519 : __strchr_g (s, c)))
521 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
523 __STRING_INLINE char *
524 __strchr_g (__const char *__s, int __c)
526 register unsigned long int __d0;
527 register char *__res;
535 "testb %%al,%%al\n\t"
540 : "=a" (__res), "=&S" (__d0)
541 : "0" (__c), "1" (__s)
546 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
548 __STRING_INLINE char *
549 __strchr_c (__const char *__s, int __c)
551 register unsigned long int __d0;
552 register char *__res;
559 "testb %%al,%%al\n\t"
564 : "=a" (__res), "=&S" (__d0)
565 : "0" (__c), "1" (__s)
571 /* Find the first occurrence of C in S or the final NUL byte. */
572 #define _HAVE_STRING_ARCH_strchrnul 1
573 #define __strchrnul(s, c) \
574 (__extension__ (__builtin_constant_p (c) \
576 ? (char *) __rawmemchr (s, c) \
577 : __strchrnul_c (s, ((c) & 0xff) << 8)) \
578 : __strchrnul_g (s, c)))
580 __STRING_INLINE char *__strchrnul_g (__const char *__s, int __c);
582 __STRING_INLINE char *
583 __strchrnul_g (__const char *__s, int __c)
585 register unsigned long int __d0;
586 register char *__res;
594 "testb %%al,%%al\n\t"
598 : "=a" (__res), "=&S" (__d0)
599 : "0" (__c), "1" (__s)
604 __STRING_INLINE char *__strchrnul_c (__const char *__s, int __c);
606 __STRING_INLINE char *
607 __strchrnul_c (__const char *__s, int __c)
609 register unsigned long int __d0;
610 register char *__res;
617 "testb %%al,%%al\n\t"
621 : "=a" (__res), "=&S" (__d0)
622 : "0" (__c), "1" (__s)
627 # define strchrnul(s, c) __strchrnul (s, c)
631 /* Return the length of the initial segment of S which
632 consists entirely of characters not in REJECT. */
633 #define _HAVE_STRING_ARCH_strcspn 1
634 #ifndef _FORCE_INLINES
636 __STRING_INLINE size_t
637 strcspn (__const char *__s, __const char *__reject)
639 register unsigned long int __d0, __d1, __d2;
640 register char *__res;
651 "testb %%al,%%al\n\t"
654 "movl %%ebx,%%ecx\n\t"
659 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
660 : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
662 return (__res - 1) - __s;
665 __STRING_INLINE size_t
666 strcspn (__const char *__s, __const char *__reject)
668 register unsigned long int __d0, __d1, __d2, __d3;
669 register char *__res;
679 "testb %%al,%%al\n\t"
682 "movl %%edx,%%ecx\n\t"
686 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
687 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
689 return (__res - 1) - __s;
695 /* Return the length of the initial segment of S which
696 consists entirely of characters in ACCEPT. */
697 #define _HAVE_STRING_ARCH_strspn 1
698 #ifndef _FORCE_INLINES
700 __STRING_INLINE size_t
701 strspn (__const char *__s, __const char *__accept)
703 register unsigned long int __d0, __d1, __d2;
704 register char *__res;
715 "testb %%al,%%al\n\t"
718 "movl %%ebx,%%ecx\n\t"
723 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
724 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
726 return (__res - 1) - __s;
729 __STRING_INLINE size_t
730 strspn (__const char *__s, __const char *__accept)
732 register unsigned long int __d0, __d1, __d2, __d3;
733 register char *__res;
743 "testb %%al,%%al\n\t"
746 "movl %%edx,%%ecx\n\t"
750 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
751 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
753 return (__res - 1) - __s;
759 /* Find the first occurrence in S of any character in ACCEPT. */
760 #define _HAVE_STRING_ARCH_strpbrk 1
761 #ifndef _FORCE_INLINES
763 __STRING_INLINE char *
764 strpbrk (__const char *__s, __const char *__accept)
766 unsigned long int __d0, __d1, __d2;
767 register char *__res;
778 "testb %%al,%%al\n\t"
781 "movl %%ebx,%%ecx\n\t"
790 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
791 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
796 __STRING_INLINE char *
797 strpbrk (__const char *__s, __const char *__accept)
799 register unsigned long int __d0, __d1, __d2, __d3;
800 register char *__res;
810 "testb %%al,%%al\n\t"
813 "movl %%edx,%%ecx\n\t"
821 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
822 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
830 /* Find the first occurrence of NEEDLE in HAYSTACK. */
831 #define _HAVE_STRING_ARCH_strstr 1
832 #ifndef _FORCE_INLINES
834 __STRING_INLINE char *
835 strstr (__const char *__haystack, __const char *__needle)
837 register unsigned long int __d0, __d1, __d2;
838 register char *__res;
845 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
849 "movl %%esi,%%eax\n\t"
850 "movl %%ebx,%%ecx\n\t"
852 "je 2f\n\t" /* also works for empty string, see above */
853 "xchgl %%eax,%%esi\n\t"
855 "cmpb $0,-1(%%eax)\n\t"
857 "xorl %%eax,%%eax\n\t"
860 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
861 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
866 __STRING_INLINE char *
867 strstr (__const char *__haystack, __const char *__needle)
869 register unsigned long int __d0, __d1, __d2, __d3;
870 register char *__res;
876 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
880 "movl %%esi,%%eax\n\t"
881 "movl %%edx,%%ecx\n\t"
883 "je 2f\n\t" /* also works for empty string, see above */
884 "xchgl %%eax,%%esi\n\t"
886 "cmpb $0,-1(%%eax)\n\t"
888 "xorl %%eax,%%eax\n\t"
890 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
891 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
898 #ifndef _FORCE_INLINES
899 # undef __STRING_INLINE
902 #endif /* use string inlines && GNU CC */