Update.
[glibc.git] / sysdeps / i386 / bits / string.h
blob016f414a30b3fe405f1a0c5db350cda1022d46e5
1 /* Optimized, inlined string functions. i386 version.
2 Copyright (C) 1997, 1998 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. */
20 #ifndef _STRING_H
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
22 #endif
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
29 GNU CC is used. */
30 #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
31 && defined __GNUC__ && __GNUC__ >= 2
33 #ifdef __cplusplus
34 # define __STRING_INLINE inline
35 #else
36 # define __STRING_INLINE extern __inline
37 #endif
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,
49 size_t __n);
51 __STRING_INLINE void *
52 __memcpy_c (void *__dest, __const void *__src, size_t __n)
54 register unsigned long int __d0, __d1, __d2;
55 switch (__n)
57 case 0:
58 return __dest;
59 case 1:
60 *(unsigned char *) __dest = *(const unsigned char *) __src;
61 return __dest;
62 case 2:
63 *(unsigned short int *) __dest = *(const unsigned short int *) __src;
64 return __dest;
65 case 3:
66 *(unsigned short int *) __dest = *(const unsigned short int *) __src;
67 *(2 + (unsigned char *) __dest) = *(2 + (const unsigned char *) __src);
68 return __dest;
69 case 4:
70 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
71 return __dest;
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);
76 return __dest;
77 case 8:
78 *(unsigned long int *) __dest = *(const unsigned long int *) __src;
79 *(1 + (unsigned long int *) __dest) =
80 *(1 + (const unsigned long int *) __src);
81 return __dest;
82 case 12:
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);
88 return __dest;
89 case 16:
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);
97 return __dest;
98 case 20:
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);
108 return __dest;
110 #define __COMMON_CODE(x) \
111 __asm__ __volatile__ \
112 ("cld\n\t" \
113 "rep; movsl" \
115 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2) \
116 : "0" (__n / 4), "1" (__dest), "2" (__src) \
117 : "memory");
119 switch (__n % 4)
121 case 0:
122 __COMMON_CODE ("");
123 return __dest;
124 case 1:
125 __COMMON_CODE ("\n\tmovsb");
126 return __dest;
127 case 2:
128 __COMMON_CODE ("\n\tmovsw");
129 return __dest;
130 case 3:
131 __COMMON_CODE ("\n\tmovsw\n\tmovsb");
132 return __dest;
134 #undef __COMMON_CODE
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;
145 if (__dest < __src)
146 __asm__ __volatile__
147 ("cld\n\t"
148 "rep\n\t"
149 "movsb"
150 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
151 : "0" (__n), "1" (__src), "2" (__dest)
152 : "memory");
153 else
154 __asm__ __volatile__
155 ("std\n\t"
156 "rep\n\t"
157 "movsb\n\t"
158 "cld"
159 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
160 : "0" (__n), "1" (__n - 1 + (const char *) __src),
161 "2" (__n - 1 + (char *) __dest)
162 : "memory");
163 return __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,
177 size_t __n);
179 __STRING_INLINE void *
180 __memset_cc (void *__s, unsigned long int __pattern, size_t __n)
182 register unsigned long int __d0, __d1;
183 switch (__n)
185 case 0:
186 return __s;
187 case 1:
188 *(unsigned char *) __s = __pattern;
189 return __s;
190 case 2:
191 *(unsigned short int *) __s = __pattern;
192 return __s;
193 case 3:
194 *(unsigned short int *) __s = __pattern;
195 *(2 + (unsigned char *) __s) = __pattern;
196 return __s;
197 case 4:
198 *(unsigned long *) __s = __pattern;
199 return __s;
201 #define __COMMON_CODE(x) \
202 __asm__ __volatile__ \
203 ("cld\n\t" \
204 "rep; stosl" \
206 : "=&c" (__d0), "=&D" (__d1) \
207 : "a" (__pattern), "0" (__n / 4), "1" (__s) \
208 : "memory")
210 switch (__n % 4)
212 case 0:
213 __COMMON_CODE ("");
214 return __s;
215 case 1:
216 __COMMON_CODE ("\n\tstosb");
217 return __s;
218 case 2:
219 __COMMON_CODE ("\n\tstosw");
220 return __s;
221 case 3:
222 __COMMON_CODE ("\n\tstosw\n\tstosb");
223 return __s;
225 #undef __COMMON_CODE
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;
234 __asm__ __volatile__
235 ("cld\n\t"
236 "rep; stosl\n\t"
237 "testb $2,%b3\n\t"
238 "je 1f\n\t"
239 "stosw\n"
240 "1:\n\t"
241 "testb $1,%b3\n\t"
242 "je 2f\n\t"
243 "stosb\n"
244 "2:"
245 : "=&c" (__d0), "=&D" (__d1)
246 : "a" (__c), "q" (__n), "0" (__n / 4), "1" (__s)
247 : "memory");
248 return __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;
257 __asm__ __volatile__
258 ("cld\n\t"
259 "rep; stosb"
260 : "=&D" (__d0), "=&c" (__d1)
261 : "a" (__c), "0" (__s), "1" (__n)
262 : "memory");
263 return __s;
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;
276 if (__n == 0)
277 return NULL;
278 __asm__ __volatile__
279 ("cld\n\t"
280 "repne; scasb\n\t"
281 "je 1f\n\t"
282 "movl $1,%0\n"
283 "1:"
284 : "=D" (__res), "=&c" (__d0)
285 : "a" (__c), "0" (__s), "1" (__n));
286 return __res - 1;
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;
297 __asm__ __volatile__
298 ("cld\n\t"
299 "repne; scasb\n\t"
300 "notl %0"
301 : "=c" (__res), "=&D" (__d0)
302 : "1" (__str), "a" (0), "0" (0xffffffff)
303 : "cc");
304 return __res - 1;
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;
314 __asm__ __volatile__
315 ("cld\n"
316 "1:\n\t"
317 "lodsb\n\t"
318 "stosb\n\t"
319 "testb %%al,%%al\n\t"
320 "jne 1b"
321 : "=&S" (__d0), "=&D" (__d1)
322 : "0" (__src), "1" (__dest)
323 : "ax", "memory", "cc");
324 return __dest;
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;
334 __asm__ __volatile__
335 ("cld\n"
336 "1:\n\t"
337 "decl %2\n\t"
338 "js 2f\n\t"
339 "lodsb\n\t"
340 "stosb\n\t"
341 "testb %%al,%%al\n\t"
342 "jne 1b\n\t"
343 "rep; stosb\n"
344 "2:"
345 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
346 : "0" (__src), "1" (__dest), "2" (__n)
347 : "ax", "memory", "cc");
348 return __dest;
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;
358 __asm__ __volatile__
359 ("cld\n\t"
360 "repne; scasb\n\t"
361 "decl %1\n"
362 "1:\n\t"
363 "lodsb\n\t"
364 "stosb\n\t"
365 "testb %%al,%%al\n\t"
366 "jne 1b"
367 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
368 : "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
369 : "memory", "cc");
370 return __dest;
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;
380 __asm__ __volatile__
381 ("cld\n\t"
382 "repne; scasb\n\t"
383 "decl %1\n\t"
384 "movl %5,%3\n"
385 "1:\n\t"
386 "decl %3\n\t"
387 "js 2f\n\t"
388 "lodsb\n\t"
389 "stosb\n\t"
390 "testb %%al,%%al\n\t"
391 "jne 1b\n"
392 "2:\n\t"
393 "xorl %2,%2\n\t"
394 "stosb"
395 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
396 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
397 : "memory", "cc");
398 return __dest;
402 /* Compare S1 and S2. */
403 #define _HAVE_STRING_ARCH_strcmp 1
404 __STRING_INLINE int
405 strcmp (__const char *__s1, __const char *__s2)
407 register unsigned long int __d0, __d1;
408 register int __res;
409 __asm__ __volatile__
410 ("cld\n"
411 "1:\n\t"
412 "lodsb\n\t"
413 "scasb\n\t"
414 "jne 2f\n\t"
415 "testb %%al,%%al\n\t"
416 "jne 1b\n\t"
417 "xorl %%eax,%%eax\n\t"
418 "jmp 3f\n"
419 "2:\n\t"
420 "sbbl %%eax,%%eax\n\t"
421 "orb $1,%%eax\n"
422 "3:"
423 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
424 : "1" (__s1), "2" (__s2)
425 : "cc");
426 return __res;
430 /* Compare N characters of S1 and S2. */
431 #define _HAVE_STRING_ARCH_strncmp 1
432 __STRING_INLINE int
433 strncmp (__const char *__s1, __const char *__s2, size_t __n)
435 register unsigned long int __d0, __d1, __d2;
436 register int __res;
437 __asm__ __volatile__
438 ("cld\n"
439 "1:\n\t"
440 "decl %3\n\t"
441 "js 2f\n\t"
442 "lodsb\n\t"
443 "scasb\n\t"
444 "jne 3f\n\t"
445 "testb %%al,%%al\n\t"
446 "jne 1b\n"
447 "2:\n\t"
448 "xorl %%eax,%%eax\n\t"
449 "jmp 4f\n"
450 "3:\n\t"
451 "sbbl %%eax,%%eax\n\t"
452 "orb $1,%%al\n"
453 "4:"
454 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
455 : "1" (__s1), "2" (__s2), "3" (__n)
456 : "cc");
457 return __res;
461 /* Find the first occurrence of C in S. */
462 #define _HAVE_STRING_ARCH_strchr 1
463 #define strchr(s, c) \
464 (__extension__ (__builtin_constant_p (c) \
465 ? __strchr_c (s, ((c) & 0xff) << 8) \
466 : __strchr_g (s, c)))
468 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
470 __STRING_INLINE char *
471 __strchr_g (__const char *__s, int __c)
473 register unsigned long int __d0;
474 register char *__res;
475 __asm__ __volatile__
476 ("cld\n\t"
477 "movb %%al,%%ah\n"
478 "1:\n\t"
479 "lodsb\n\t"
480 "cmpb %%ah,%%al\n\t"
481 "je 2f\n\t"
482 "testb %%al,%%al\n\t"
483 "jne 1b\n\t"
484 "movl $1,%1\n"
485 "2:\n\t"
486 "movl %1,%0"
487 : "=a" (__res), "=&S" (__d0)
488 : "0" (__c), "1" (__s)
489 : "cc");
490 return __res - 1;
493 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
495 __STRING_INLINE char *
496 __strchr_c (__const char *__s, int __c)
498 register unsigned long int __d0;
499 register char *__res;
500 __asm__ __volatile__
501 ("cld\n\t"
502 "1:\n\t"
503 "lodsb\n\t"
504 "cmpb %%ah,%%al\n\t"
505 "je 2f\n\t"
506 "testb %%al,%%al\n\t"
507 "jne 1b\n\t"
508 "movl $1,%1\n"
509 "2:\n\t"
510 "movl %1,%0"
511 : "=a" (__res), "=&S" (__d0)
512 : "0" (__c), "1" (__s)
513 : "cc");
514 return __res - 1;
518 /* Return the length of the initial segment of S which
519 consists entirely of characters not in REJECT. */
520 #define _HAVE_STRING_ARCH_strcspn 1
521 #ifdef __PIC__
522 __STRING_INLINE size_t
523 strcspn (__const char *__s, __const char *__reject)
525 register unsigned long int __d0, __d1, __d2;
526 register char *__res;
527 __asm__ __volatile__
528 ("pushl %%ebx\n\t"
529 "cld\n\t"
530 "movl %4,%%edi\n\t"
531 "repne; scasb\n\t"
532 "notl %%ecx\n\t"
533 "decl %%ecx\n\t"
534 "movl %%ecx,%%ebx\n"
535 "1:\n\t"
536 "lodsb\n\t"
537 "testb %%al,%%al\n\t"
538 "je 2f\n\t"
539 "movl %4,%%edi\n\t"
540 "movl %%ebx,%%ecx\n\t"
541 "repne; scasb\n\t"
542 "jne 1b\n"
543 "2:\n\t"
544 "popl %%ebx"
545 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
546 : "r" (__reject), "1" (0), "2" (0xffffffff), "3" (__s),
547 : "cc");
548 return (__res - 1) - __s;
550 #else
551 __STRING_INLINE size_t
552 strcspn (__const char *__s, __const char *__reject)
554 register unsigned long int __d0, __d1, __d2, __d3;
555 register char *__res;
556 __asm__ __volatile__
557 ("cld\n\t"
558 "movl %5,%%edi\n\t"
559 "repne; scasb\n\t"
560 "notl %%ecx\n\t"
561 "decl %%ecx\n\t"
562 "movl %%ecx,%%edx\n"
563 "1:\n\t"
564 "lodsb\n\t"
565 "testb %%al,%%al\n\t"
566 "je 2f\n\t"
567 "movl %5,%%edi\n\t"
568 "movl %%edx,%%ecx\n\t"
569 "repne; scasb\n\t"
570 "jne 1b\n"
571 "2:"
572 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
573 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
574 : "cc");
575 return (__res - 1) - __s;
577 #endif
580 /* Return the length of the initial segment of S which
581 consists entirely of characters in ACCEPT. */
582 #define _HAVE_STRING_ARCH_strspn 1
583 #ifdef __PIC__
584 __STRING_INLINE size_t
585 strspn (__const char *__s, __const char *__accept)
587 register unsigned long int __d0, __d1, __d2;
588 register char *__res;
589 __asm__ __volatile__
590 ("pushl %%ebx\n\t"
591 "cld\n\t"
592 "movl %4,%%edi\n\t"
593 "repne; scasb\n\t"
594 "notl %%ecx\n\t"
595 "decl %%ecx\n\t"
596 "movl %%ecx,%%ebx\n"
597 "1:\n\t"
598 "lodsb\n\t"
599 "testb %%al,%%al\n\t"
600 "je 2f\n\t"
601 "movl %4,%%edi\n\t"
602 "movl %%ebx,%%ecx\n\t"
603 "repne; scasb\n\t"
604 "je 1b\n"
605 "2:\n\t"
606 "popl %%ebx"
607 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
608 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
609 : "cc");
610 return (__res - 1) - __s;
612 #else
613 __STRING_INLINE size_t
614 strspn (__const char *__s, __const char *__accept)
616 register unsigned long int __d0, __d1, __d2, __d3;
617 register char *__res;
618 __asm__ __volatile__
619 ("cld\n\t"
620 "movl %5,%%edi\n\t"
621 "repne; scasb\n\t"
622 "notl %%ecx\n\t"
623 "decl %%ecx\n\t"
624 "movl %%ecx,%%edx\n"
625 "1:\n\t"
626 "lodsb\n\t"
627 "testb %%al,%%al\n\t"
628 "je 2f\n\t"
629 "movl %5,%%edi\n\t"
630 "movl %%edx,%%ecx\n\t"
631 "repne; scasb\n\t"
632 "je 1b\n"
633 "2:"
634 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
635 : "g" (__accept), "0" (__s), "a" (0), "c" (0xffffffff)
636 : "cc");
637 return (__res - 1) - __s;
639 #endif
642 /* Find the first occurrence in S of any character in ACCEPT. */
643 #define _HAVE_STRING_ARCH_strpbrk 1
644 #ifdef __PIC__
645 __STRING_INLINE char *
646 strpbrk (__const char *__s, __const char *__accept)
648 unsigned long int __d0, __d1, __d2;
649 register char *__res;
650 __asm__ __volatile__
651 ("pushl %%ebx\n\t"
652 "cld\n\t"
653 "movl %4,%%edi\n\t"
654 "repne; scasb\n\t"
655 "notl %%ecx\n\t"
656 "decl %%ecx\n\t"
657 "movl %%ecx,%%ebx\n"
658 "1:\n\t"
659 "lodsb\n\t"
660 "testb %%al,%%al\n\t"
661 "je 2f\n\t"
662 "movl %4,%%edi\n\t"
663 "movl %%ebx,%%ecx\n\t"
664 "repne; scasb\n\t"
665 "jne 1b\n\t"
666 "decl %0\n\t"
667 "jmp 3f\n"
668 "2:\n\t"
669 "xorl %0,%0\n"
670 "3:\n\t"
671 "popl %%ebx"
672 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
673 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
674 : "cc");
675 return __res;
677 #else
678 __STRING_INLINE char *
679 strpbrk (__const char *__s, __const char *__accept)
681 register unsigned long int __d0, __d1, __d2, __d3;
682 register char *__res;
683 __asm__ __volatile__
684 ("cld\n\t"
685 "movl %4,%%edi\n\t"
686 "repne; scasb\n\t"
687 "notl %%ecx\n\t"
688 "decl %%ecx\n\t"
689 "movl %%ecx,%%edx\n"
690 "1:\n\t"
691 "lodsb\n\t"
692 "testb %%al,%%al\n\t"
693 "je 2f\n\t"
694 "movl %4,%%edi\n\t"
695 "movl %%edx,%%ecx\n\t"
696 "repne; scasb\n\t"
697 "jne 1b\n\t"
698 "decl %0\n\t"
699 "jmp 3f\n"
700 "2:\n\t"
701 "xorl %0,%0\n"
702 "3:"
703 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
704 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
705 : "cc");
706 return __res;
708 #endif
711 /* Find the first occurrence of NEEDLE in HAYSTACK. */
712 #define _HAVE_STRING_ARCH_strstr 1
713 #ifdef __PIC__
714 __STRING_INLINE char *
715 strstr (__const char *__haystack, __const char *__needle)
717 register unsigned long int __d0, __d1, __d2, __d3;
718 register char *__res;
719 __asm__ __volatile__
720 ("pushl %%ebx\n\t"
721 "cld\n\t" \
722 "movl %4,%%edi\n\t"
723 "repne; scasb\n\t"
724 "notl %%ecx\n\t"
725 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
726 "movl %%ecx,%%ebx\n"
727 "1:\n\t"
728 "movl %4,%%edi\n\t"
729 "movl %%esi,%%eax\n\t"
730 "movl %%ebx,%%ecx\n\t"
731 "repe; cmpsb\n\t"
732 "je 2f\n\t" /* also works for empty string, see above */
733 "xchgl %%eax,%%esi\n\t"
734 "incl %%esi\n\t"
735 "cmpb $0,-1(%%eax)\n\t"
736 "jne 1b\n\t"
737 "xorl %%eax,%%eax\n\t"
738 "2:\n\t"
739 "popl %%ebx"
740 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
741 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
742 : "cc");
743 return __res;
745 #else
746 __STRING_INLINE char *
747 strstr (__const char *__haystack, __const char *__needle)
749 register unsigned long int __d0, __d1, __d2, __d3;
750 register char *__res;
751 __asm__ __volatile__
752 ("cld\n\t" \
753 "movl %5,%%edi\n\t"
754 "repne; scasb\n\t"
755 "notl %%ecx\n\t"
756 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
757 "movl %%ecx,%%edx\n"
758 "1:\n\t"
759 "movl %5,%%edi\n\t"
760 "movl %%esi,%%eax\n\t"
761 "movl %%edx,%%ecx\n\t"
762 "repe; cmpsb\n\t"
763 "je 2f\n\t" /* also works for empty string, see above */
764 "xchgl %%eax,%%esi\n\t"
765 "incl %%esi\n\t"
766 "cmpb $0,-1(%%eax)\n\t"
767 "jne 1b\n\t"
768 "xorl %%eax,%%eax\n\t"
769 "2:"
770 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
771 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
772 : "cc");
773 return __res;
775 #endif
778 #undef __STRING_INLINE
780 #endif /* use string inlines && GNU CC */