Don't define anything is __NO_STRING_INLINES is defined.
[kopensolaris-gnu/glibc.git] / sysdeps / i386 / bits / string.h
1 /* Optimized, inlined string functions.  i386 version.
2    Copyright (C) 1997 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4
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.
9
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.
14
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.  */
19
20 #ifndef _STRING_H
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
22 #endif
23
24 /* The ix86 processors can access unaligned multi-byte variables.  */
25 #define _STRING_ARCH_unaligned  1
26
27
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
32
33 #ifdef __cplusplus
34 # define __STRING_INLINE inline
35 #else
36 # define __STRING_INLINE extern __inline
37 #endif
38
39
40 /* Copy N bytes of SRC to DEST.  */
41 #define memcpy(dest, src, n) \
42   (__extension__ (__builtin_constant_p (n)                                    \
43                   ? __memcpy_c (dest, src, n)                                 \
44                   : memcpy (dest, src, n)))
45 /* This looks horribly ugly, but the compiler can optimize it totally,
46    as the count is constant.  */
47 __STRING_INLINE void *
48 __memcpy_c (void *__dest, __const void *__src, size_t __n)
49 {
50   switch (__n)
51     {
52     case 0:
53       return __dest;
54     case 1:
55       *(unsigned char *) __dest = *(const unsigned char *) __src;
56       return __dest;
57     case 2:
58       *(unsigned short int *) __dest = *(const unsigned short int *) __src;
59       return __dest;
60     case 3:
61       *(unsigned short int *) __dest = *(const unsigned short int *) __src;
62       *(2 + (unsigned char *) __dest) = *(2 + (const unsigned char *) __src);
63       return __dest;
64     case 4:
65       *(unsigned long int *) __dest = *(const unsigned long int *) __src;
66       return __dest;
67     case 6:     /* for ethernet addresses */
68       *(unsigned long int *) __dest = *(const unsigned long int *) __src;
69       *(2 + (unsigned short int *) __dest) =
70         *(2 + (const unsigned short int *) __src);
71       return __dest;
72     case 8:
73       *(unsigned long int *) __dest = *(const unsigned long int *) __to;
74       *(1 + (unsigned long int *) __dest) =
75         *(1 + (const unsigned long int *) __src);
76       return __dest;
77     case 12:
78       *(unsigned long int *) __dest = *(const unsigned long int *) __src;
79       *(1 + (unsigned long int *) __dest) =
80         *(1 + (const unsigned long int *) __src);
81       *(2 + (unsigned long int *) __dest) =
82         *(2 + (const unsigned long int *) __src);
83       return __dest;
84     case 16:
85       *(unsigned long int *) __dest = *(const unsigned long int *) __src;
86       *(1 + (unsigned long int *) __dest) =
87         *(1 + (const unsigned long int *) __src);
88       *(2 + (unsigned long int *) __dest) =
89         *(2 + (const unsigned long int *) __src);
90       *(3 + (unsigned long int *) __dest) =
91         *(3 + (const unsigned long int *) __src);
92       return __dest;
93     case 20:
94       *(unsigned long int *) __dest = *(const unsigned long int *) __src;
95       *(1 + (unsigned long int *) __dest) =
96         *(1 + (const unsigned long int *) __src);
97       *(2 + (unsigned long int *) __dest) =
98         *(2 + (const unsigned long int *) __src);
99       *(3 + (unsigned long int *) __dest) =
100         *(3 + (const unsigned long int *) __src);
101       *(4 + (unsigned long int *) __dest) =
102         *(4 + (const unsigned long int *) __src);
103       return __dest;
104     }
105 #define __COMMON_CODE(x) \
106   __asm__ __volatile__                                                        \
107     ("cld\n\t"                                                                \
108      "rep; movsl"                                                             \
109      x                                                                        \
110      : /* no outputs */                                                       \
111      : "c" (__n / 4), "D" (__dest), "S" (__src)                               \
112      : "cx", "di", "si", "memory");
113
114   switch (__n % 4)
115     {
116     case 0:
117       __COMMON_CODE ("");
118       return __dest;
119     case 1:
120       __COMMON_CODE ("\n\tmovsb");
121       return __dest;
122     case 2:
123       __COMMON_CODE ("\n\tmovsw");
124       return __dest;
125     case 3:
126       __COMMON_CODE ("\n\tmovsw\n\tmovsb");
127       return __dest;
128     }
129 #undef __COMMON_CODE
130 }
131
132
133 /* Copy N bytes of SRC to DEST, guaranteeing
134    correct behavior for overlapping strings.  */
135 __STRING_INLINE void *
136 memmove (void *__dest, __const void *__src, size_t __n)
137 {
138   if (__dest < __src)
139     __asm__ __volatile__
140       ("cld\n\t"
141        "rep\n\t"
142        "movsb"
143        : /* no output */
144        : "c" (__n), "S" (__src),"D" (__dest)
145        : "cx", "si", "di");
146   else
147     __asm__ __volatile__
148       ("std\n\t"
149        "rep\n\t"
150        "movsb\n\t"
151        "cld"
152        : /* no output */
153        : "c" (__n), "S" (__n - 1 + (const char *) __src),
154          "D" (__n - 1 + (char *) __dest)
155        : "cx", "si", "di", "memory");
156   return __dest;
157 }
158
159
160 /* Set N bytes of S to C.  */
161 #define memset(s, c, n) \
162   (__extension__ (__builtin_constant_p (c)                                    \
163                   ? (__builtin_constant_p (n)                                 \
164                      ? __memset_cc (s, 0x01010101UL * (unsigned char) (c), n) \
165                      : __memset_cg (s, 0x01010101UL * (unsigned char) (c), n))\
166                   : __memset_gg (s, c, n)))
167
168 __STRING_INLINE void *
169 __memset_cc (void *__s, unsigned long int __pattern, size_t __n)
170 {
171   switch (__n)
172     {
173     case 0:
174       return s;
175     case 1:
176       *(unsigned char *) __s = __pattern;
177       return __s;
178     case 2:
179       *(unsigned short int *) __s = __pattern;
180       return s;
181     case 3:
182       *(unsigned short int *) __s = __pattern;
183       *(2 + (unsigned char *) __s) = __pattern;
184       return __s;
185     case 4:
186       *(unsigned long *) __s = __pattern;
187       return __s;
188         }
189 #define __COMMON_CODE(x) \
190   __asm__ __volatile__                                                        \
191     ("cld\n\t"                                                                \
192      "rep; stosl"                                                             \
193      x                                                                        \
194      : /* no outputs */                                                       \
195      : "a" (__pattern),"c" (__n / 4), "D" (__s)                               \
196      : "cx", "di", "memory")
197
198   switch (__n % 4)
199     {
200     case 0:
201       __COMMON_CODE ("");
202       return __s;
203     case 1:
204       __COMMON_CODE ("\n\tstosb");
205       return __s;
206     case 2:
207       __COMMON__CODE ("\n\tstosw");
208       return s;
209     case 3:
210       __COMMON_CODE ("\n\tstosw\n\tstosb");
211       return __s;
212     }
213 #undef __COMMON_CODE
214 }
215
216 __STRING_INLINE void *
217 __memset_cg (void *__s, unsigned long __c, size_t __n)
218 {
219   __asm__ __volatile__
220     ("cld\n\t"
221      "rep; stosl\n\t"
222      "testb     $2,%b1\n\t"
223      "je        1f\n\t"
224      "stosw\n"
225      "1:\n\t"
226      "testb     $1,%b1\n\t"
227      "je        2f\n\t"
228      "stosb\n"
229      "2:"
230      : /* no output */
231      : "a" (__c), "q" (__n), "c" (__n / 4), "D" (__s)
232      : "cx", "di", "memory");
233   return __s;
234 }
235
236 __STRING_INLINE void *
237 __memset_gg (void *__s, char __c, size_t __n)
238 {
239   __asm__ __volatile__
240     ("cld\n\t"
241      "rep; stosb"
242      : /* no output */
243      : "a" (__c),"D" (__s), "c" (__n)
244      : "cx", "di", "memory");
245   return __s;
246 }
247
248
249
250
251 /* Search N bytes of S for C.  */
252 __STRING_INLINE void *
253 memchr (__const void *__s, int __c, size_t __n)
254 {
255   register void *__res;
256   if (count == 0)
257     return NULL;
258   __asm__ __volatile__
259     ("cld\n\t"
260      "repne; scasb\n\t"
261      "je        1f\n\t"
262      "movl      $1,%0\n"
263      "1:\n\t"
264      "decl      %0"
265      : "=D" (__res)
266      : "a" (__c), "D" (__s), "c" (__n)
267      : "cx", "cc");
268   return __res;
269 }
270
271
272 /* Search N bytes of S for C.  */
273 __STRING_INLINE void *
274 memchr (__const void *__s, int __c, size_t __n)
275 {
276   register void *__res;
277   if (count == 0)
278     return NULL;
279   __asm__ __volatile__
280     ("cld\n\t"
281      "repne\n\t"
282      "scasb\n\t"
283      "je        1f\n\t"
284      "movl      $1,%0\n"
285      "1:"
286      : "=D" (__res)
287      : "a" (__c), "0" (__s), "c" (__n)
288      : "cx");
289   return __res - 1;
290 }
291
292
293 /* Return the length of S.  */
294 __STRING_INLINE size_t
295 strlen (__const char *__str)
296 {
297   register size_t __res;
298   __asm__ __volatile__
299     ("cld\n\t"
300      "repne; scasb\n\t"
301      "notl %0"
302      : "=c" (__res)
303      : "D" (__str), "a" (0), "0" (0xffffffff)
304      : "di", "cc");
305   return __res - 1;
306 }
307
308
309 /* Copy SRC to DEST.  */
310 __STRING_INLINE char *
311 strcpy (char *__dest, __const char *__src)
312 {
313   __asm__ __volatile__
314     ("cld\n"
315      "1:\n\t"
316      "lodsb\n\t"
317      "stosb\n\t"
318      "testb     %%al,%%al\n\t"
319      "jne       1b"
320      : /* no output */
321      : "S" (__src), "D" (__dest)
322      : "si", "di", "ax", "memory", "cc");
323   return __dest;
324 }
325
326
327 /* Copy no more than N characters of SRC to DEST.  */
328 __STRING_INLINE char *
329 strncpy (char *__dest, __const char *__src, size_t __n)
330 {
331   __asm__ __volatile__
332     ("cld\n"
333      "1:\n\t"
334      "decl      %2\n\t"
335      "js        2f\n\t"
336      "lodsb\n\t"
337      "stosb\n\t"
338      "testb     %%al,%%al\n\t"
339      "jne       1b\n\t"
340      "rep; stosb\n"
341      "2:"
342      : /* no output */
343      : "S" (__src), "D" (__dest), "c" (__n)
344      : "si", "di", "ax", "cx", "memory", "cc");
345   return __dest;
346 }
347
348
349 /* Append SRC onto DEST.  */
350 __STRING_INLINE char *
351 strcat (char *__dest, __const char *__src)
352 {
353   __asm__ __volatile__
354     ("cld\n\t"
355      "repne; scasb\n\t"
356      "decl      %1\n"
357      "1:\n\t"
358      "lodsb\n\t"
359      "stosb\n\t"
360      "testb     %%al,%%al\n\t"
361      "jne       1b"
362      : /* no output */
363      : "S" (__src), "D" (__dest), "a" (0), "c" (0xffffffff)
364      : "si", "di", "ax", "cx", "memory", "cc");
365   return __dest;
366 }
367
368
369 /* Append no more than N characters from SRC onto DEST.  */
370 __STRING_INLINE char *
371 strncat (char *__dest, __const char *__src, size_t __n)
372 {
373   __asm__ __volatile__
374     ("cld\n\t"
375      "repne; scasb\n\t"
376      "decl      %1\n\t"
377      "movl      %4,%3\n"
378      "1:\n\t"
379      "decl      %3\n\t"
380      "js        2f\n\t"
381      "lodsb\n\t"
382      "stosb\n\t"
383      "testb     %%al,%%al\n\t"
384      "jne       1b\n"
385      "2:\n\t"
386      "xorl      %2,%2\n\t"
387      "stosb"
388      : /* no output */
389      : "S" (__src), "D" (__dest), "a" (0), "c" (0xffffffff), "g" (__n)
390      : "si", "di", "ax", "cx", "memory", "cc");
391   return __dest;
392 }
393
394
395 /* Compare S1 and S2.  */
396 __STRING_INLINE int
397 strcmp (__const char *__s1, __const char *__s2)
398 {
399   register int __res;
400   __asm__ __volatile__
401     ("cld\n"
402      "1:\n\t"
403      "lodsb\n\t"
404      "scasb\n\t"
405      "jne       2f\n\t"
406      "testb     %%al,%%al\n\t"
407      "jne       1b\n\t"
408      "xorl      %%eax,%%eax\n\t"
409      "jmp       3f\n"
410      "2:\n\t"
411      "sbbl      %%eax,%%eax\n\t"
412      "orb       $1,%%eax\n"
413      "3:"
414      : "=a" (__res)
415      : "S" (__s1), "D" (__s2)
416      : "si", "di", "cc");
417   return __res;
418 }
419
420
421 /* Compare N characters of S1 and S2.  */
422 __STRING_INLINE int
423 strncmp (__const char *__s1, __const char *__s2, size_t __n)
424 {
425   register int __res;
426   __asm__ __volatile__
427     ("cld\n"
428      "1:\n\t"
429      "decl      %3\n\t"
430      "js        2f\n\t"
431      "lodsb\n\t"
432      "scasb\n\t"
433      "jne       3f\n\t"
434      "testb     %%al,%%al\n\t"
435      "jne       1b\n"
436      "2:\n\t"
437      "xorl      %%eax,%%eax\n\t"
438      "jmp       4f\n"
439      "3:\n\t"
440      "sbbl      %%eax,%%eax\n\t"
441      "orb       $1,%%al\n"
442      "4:"
443      : "=a" (__res)
444      : "S" (__s1), "D" (__s2), "c" (__n)
445      : "si", "di", "cx", "cc");
446   return __res;
447 }
448
449
450 /* Find the first occurrence of C in S.  */
451 #define strchr(s, c) \
452   (__extension__ (__builtin_constant_p (c)                                    \
453                   ? __strchr_c (s, ((c) & 0xff) << 8)                         \
454                   : __strchr_g (s, c)))
455
456 __STRING_INLINE char *
457 __strchr_g (__const char *__s, int __c)
458 {
459   register char *__res;
460   __asm__ __volatile__
461     ("cld\n\t"
462      "movb      %%al,%%ah\n"
463      "1:\n\t"
464      "lodsb\n\t"
465      "cmpb      %%ah,%%al\n\t"
466      "je        2f\n\t"
467      "testb     %%al,%%al\n\t"
468      "jne       1b\n\t"
469      "movl      $1,%1\n"
470      "2:\n\t"
471      "movl      %1,%0"
472      : "=a" (__res)
473      : "S" (__s), "0" (__c)
474      : "si", "cc");
475   return __res - 1;
476 }
477
478 __STRING_INLINE char *
479 __strchr_c (__const char *__s, int __c)
480 {
481   register char *__res;
482   __asm__ __volatile__
483     ("cld\n\t"
484      "1:\n\t"
485      "lodsb\n\t"
486      "cmpb      %%ah,%%al\n\t"
487      "je        2f\n\t"
488      "testb     %%al,%%al\n\t"
489      "jne       1b\n\t"
490      "movl      $1,%1\n"
491      "2:\n\t"
492      "movl      %1,%0"
493      : "=a" (__res)
494      : "S" (__s), "0" (__c)
495      : "si", "cc");
496   return __res - 1;
497 }
498
499
500 /* Return the length of the initial segment of S which
501    consists entirely of characters not in REJECT.  */
502 #ifdef __PIC__
503 __STRING_INLINE size_t
504 strcspn (__const char *__s, __const char *__reject)
505 {
506   register char *__res;
507   __asm__ __volatile__
508     ("pushl     %%ebx\n\t"
509      "cld\n\t"
510      "movl      %4,%%edi\n\t"
511      "repne; scasb\n\t"
512      "notl      %%ecx\n\t"
513      "decl      %%ecx\n\t"
514      "movl      %%ecx,%%ebx\n"
515      "1:\n\t"
516      "lodsb\n\t"
517      "testb     %%al,%%al\n\t"
518      "je        2f\n\t"
519      "movl      %4,%%edi\n\t"
520      "movl      %%ebx,%%ecx\n\t"
521      "repne; scasb\n\t"
522      "jne       1b\n"
523      "2:\n\t"
524      "popl      %%ebx"
525      : "=S" (__res)
526      : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__reject)
527      : "ax", "cx", "di", "cc");
528   return (__res - 1) - __s;
529 }
530 #else
531 __STRING_INLINE size_t
532 strcspn (__const char *__s, __const char *__reject)
533 {
534   register char *__res;
535   __asm__ __volatile__
536     ("cld\n\t"
537      "movl      %4,%%edi\n\t"
538      "repne; scasb\n\t"
539      "notl      %%ecx\n\t"
540      "decl      %%ecx\n\t"
541      "movl      %%ecx,%%edx\n"
542      "1:\n\t"
543      "lodsb\n\t"
544      "testb     %%al,%%al\n\t"
545      "je        2f\n\t"
546      "movl      %4,%%edi\n\t"
547      "movl      %%edx,%%ecx\n\t"
548      "repne; scasb\n\t"
549      "jne       1b\n"
550      "2:"
551      : "=S" (__res)
552      : "a" (0), "c" (0xffffffff),"0" (__s), "g" (__reject)
553      : "ax", "cx", "dx", "di", "cc");
554   return (__res - 1) - __s;
555 }
556 #endif
557
558
559 /* Return the length of the initial segment of S which
560    consists entirely of characters in ACCEPT.  */
561 #ifdef __PIC__
562 __STRING_INLINE size_t
563 strspn (__const char *__s, __const char *__accept)
564 {
565   register char *__res;
566   __asm__ __volatile__
567     ("pushl     %%ebx\n\t"
568      "cld\n\t"
569      "movl      %4,%%edi\n\t"
570      "repne; scasb\n\t"
571      "notl      %%ecx\n\t"
572      "decl      %%ecx\n\t"
573      "movl      %%ecx,%%ebx\n"
574      "1:\n\t"
575      "lodsb\n\t"
576      "testb     %%al,%%al\n\t"
577      "je        2f\n\t"
578      "movl      %4,%%edi\n\t"
579      "movl      %%ebx,%%ecx\n\t"
580      "repne; scasb\n\t"
581      "je        1b\n"
582      "2:\n\t"
583      "popl      %%ebx"
584      : "=S" (__res)
585      : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
586      : "ax", "cx", "di", "cc");
587   return (__res - 1) - __s;
588 }
589 #else
590 __STRING_INLINE size_t
591 strspn (__const char *__s, __const char *__accept)
592 {
593   register char *__res;
594   __asm__ __volatile__
595     ("cld\n\t"
596      "movl      %4,%%edi\n\t"
597      "repne; scasb\n\t"
598      "notl      %%ecx\n\t"
599      "decl      %%ecx\n\t"
600      "movl      %%ecx,%%edx\n"
601      "1:\n\t"
602      "lodsb\n\t"
603      "testb     %%al,%%al\n\t"
604      "je        2f\n\t"
605      "movl      %4,%%edi\n\t"
606      "movl      %%edx,%%ecx\n\t"
607      "repne; scasb\n\t"
608      "je        1b\n"
609      "2:"
610      : "=S" (__res)
611      : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
612      : "ax", "cx", "dx", "di", "cc");
613   return (__res - 1) - __s;
614 }
615 #endif
616
617
618 /* Find the first occurrence in S of any character in ACCEPT.  */
619 #ifdef __PIC__
620 __STRING_INLINE char *
621 strpbrk (__const char *__s, __const char *__accept)
622 {
623   register char *__res;
624   __asm__ __volatile__
625     ("pushl     %%ebx\n\t"
626      "cld\n\t"
627      "movl      %4,%%edi\n\t"
628      "repne; scasb\n\t"
629      "notl      %%ecx\n\t"
630      "decl      %%ecx\n\t"
631      "movl      %%ecx,%%ebx\n"
632      "1:\n\t"
633      "lodsb\n\t"
634      "testb     %%al,%%al\n\t"
635      "je        2f\n\t"
636      "movl      %4,%%edi\n\t"
637      "movl      %%ebx,%%ecx\n\t"
638      "repne; scasb\n\t"
639      "jne       1b\n\t"
640      "decl      %0\n\t"
641      "jmp       3f\n"
642      "2:\n\t"
643      "xorl      %0,%0\n"
644      "3:\n\t"
645      "popl      %%ebx"
646      : "=S" (__res)
647      : "a" (0), "c" (0xffffffff), "0" (__s), "r" (__accept)
648      : "ax", "cx", "di", "cc");
649   return __res;
650 }
651 #else
652 __STRING_INLINE char *
653 strpbrk (__const char *__s, __const char *__accept)
654 {
655   register char *__res;
656   __asm__ __volatile__
657     ("cld\n\t"
658      "movl      %4,%%edi\n\t"
659      "repne; scasb\n\t"
660      "notl      %%ecx\n\t"
661      "decl      %%ecx\n\t"
662      "movl      %%ecx,%%edx\n"
663      "1:\n\t"
664      "lodsb\n\t"
665      "testb     %%al,%%al\n\t"
666      "je        2f\n\t"
667      "movl      %4,%%edi\n\t"
668      "movl      %%edx,%%ecx\n\t"
669      "repne; scasb\n\t"
670      "jne       1b\n\t"
671      "decl      %0\n\t"
672      "jmp       3f\n"
673      "2:\n\t"
674      "xorl      %0,%0\n"
675      "3:"
676      : "=S" (__res)
677      : "a" (0), "c" (0xffffffff), "0" (__s), "g" (__accept)
678      : "ax", "cx", "dx", "di", "cc");
679   return __res;
680 }
681 #endif
682
683
684 /* Find the first occurrence of NEEDLE in HAYSTACK.  */
685 #ifdef __PIC__
686 __STRING_INLINE char *
687 strstr (__const char *__haystack, __const char *__needle)
688 {
689   register char *__res;
690   __asm__ __volatile__
691     ("pushl     %%ebx\n\t"
692      "cld\n\t" \
693      "movl      %4,%%edi\n\t"
694      "repne; scasb\n\t"
695      "notl      %%ecx\n\t"
696      "decl      %%ecx\n\t"      /* NOTE! This also sets Z if searchstring='' */
697      "movl      %%ecx,%%ebx\n"
698      "1:\n\t"
699      "movl      %4,%%edi\n\t"
700      "movl      %%esi,%%eax\n\t"
701      "movl      %%ebx,%%ecx\n\t"
702      "repe; cmpsb\n\t"
703      "je        2f\n\t"         /* also works for empty string, see above */
704      "xchgl     %%eax,%%esi\n\t"
705      "incl      %%esi\n\t"
706      "cmpb      $0,-1(%%eax)\n\t"
707      "jne       1b\n\t"
708      "xorl      %%eax,%%eax\n\t"
709      "2:\n\t"
710      "popl      %%ebx"
711      : "=a" (__res)
712      : "0" (0), "c" (0xffffffff), "S" (__haystack), "r" (__needle)
713      : "cx", "di", "si", "cc");
714   return __res;
715 }
716 #else
717 __STRING_INLINE char *
718 strstr (__const char *__haystack, __const char *__needle)
719 {
720   register char *__res;
721   __asm__ __volatile__
722     ("cld\n\t" \
723      "movl      %4,%%edi\n\t"
724      "repne; scasb\n\t"
725      "notl      %%ecx\n\t"
726      "decl      %%ecx\n\t"      /* NOTE! This also sets Z if searchstring='' */
727      "movl      %%ecx,%%edx\n"
728      "1:\n\t"
729      "movl      %4,%%edi\n\t"
730      "movl      %%esi,%%eax\n\t"
731      "movl      %%edx,%%ecx\n\t"
732      "repe; cmpsb\n\t"
733      "je        2f\n\t"         /* also works for empty string, see above */
734      "xchgl     %%eax,%%esi\n\t"
735      "incl      %%esi\n\t"
736      "cmpb      $0,-1(%%eax)\n\t"
737      "jne       1b\n\t"
738      "xorl      %%eax,%%eax\n\t"
739      "2:"
740      : "=a" (__res)
741      : "0" (0), "c" (0xffffffff), "S" (__haystack), "g" (__needle)
742      : "cx", "dx", "di", "si", "cc");
743   return __res;
744 }
745 #endif
746
747
748 #undef __STRING_INLINE
749
750 #endif  /* use string inlines && GNU CC */