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