Update.
[glibc.git] / sysdeps / i386 / bits / string.h
blob4bd65af7f15a80ac6c1a08b1732369ff9a06b6e5
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. */
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 %4,%2\n"
385 "1:\n\t"
386 "decl %2\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\t"
392 "jmp 3f\n"
393 "2:\n\t"
394 "xorl %3,%3\n\t"
395 "stosb\n"
396 "3:"
397 : "=&S" (__d0), "=&D" (__d1), "=&c" (__d2), "=&a" (__d3)
398 : "g" (__n), "0" (__src), "1" (__dest), "2" (0xffffffff), "3" (0)
399 : "memory", "cc");
400 return __dest;
404 /* Compare S1 and S2. */
405 #define _HAVE_STRING_ARCH_strcmp 1
406 __STRING_INLINE int
407 strcmp (__const char *__s1, __const char *__s2)
409 register unsigned long int __d0, __d1;
410 register int __res;
411 __asm__ __volatile__
412 ("cld\n"
413 "1:\n\t"
414 "lodsb\n\t"
415 "scasb\n\t"
416 "jne 2f\n\t"
417 "testb %%al,%%al\n\t"
418 "jne 1b\n\t"
419 "xorl %%eax,%%eax\n\t"
420 "jmp 3f\n"
421 "2:\n\t"
422 "sbbl %%eax,%%eax\n\t"
423 "orb $1,%%eax\n"
424 "3:"
425 : "=a" (__res), "=&S" (__d0), "=&D" (__d1)
426 : "1" (__s1), "2" (__s2)
427 : "cc");
428 return __res;
432 /* Compare N characters of S1 and S2. */
433 #define _HAVE_STRING_ARCH_strncmp 1
434 __STRING_INLINE int
435 strncmp (__const char *__s1, __const char *__s2, size_t __n)
437 register unsigned long int __d0, __d1, __d2;
438 register int __res;
439 __asm__ __volatile__
440 ("cld\n"
441 "1:\n\t"
442 "decl %3\n\t"
443 "js 2f\n\t"
444 "lodsb\n\t"
445 "scasb\n\t"
446 "jne 3f\n\t"
447 "testb %%al,%%al\n\t"
448 "jne 1b\n"
449 "2:\n\t"
450 "xorl %%eax,%%eax\n\t"
451 "jmp 4f\n"
452 "3:\n\t"
453 "sbbl %%eax,%%eax\n\t"
454 "orb $1,%%al\n"
455 "4:"
456 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
457 : "1" (__s1), "2" (__s2), "3" (__n)
458 : "cc");
459 return __res;
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;
477 __asm__ __volatile__
478 ("cld\n\t"
479 "movb %%al,%%ah\n"
480 "1:\n\t"
481 "lodsb\n\t"
482 "cmpb %%ah,%%al\n\t"
483 "je 2f\n\t"
484 "testb %%al,%%al\n\t"
485 "jne 1b\n\t"
486 "movl $1,%1\n"
487 "2:\n\t"
488 "movl %1,%0"
489 : "=a" (__res), "=&S" (__d0)
490 : "0" (__c), "1" (__s)
491 : "cc");
492 return __res - 1;
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;
502 __asm__ __volatile__
503 ("cld\n\t"
504 "1:\n\t"
505 "lodsb\n\t"
506 "cmpb %%ah,%%al\n\t"
507 "je 2f\n\t"
508 "testb %%al,%%al\n\t"
509 "jne 1b\n\t"
510 "movl $1,%1\n"
511 "2:\n\t"
512 "movl %1,%0"
513 : "=a" (__res), "=&S" (__d0)
514 : "0" (__c), "1" (__s)
515 : "cc");
516 return __res - 1;
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
523 #ifdef __PIC__
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;
529 __asm__ __volatile__
530 ("pushl %%ebx\n\t"
531 "cld\n\t"
532 "movl %4,%%edi\n\t"
533 "repne; scasb\n\t"
534 "notl %%ecx\n\t"
535 "decl %%ecx\n\t"
536 "movl %%ecx,%%ebx\n"
537 "1:\n\t"
538 "lodsb\n\t"
539 "testb %%al,%%al\n\t"
540 "je 2f\n\t"
541 "movl %4,%%edi\n\t"
542 "movl %%ebx,%%ecx\n\t"
543 "repne; scasb\n\t"
544 "jne 1b\n"
545 "2:\n\t"
546 "popl %%ebx"
547 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
548 : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
549 : "cc");
550 return (__res - 1) - __s;
552 #else
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;
558 __asm__ __volatile__
559 ("cld\n\t"
560 "movl %5,%%edi\n\t"
561 "repne; scasb\n\t"
562 "notl %%ecx\n\t"
563 "decl %%ecx\n\t"
564 "movl %%ecx,%%edx\n"
565 "1:\n\t"
566 "lodsb\n\t"
567 "testb %%al,%%al\n\t"
568 "je 2f\n\t"
569 "movl %5,%%edi\n\t"
570 "movl %%edx,%%ecx\n\t"
571 "repne; scasb\n\t"
572 "jne 1b\n"
573 "2:"
574 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
575 : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
576 : "cc");
577 return (__res - 1) - __s;
579 #endif
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
585 #ifdef __PIC__
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;
591 __asm__ __volatile__
592 ("pushl %%ebx\n\t"
593 "cld\n\t"
594 "movl %4,%%edi\n\t"
595 "repne; scasb\n\t"
596 "notl %%ecx\n\t"
597 "decl %%ecx\n\t"
598 "movl %%ecx,%%ebx\n"
599 "1:\n\t"
600 "lodsb\n\t"
601 "testb %%al,%%al\n\t"
602 "je 2f\n\t"
603 "movl %4,%%edi\n\t"
604 "movl %%ebx,%%ecx\n\t"
605 "repne; scasb\n\t"
606 "je 1b\n"
607 "2:\n\t"
608 "popl %%ebx"
609 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
610 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
611 : "cc");
612 return (__res - 1) - __s;
614 #else
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;
620 __asm__ __volatile__
621 ("cld\n\t"
622 "movl %5,%%edi\n\t"
623 "repne; scasb\n\t"
624 "notl %%ecx\n\t"
625 "decl %%ecx\n\t"
626 "movl %%ecx,%%edx\n"
627 "1:\n\t"
628 "lodsb\n\t"
629 "testb %%al,%%al\n\t"
630 "je 2f\n\t"
631 "movl %5,%%edi\n\t"
632 "movl %%edx,%%ecx\n\t"
633 "repne; scasb\n\t"
634 "je 1b\n"
635 "2:"
636 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
637 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
638 : "cc");
639 return (__res - 1) - __s;
641 #endif
644 /* Find the first occurrence in S of any character in ACCEPT. */
645 #define _HAVE_STRING_ARCH_strpbrk 1
646 #ifdef __PIC__
647 __STRING_INLINE char *
648 strpbrk (__const char *__s, __const char *__accept)
650 unsigned long int __d0, __d1, __d2;
651 register char *__res;
652 __asm__ __volatile__
653 ("pushl %%ebx\n\t"
654 "cld\n\t"
655 "movl %4,%%edi\n\t"
656 "repne; scasb\n\t"
657 "notl %%ecx\n\t"
658 "decl %%ecx\n\t"
659 "movl %%ecx,%%ebx\n"
660 "1:\n\t"
661 "lodsb\n\t"
662 "testb %%al,%%al\n\t"
663 "je 2f\n\t"
664 "movl %4,%%edi\n\t"
665 "movl %%ebx,%%ecx\n\t"
666 "repne; scasb\n\t"
667 "jne 1b\n\t"
668 "decl %0\n\t"
669 "jmp 3f\n"
670 "2:\n\t"
671 "xorl %0,%0\n"
672 "3:\n\t"
673 "popl %%ebx"
674 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
675 : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
676 : "cc");
677 return __res;
679 #else
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;
685 __asm__ __volatile__
686 ("cld\n\t"
687 "movl %5,%%edi\n\t"
688 "repne; scasb\n\t"
689 "notl %%ecx\n\t"
690 "decl %%ecx\n\t"
691 "movl %%ecx,%%edx\n"
692 "1:\n\t"
693 "lodsb\n\t"
694 "testb %%al,%%al\n\t"
695 "je 2f\n\t"
696 "movl %5,%%edi\n\t"
697 "movl %%edx,%%ecx\n\t"
698 "repne; scasb\n\t"
699 "jne 1b\n\t"
700 "decl %0\n\t"
701 "jmp 3f\n"
702 "2:\n\t"
703 "xorl %0,%0\n"
704 "3:"
705 : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
706 : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
707 : "cc");
708 return __res;
710 #endif
713 /* Find the first occurrence of NEEDLE in HAYSTACK. */
714 #define _HAVE_STRING_ARCH_strstr 1
715 #ifdef __PIC__
716 __STRING_INLINE char *
717 strstr (__const char *__haystack, __const char *__needle)
719 register unsigned long int __d0, __d1, __d2;
720 register char *__res;
721 __asm__ __volatile__
722 ("pushl %%ebx\n\t"
723 "cld\n\t" \
724 "movl %4,%%edi\n\t"
725 "repne; scasb\n\t"
726 "notl %%ecx\n\t"
727 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
728 "movl %%ecx,%%ebx\n"
729 "1:\n\t"
730 "movl %4,%%edi\n\t"
731 "movl %%esi,%%eax\n\t"
732 "movl %%ebx,%%ecx\n\t"
733 "repe; cmpsb\n\t"
734 "je 2f\n\t" /* also works for empty string, see above */
735 "xchgl %%eax,%%esi\n\t"
736 "incl %%esi\n\t"
737 "cmpb $0,-1(%%eax)\n\t"
738 "jne 1b\n\t"
739 "xorl %%eax,%%eax\n\t"
740 "2:\n\t"
741 "popl %%ebx"
742 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
743 : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
744 : "cc");
745 return __res;
747 #else
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;
753 __asm__ __volatile__
754 ("cld\n\t" \
755 "movl %5,%%edi\n\t"
756 "repne; scasb\n\t"
757 "notl %%ecx\n\t"
758 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
759 "movl %%ecx,%%edx\n"
760 "1:\n\t"
761 "movl %5,%%edi\n\t"
762 "movl %%esi,%%eax\n\t"
763 "movl %%edx,%%ecx\n\t"
764 "repe; cmpsb\n\t"
765 "je 2f\n\t" /* also works for empty string, see above */
766 "xchgl %%eax,%%esi\n\t"
767 "incl %%esi\n\t"
768 "cmpb $0,-1(%%eax)\n\t"
769 "jne 1b\n\t"
770 "xorl %%eax,%%eax\n\t"
771 "2:"
772 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&d" (__d2), "=&D" (__d3)
773 : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
774 : "cc");
775 return __res;
777 #endif
780 #undef __STRING_INLINE
782 #endif /* use string inlines && GNU CC */