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
34 # define __STRING_INLINE inline
36 # define __STRING_INLINE extern __inline
40 /* Copy N bytes of SRC to DEST. */
41 #define _HAVE_STRING_ARCH_memcpy 1
42 #define memcpy(dest, src, n) \
43 (__extension__ (__builtin_constant_p (n) \
44 ? __memcpy_c (dest, src, n) \
45 : memcpy (dest, src, n)))
46 /* This looks horribly ugly, but the compiler can optimize it totally,
47 as the count is constant. */
48 __STRING_INLINE
void *__memcpy_c (void *__dest
, __const
void *__src
,
51 __STRING_INLINE
void *
52 __memcpy_c (void *__dest
, __const
void *__src
, size_t __n
)
54 register unsigned long int __d0
, __d1
, __d2
;
60 *(unsigned char *) __dest
= *(const unsigned char *) __src
;
63 *(unsigned short int *) __dest
= *(const unsigned short int *) __src
;
66 *(unsigned short int *) __dest
= *(const unsigned short int *) __src
;
67 *(2 + (unsigned char *) __dest
) = *(2 + (const unsigned char *) __src
);
70 *(unsigned long int *) __dest
= *(const unsigned long int *) __src
;
72 case 6: /* for ethernet addresses */
73 *(unsigned long int *) __dest
= *(const unsigned long int *) __src
;
74 *(2 + (unsigned short int *) __dest
) =
75 *(2 + (const unsigned short int *) __src
);
78 *(unsigned long int *) __dest
= *(const unsigned long int *) __src
;
79 *(1 + (unsigned long int *) __dest
) =
80 *(1 + (const unsigned long int *) __src
);
83 *(unsigned long int *) __dest
= *(const unsigned long int *) __src
;
84 *(1 + (unsigned long int *) __dest
) =
85 *(1 + (const unsigned long int *) __src
);
86 *(2 + (unsigned long int *) __dest
) =
87 *(2 + (const unsigned long int *) __src
);
90 *(unsigned long int *) __dest
= *(const unsigned long int *) __src
;
91 *(1 + (unsigned long int *) __dest
) =
92 *(1 + (const unsigned long int *) __src
);
93 *(2 + (unsigned long int *) __dest
) =
94 *(2 + (const unsigned long int *) __src
);
95 *(3 + (unsigned long int *) __dest
) =
96 *(3 + (const unsigned long int *) __src
);
99 *(unsigned long int *) __dest
= *(const unsigned long int *) __src
;
100 *(1 + (unsigned long int *) __dest
) =
101 *(1 + (const unsigned long int *) __src
);
102 *(2 + (unsigned long int *) __dest
) =
103 *(2 + (const unsigned long int *) __src
);
104 *(3 + (unsigned long int *) __dest
) =
105 *(3 + (const unsigned long int *) __src
);
106 *(4 + (unsigned long int *) __dest
) =
107 *(4 + (const unsigned long int *) __src
);
110 #define __COMMON_CODE(x) \
111 __asm__ __volatile__ \
115 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
116 : "0" (__n / 4), "1" (__dest), "2" (__src) \
125 __COMMON_CODE ("\n\tmovsb");
128 __COMMON_CODE ("\n\tmovsw");
131 __COMMON_CODE ("\n\tmovsw\n\tmovsb");
138 /* Copy N bytes of SRC to DEST, guaranteeing
139 correct behavior for overlapping strings. */
140 #define _HAVE_STRING_ARCH_memmove 1
141 __STRING_INLINE
void *
142 memmove (void *__dest
, __const
void *__src
, size_t __n
)
144 register unsigned long int __d0
, __d1
, __d2
;
150 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
151 : "0" (__n
), "1" (__src
), "2" (__dest
)
159 : "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
160 : "0" (__n
), "1" (__n
- 1 + (const char *) __src
),
161 "2" (__n
- 1 + (char *) __dest
)
167 /* Set N bytes of S to C. */
168 #define _HAVE_STRING_ARCH_memset 1
169 #define memset(s, c, n) \
170 (__extension__ (__builtin_constant_p (c) \
171 ? (__builtin_constant_p (n) \
172 ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
173 : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
174 : __memset_gg (s, c, n)))
176 __STRING_INLINE
void *__memset_cc (void *__s
, unsigned long int __pattern
,
179 __STRING_INLINE
void *
180 __memset_cc (void *__s
, unsigned long int __pattern
, size_t __n
)
182 register unsigned long int __d0
, __d1
;
188 *(unsigned char *) __s
= __pattern
;
191 *(unsigned short int *) __s
= __pattern
;
194 *(unsigned short int *) __s
= __pattern
;
195 *(2 + (unsigned char *) __s
) = __pattern
;
198 *(unsigned long *) __s
= __pattern
;
201 #define __COMMON_CODE(x) \
202 __asm__ __volatile__ \
206 : "=&c" (__d0), "=&D" (__d1) \
207 : "a" (__pattern), "0" (__n / 4), "1" (__s) \
216 __COMMON_CODE ("\n\tstosb");
219 __COMMON_CODE ("\n\tstosw");
222 __COMMON_CODE ("\n\tstosw\n\tstosb");
228 __STRING_INLINE
void *__memset_cg (void *__s
, unsigned long __c
, size_t __n
);
230 __STRING_INLINE
void *
231 __memset_cg (void *__s
, unsigned long __c
, size_t __n
)
233 register unsigned long int __d0
, __d1
;
245 : "=&c" (__d0
), "=&D" (__d1
)
246 : "a" (__c
), "q" (__n
), "0" (__n
/ 4), "1" (__s
)
251 __STRING_INLINE
void *__memset_gg (void *__s
, char __c
, size_t __n
);
253 __STRING_INLINE
void *
254 __memset_gg (void *__s
, char __c
, size_t __n
)
256 register unsigned long int __d0
, __d1
;
260 : "=&D" (__d0
), "=&c" (__d1
)
261 : "a" (__c
), "0" (__s
), "1" (__n
)
269 /* Search N bytes of S for C. */
270 #define _HAVE_STRING_ARCH_memchr 1
271 __STRING_INLINE
void *
272 memchr (__const
void *__s
, int __c
, size_t __n
)
274 register unsigned long int __d0
;
275 register void *__res
;
284 : "=D" (__res
), "=&c" (__d0
)
285 : "a" (__c
), "0" (__s
), "1" (__n
));
290 /* Return the length of S. */
291 #define _HAVE_STRING_ARCH_strlen 1
292 __STRING_INLINE
size_t
293 strlen (__const
char *__str
)
295 register unsigned long int __d0
;
296 register size_t __res
;
301 : "=c" (__res
), "=&D" (__d0
)
302 : "1" (__str
), "a" (0), "0" (0xffffffff)
308 /* Copy SRC to DEST. */
309 #define _HAVE_STRING_ARCH_strcpy 1
310 __STRING_INLINE
char *
311 strcpy (char *__dest
, __const
char *__src
)
313 register unsigned long int __d0
, __d1
;
319 "testb %%al,%%al\n\t"
321 : "=&S" (__d0
), "=&D" (__d1
)
322 : "0" (__src
), "1" (__dest
)
323 : "ax", "memory", "cc");
328 /* Copy no more than N characters of SRC to DEST. */
329 #define _HAVE_STRING_ARCH_strncpy 1
330 __STRING_INLINE
char *
331 strncpy (char *__dest
, __const
char *__src
, size_t __n
)
333 register unsigned long int __d0
, __d1
, __d2
;
341 "testb %%al,%%al\n\t"
345 : "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
346 : "0" (__src
), "1" (__dest
), "2" (__n
)
347 : "ax", "memory", "cc");
352 /* Append SRC onto DEST. */
353 #define _HAVE_STRING_ARCH_strcat 1
354 __STRING_INLINE
char *
355 strcat (char *__dest
, __const
char *__src
)
357 register unsigned long int __d0
, __d1
, __d2
, __d3
;
365 "testb %%al,%%al\n\t"
367 : "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
), "=&a" (__d3
)
368 : "0" (__src
), "1" (__dest
), "2" (0xffffffff), "3" (0)
374 /* Append no more than N characters from SRC onto DEST. */
375 #define _HAVE_STRING_ARCH_strncat 1
376 __STRING_INLINE
char *
377 strncat (char *__dest
, __const
char *__src
, size_t __n
)
379 register unsigned long int __d0
, __d1
, __d2
, __d3
;
390 "testb %%al,%%al\n\t"
397 : "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
), "=&a" (__d3
)
398 : "g" (__n
), "0" (__src
), "1" (__dest
), "2" (0xffffffff), "3" (0)
404 /* Compare S1 and S2. */
405 #define _HAVE_STRING_ARCH_strcmp 1
407 strcmp (__const
char *__s1
, __const
char *__s2
)
409 register unsigned long int __d0
, __d1
;
417 "testb %%al,%%al\n\t"
419 "xorl %%eax,%%eax\n\t"
422 "sbbl %%eax,%%eax\n\t"
425 : "=a" (__res
), "=&S" (__d0
), "=&D" (__d1
)
426 : "1" (__s1
), "2" (__s2
)
432 /* Compare N characters of S1 and S2. */
433 #define _HAVE_STRING_ARCH_strncmp 1
435 strncmp (__const
char *__s1
, __const
char *__s2
, size_t __n
)
437 register unsigned long int __d0
, __d1
, __d2
;
447 "testb %%al,%%al\n\t"
450 "xorl %%eax,%%eax\n\t"
453 "sbbl %%eax,%%eax\n\t"
456 : "=a" (__res
), "=&S" (__d0
), "=&D" (__d1
), "=&c" (__d2
)
457 : "1" (__s1
), "2" (__s2
), "3" (__n
)
463 /* Find the first occurrence of C in S. */
464 #define _HAVE_STRING_ARCH_strchr 1
465 #define strchr(s, c) \
466 (__extension__ (__builtin_constant_p (c) \
467 ? __strchr_c (s, ((c) & 0xff) << 8) \
468 : __strchr_g (s, c)))
470 __STRING_INLINE
char *__strchr_g (__const
char *__s
, int __c
);
472 __STRING_INLINE
char *
473 __strchr_g (__const
char *__s
, int __c
)
475 register unsigned long int __d0
;
476 register char *__res
;
484 "testb %%al,%%al\n\t"
489 : "=a" (__res
), "=&S" (__d0
)
490 : "0" (__c
), "1" (__s
)
495 __STRING_INLINE
char *__strchr_c (__const
char *__s
, int __c
);
497 __STRING_INLINE
char *
498 __strchr_c (__const
char *__s
, int __c
)
500 register unsigned long int __d0
;
501 register char *__res
;
508 "testb %%al,%%al\n\t"
513 : "=a" (__res
), "=&S" (__d0
)
514 : "0" (__c
), "1" (__s
)
520 /* Return the length of the initial segment of S which
521 consists entirely of characters not in REJECT. */
522 #define _HAVE_STRING_ARCH_strcspn 1
524 __STRING_INLINE
size_t
525 strcspn (__const
char *__s
, __const
char *__reject
)
527 register unsigned long int __d0
, __d1
, __d2
;
528 register char *__res
;
539 "testb %%al,%%al\n\t"
542 "movl %%ebx,%%ecx\n\t"
547 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
548 : "d" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff)
550 return (__res
- 1) - __s
;
553 __STRING_INLINE
size_t
554 strcspn (__const
char *__s
, __const
char *__reject
)
556 register unsigned long int __d0
, __d1
, __d2
, __d3
;
557 register char *__res
;
567 "testb %%al,%%al\n\t"
570 "movl %%edx,%%ecx\n\t"
574 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
575 : "g" (__reject
), "0" (__s
), "1" (0), "2" (0xffffffff)
577 return (__res
- 1) - __s
;
582 /* Return the length of the initial segment of S which
583 consists entirely of characters in ACCEPT. */
584 #define _HAVE_STRING_ARCH_strspn 1
586 __STRING_INLINE
size_t
587 strspn (__const
char *__s
, __const
char *__accept
)
589 register unsigned long int __d0
, __d1
, __d2
;
590 register char *__res
;
601 "testb %%al,%%al\n\t"
604 "movl %%ebx,%%ecx\n\t"
609 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
610 : "r" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
612 return (__res
- 1) - __s
;
615 __STRING_INLINE
size_t
616 strspn (__const
char *__s
, __const
char *__accept
)
618 register unsigned long int __d0
, __d1
, __d2
, __d3
;
619 register char *__res
;
629 "testb %%al,%%al\n\t"
632 "movl %%edx,%%ecx\n\t"
636 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
637 : "g" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
639 return (__res
- 1) - __s
;
644 /* Find the first occurrence in S of any character in ACCEPT. */
645 #define _HAVE_STRING_ARCH_strpbrk 1
647 __STRING_INLINE
char *
648 strpbrk (__const
char *__s
, __const
char *__accept
)
650 unsigned long int __d0
, __d1
, __d2
;
651 register char *__res
;
662 "testb %%al,%%al\n\t"
665 "movl %%ebx,%%ecx\n\t"
674 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&D" (__d2
)
675 : "r" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
680 __STRING_INLINE
char *
681 strpbrk (__const
char *__s
, __const
char *__accept
)
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"
705 : "=&S" (__res
), "=&a" (__d0
), "=&c" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
706 : "g" (__accept
), "0" (__s
), "1" (0), "2" (0xffffffff)
713 /* Find the first occurrence of NEEDLE in HAYSTACK. */
714 #define _HAVE_STRING_ARCH_strstr 1
716 __STRING_INLINE
char *
717 strstr (__const
char *__haystack
, __const
char *__needle
)
719 register unsigned long int __d0
, __d1
, __d2
;
720 register char *__res
;
727 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
731 "movl %%esi,%%eax\n\t"
732 "movl %%ebx,%%ecx\n\t"
734 "je 2f\n\t" /* also works for empty string, see above */
735 "xchgl %%eax,%%esi\n\t"
737 "cmpb $0,-1(%%eax)\n\t"
739 "xorl %%eax,%%eax\n\t"
742 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&D" (__d2
)
743 : "r" (__needle
), "0" (0), "1" (0xffffffff), "2" (__haystack
)
748 __STRING_INLINE
char *
749 strstr (__const
char *__haystack
, __const
char *__needle
)
751 register unsigned long int __d0
, __d1
, __d2
, __d3
;
752 register char *__res
;
758 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
762 "movl %%esi,%%eax\n\t"
763 "movl %%edx,%%ecx\n\t"
765 "je 2f\n\t" /* also works for empty string, see above */
766 "xchgl %%eax,%%esi\n\t"
768 "cmpb $0,-1(%%eax)\n\t"
770 "xorl %%eax,%%eax\n\t"
772 : "=&a" (__res
), "=&c" (__d0
), "=&S" (__d1
), "=&d" (__d2
), "=&D" (__d3
)
773 : "g" (__needle
), "0" (0), "1" (0xffffffff), "2" (__haystack
)
780 #undef __STRING_INLINE
782 #endif /* use string inlines && GNU CC */