Fix powerpc software sqrtf (bug 17967).
[glibc.git] / sysdeps / x86 / bits / string.h
bloba117f6be1fbf0f45e29a6bf5bba6d1ce1e75db59
1 /* Optimized, inlined string functions. i486/x86-64 version.
2 Copyright (C) 2001-2015 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 Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #ifndef _STRING_H
20 # error "Never use <bits/string.h> directly; include <string.h> instead."
21 #endif
23 /* The ix86 processors can access unaligned multi-byte variables. */
24 #define _STRING_ARCH_unaligned 1
26 /* Enable inline functions only for i486 or better when compiling for
27 ia32. */
28 #if !defined __x86_64__ && (defined __i486__ || defined __pentium__ \
29 || defined __pentiumpro__ || defined __pentium4__ \
30 || defined __nocona__ || defined __atom__ \
31 || defined __core2__ || defined __corei7__ \
32 || defined __sandybridge__ || defined __haswell__ \
33 || defined __bonnell__ || defined __silvermont__ \
34 || defined __k6__ || defined __geode__ \
35 || defined __k8__ || defined __athlon__ \
36 || defined __amdfam10__ || defined __bdver1__ \
37 || defined __bdver2__ || defined __bdver3__ \
38 || defined __bdver4__ || defined __btver1__ \
39 || defined __btver2__)
41 /* We only provide optimizations if the user selects them and if
42 GNU CC is used. */
43 # if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
44 && defined __GNUC__ && __GNUC__ >= 2
46 # ifndef __STRING_INLINE
47 # ifndef __extern_inline
48 # define __STRING_INLINE inline
49 # else
50 # define __STRING_INLINE __extern_inline
51 # endif
52 # endif
54 /* The macros are used in some of the optimized implementations below. */
55 # define __STRING_SMALL_GET16(src, idx) \
56 ((((const unsigned char *) (src))[idx + 1] << 8) \
57 | ((const unsigned char *) (src))[idx])
58 # define __STRING_SMALL_GET32(src, idx) \
59 (((((const unsigned char *) (src))[idx + 3] << 8 \
60 | ((const unsigned char *) (src))[idx + 2]) << 8 \
61 | ((const unsigned char *) (src))[idx + 1]) << 8 \
62 | ((const unsigned char *) (src))[idx])
65 /* Copy N bytes of SRC to DEST. */
66 # define _HAVE_STRING_ARCH_memcpy 1
67 # define memcpy(dest, src, n) \
68 (__extension__ (__builtin_constant_p (n) \
69 ? __memcpy_c ((dest), (src), (n)) \
70 : __memcpy_g ((dest), (src), (n))))
71 # define __memcpy_c(dest, src, n) \
72 ((n) == 0 \
73 ? (dest) \
74 : (((n) % 4 == 0) \
75 ? __memcpy_by4 (dest, src, n) \
76 : (((n) % 2 == 0) \
77 ? __memcpy_by2 (dest, src, n) \
78 : __memcpy_g (dest, src, n))))
80 __STRING_INLINE void *__memcpy_by4 (void *__dest, const void *__src,
81 size_t __n);
83 __STRING_INLINE void *
84 __memcpy_by4 (void *__dest, const void *__src, size_t __n)
86 register unsigned long int __d0, __d1;
87 register void *__tmp = __dest;
88 __asm__ __volatile__
89 ("1:\n\t"
90 "movl (%2),%0\n\t"
91 "leal 4(%2),%2\n\t"
92 "movl %0,(%1)\n\t"
93 "leal 4(%1),%1\n\t"
94 "decl %3\n\t"
95 "jnz 1b"
96 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
97 : "1" (__tmp), "2" (__src), "3" (__n / 4)
98 : "memory", "cc");
99 return __dest;
102 __STRING_INLINE void *__memcpy_by2 (void *__dest, const void *__src,
103 size_t __n);
105 __STRING_INLINE void *
106 __memcpy_by2 (void *__dest, const void *__src, size_t __n)
108 register unsigned long int __d0, __d1;
109 register void *__tmp = __dest;
110 __asm__ __volatile__
111 ("shrl $1,%3\n\t"
112 "jz 2f\n" /* only a word */
113 "1:\n\t"
114 "movl (%2),%0\n\t"
115 "leal 4(%2),%2\n\t"
116 "movl %0,(%1)\n\t"
117 "leal 4(%1),%1\n\t"
118 "decl %3\n\t"
119 "jnz 1b\n"
120 "2:\n\t"
121 "movw (%2),%w0\n\t"
122 "movw %w0,(%1)"
123 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
124 : "1" (__tmp), "2" (__src), "3" (__n / 2)
125 : "memory", "cc");
126 return __dest;
129 __STRING_INLINE void *__memcpy_g (void *__dest, const void *__src, size_t __n);
131 __STRING_INLINE void *
132 __memcpy_g (void *__dest, const void *__src, size_t __n)
134 register unsigned long int __d0, __d1, __d2;
135 register void *__tmp = __dest;
136 __asm__ __volatile__
137 ("cld\n\t"
138 "shrl $1,%%ecx\n\t"
139 "jnc 1f\n\t"
140 "movsb\n"
141 "1:\n\t"
142 "shrl $1,%%ecx\n\t"
143 "jnc 2f\n\t"
144 "movsw\n"
145 "2:\n\t"
146 "rep; movsl"
147 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2),
148 "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
149 : "0" (__n), "1" (__tmp), "2" (__src),
150 "m" ( *(struct { __extension__ char __x[__n]; } *)__src)
151 : "cc");
152 return __dest;
155 # define _HAVE_STRING_ARCH_memmove 1
156 # ifndef _FORCE_INLINES
157 /* Copy N bytes of SRC to DEST, guaranteeing
158 correct behavior for overlapping strings. */
159 # define memmove(dest, src, n) __memmove_g (dest, src, n)
161 __STRING_INLINE void *__memmove_g (void *, const void *, size_t)
162 __asm__ ("memmove");
164 __STRING_INLINE void *
165 __memmove_g (void *__dest, const void *__src, size_t __n)
167 register unsigned long int __d0, __d1, __d2;
168 register void *__tmp = __dest;
169 if (__dest < __src)
170 __asm__ __volatile__
171 ("cld\n\t"
172 "rep; movsb"
173 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2),
174 "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
175 : "0" (__n), "1" (__src), "2" (__tmp),
176 "m" ( *(struct { __extension__ char __x[__n]; } *)__src));
177 else
178 __asm__ __volatile__
179 ("std\n\t"
180 "rep; movsb\n\t"
181 "cld"
182 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2),
183 "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
184 : "0" (__n), "1" (__n - 1 + (const char *) __src),
185 "2" (__n - 1 + (char *) __tmp),
186 "m" ( *(struct { __extension__ char __x[__n]; } *)__src));
187 return __dest;
189 # endif
191 /* Compare N bytes of S1 and S2. */
192 # define _HAVE_STRING_ARCH_memcmp 1
193 # ifndef _FORCE_INLINES
194 # ifndef __PIC__
195 /* gcc has problems to spill registers when using PIC. */
196 __STRING_INLINE int
197 memcmp (const void *__s1, const void *__s2, size_t __n)
199 register unsigned long int __d0, __d1, __d2;
200 register int __res;
201 __asm__ __volatile__
202 ("cld\n\t"
203 "testl %3,%3\n\t"
204 "repe; cmpsb\n\t"
205 "je 1f\n\t"
206 "sbbl %0,%0\n\t"
207 "orl $1,%0\n"
208 "1:"
209 : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
210 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n),
211 "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
212 "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
213 : "cc");
214 return __res;
216 # endif
217 # endif
219 /* Set N bytes of S to C. */
220 # define _HAVE_STRING_ARCH_memset 1
221 # define _USE_STRING_ARCH_memset 1
222 # define memset(s, c, n) \
223 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
224 ? ((n) == 1 \
225 ? __memset_c1 ((s), (c)) \
226 : __memset_gc ((s), (c), (n))) \
227 : (__builtin_constant_p (c) \
228 ? (__builtin_constant_p (n) \
229 ? __memset_ccn ((s), (c), (n)) \
230 : memset ((s), (c), (n))) \
231 : (__builtin_constant_p (n) \
232 ? __memset_gcn ((s), (c), (n)) \
233 : memset ((s), (c), (n))))))
235 # define __memset_c1(s, c) ({ void *__s = (s); \
236 *((unsigned char *) __s) = (unsigned char) (c); \
237 __s; })
239 # define __memset_gc(s, c, n) \
240 ({ void *__s = (s); \
241 union { \
242 unsigned int __ui; \
243 unsigned short int __usi; \
244 unsigned char __uc; \
245 } *__u = __s; \
246 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
248 /* We apply a trick here. `gcc' would implement the following \
249 assignments using immediate operands. But this uses to much \
250 memory (7, instead of 4 bytes). So we force the value in a \
251 registers. */ \
252 if ((n) == 3 || (n) >= 5) \
253 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
255 /* This `switch' statement will be removed at compile-time. */ \
256 switch (n) \
258 case 15: \
259 __u->__ui = __c; \
260 __u = __extension__ ((void *) __u + 4); \
261 case 11: \
262 __u->__ui = __c; \
263 __u = __extension__ ((void *) __u + 4); \
264 case 7: \
265 __u->__ui = __c; \
266 __u = __extension__ ((void *) __u + 4); \
267 case 3: \
268 __u->__usi = (unsigned short int) __c; \
269 __u = __extension__ ((void *) __u + 2); \
270 __u->__uc = (unsigned char) __c; \
271 break; \
273 case 14: \
274 __u->__ui = __c; \
275 __u = __extension__ ((void *) __u + 4); \
276 case 10: \
277 __u->__ui = __c; \
278 __u = __extension__ ((void *) __u + 4); \
279 case 6: \
280 __u->__ui = __c; \
281 __u = __extension__ ((void *) __u + 4); \
282 case 2: \
283 __u->__usi = (unsigned short int) __c; \
284 break; \
286 case 13: \
287 __u->__ui = __c; \
288 __u = __extension__ ((void *) __u + 4); \
289 case 9: \
290 __u->__ui = __c; \
291 __u = __extension__ ((void *) __u + 4); \
292 case 5: \
293 __u->__ui = __c; \
294 __u = __extension__ ((void *) __u + 4); \
295 case 1: \
296 __u->__uc = (unsigned char) __c; \
297 break; \
299 case 16: \
300 __u->__ui = __c; \
301 __u = __extension__ ((void *) __u + 4); \
302 case 12: \
303 __u->__ui = __c; \
304 __u = __extension__ ((void *) __u + 4); \
305 case 8: \
306 __u->__ui = __c; \
307 __u = __extension__ ((void *) __u + 4); \
308 case 4: \
309 __u->__ui = __c; \
310 case 0: \
311 break; \
314 __s; })
316 # define __memset_ccn(s, c, n) \
317 (((n) % 4 == 0) \
318 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
319 n) \
320 : (((n) % 2 == 0) \
321 ? __memset_ccn_by2 (s, \
322 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
323 n) \
324 : memset (s, c, n)))
326 __STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
327 size_t __n);
329 __STRING_INLINE void *
330 __memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
332 register void *__tmp = __s;
333 register unsigned long int __d0;
334 # ifdef __i686__
335 __asm__ __volatile__
336 ("cld\n\t"
337 "rep; stosl"
338 : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0),
339 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
340 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
341 : "cc");
342 # else
343 __asm__ __volatile__
344 ("1:\n\t"
345 "movl %0,(%1)\n\t"
346 "addl $4,%1\n\t"
347 "decl %2\n\t"
348 "jnz 1b\n"
349 : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0),
350 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
351 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
352 : "cc");
353 # endif
354 return __s;
357 __STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
358 size_t __n);
360 __STRING_INLINE void *
361 __memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
363 register unsigned long int __d0, __d1;
364 register void *__tmp = __s;
365 # ifdef __i686__
366 __asm__ __volatile__
367 ("cld\n\t"
368 "rep; stosl\n"
369 "stosw"
370 : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1),
371 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
372 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
373 : "cc");
374 # else
375 __asm__ __volatile__
376 ("1:\tmovl %0,(%1)\n\t"
377 "leal 4(%1),%1\n\t"
378 "decl %2\n\t"
379 "jnz 1b\n"
380 "movw %w0,(%1)"
381 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1),
382 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
383 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
384 : "cc");
385 #endif
386 return __s;
389 # define __memset_gcn(s, c, n) \
390 (((n) % 4 == 0) \
391 ? __memset_gcn_by4 (s, c, n) \
392 : (((n) % 2 == 0) \
393 ? __memset_gcn_by2 (s, c, n) \
394 : memset (s, c, n)))
396 __STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
398 __STRING_INLINE void *
399 __memset_gcn_by4 (void *__s, int __c, size_t __n)
401 register void *__tmp = __s;
402 register unsigned long int __d0;
403 __asm__ __volatile__
404 ("movb %b0,%h0\n"
405 "pushw %w0\n\t"
406 "shll $16,%0\n\t"
407 "popw %w0\n"
408 "1:\n\t"
409 "movl %0,(%1)\n\t"
410 "addl $4,%1\n\t"
411 "decl %2\n\t"
412 "jnz 1b\n"
413 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0),
414 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
415 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
416 : "cc");
417 return __s;
420 __STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
422 __STRING_INLINE void *
423 __memset_gcn_by2 (void *__s, int __c, size_t __n)
425 register unsigned long int __d0, __d1;
426 register void *__tmp = __s;
427 __asm__ __volatile__
428 ("movb %b0,%h0\n\t"
429 "pushw %w0\n\t"
430 "shll $16,%0\n\t"
431 "popw %w0\n"
432 "1:\n\t"
433 "movl %0,(%1)\n\t"
434 "leal 4(%1),%1\n\t"
435 "decl %2\n\t"
436 "jnz 1b\n"
437 "movw %w0,(%1)"
438 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1),
439 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
440 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
441 : "cc");
442 return __s;
446 /* Search N bytes of S for C. */
447 # define _HAVE_STRING_ARCH_memchr 1
448 # ifndef _FORCE_INLINES
449 __STRING_INLINE void *
450 memchr (const void *__s, int __c, size_t __n)
452 register unsigned long int __d0;
453 # ifdef __i686__
454 register unsigned long int __d1;
455 # endif
456 register unsigned char *__res;
457 if (__n == 0)
458 return NULL;
459 # ifdef __i686__
460 __asm__ __volatile__
461 ("cld\n\t"
462 "repne; scasb\n\t"
463 "cmovne %2,%0"
464 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
465 : "a" (__c), "0" (__s), "1" (__n), "2" (1),
466 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
467 : "cc");
468 # else
469 __asm__ __volatile__
470 ("cld\n\t"
471 "repne; scasb\n\t"
472 "je 1f\n\t"
473 "movl $1,%0\n"
474 "1:"
475 : "=D" (__res), "=&c" (__d0)
476 : "a" (__c), "0" (__s), "1" (__n),
477 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
478 : "cc");
479 # endif
480 return __res - 1;
482 # endif
484 # define _HAVE_STRING_ARCH_memrchr 1
485 # ifndef _FORCE_INLINES
486 __STRING_INLINE void *__memrchr (const void *__s, int __c, size_t __n);
488 __STRING_INLINE void *
489 __memrchr (const void *__s, int __c, size_t __n)
491 register unsigned long int __d0;
492 # ifdef __i686__
493 register unsigned long int __d1;
494 # endif
495 register void *__res;
496 if (__n == 0)
497 return NULL;
498 # ifdef __i686__
499 __asm__ __volatile__
500 ("std\n\t"
501 "repne; scasb\n\t"
502 "cmovne %2,%0\n\t"
503 "cld\n\t"
504 "incl %0"
505 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
506 : "a" (__c), "0" (__s + __n - 1), "1" (__n), "2" (-1),
507 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
508 : "cc");
509 # else
510 __asm__ __volatile__
511 ("std\n\t"
512 "repne; scasb\n\t"
513 "je 1f\n\t"
514 "orl $-1,%0\n"
515 "1:\tcld\n\t"
516 "incl %0"
517 : "=D" (__res), "=&c" (__d0)
518 : "a" (__c), "0" (__s + __n - 1), "1" (__n),
519 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
520 : "cc");
521 # endif
522 return __res;
524 # ifdef __USE_GNU
525 # define memrchr(s, c, n) __memrchr ((s), (c), (n))
526 # endif
527 # endif
529 /* Return pointer to C in S. */
530 # define _HAVE_STRING_ARCH_rawmemchr 1
531 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
533 # ifndef _FORCE_INLINES
534 __STRING_INLINE void *
535 __rawmemchr (const void *__s, int __c)
537 register unsigned long int __d0;
538 register unsigned char *__res;
539 __asm__ __volatile__
540 ("cld\n\t"
541 "repne; scasb\n\t"
542 : "=D" (__res), "=&c" (__d0)
543 : "a" (__c), "0" (__s), "1" (0xffffffff),
544 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
545 : "cc");
546 return __res - 1;
548 # ifdef __USE_GNU
549 __STRING_INLINE void *
550 rawmemchr (const void *__s, int __c)
552 return __rawmemchr (__s, __c);
554 # endif /* use GNU */
555 # endif
558 /* Return the length of S. */
559 # define _HAVE_STRING_ARCH_strlen 1
560 # define strlen(str) \
561 (__extension__ (__builtin_constant_p (str) \
562 ? __builtin_strlen (str) \
563 : __strlen_g (str)))
564 __STRING_INLINE size_t __strlen_g (const char *__str);
566 __STRING_INLINE size_t
567 __strlen_g (const char *__str)
569 register char __dummy;
570 register const char *__tmp = __str;
571 __asm__ __volatile__
572 ("1:\n\t"
573 "movb (%0),%b1\n\t"
574 "leal 1(%0),%0\n\t"
575 "testb %b1,%b1\n\t"
576 "jne 1b"
577 : "=r" (__tmp), "=&q" (__dummy)
578 : "0" (__str),
579 "m" ( *(struct { char __x[0xfffffff]; } *)__str)
580 : "cc" );
581 return __tmp - __str - 1;
585 /* Copy SRC to DEST. */
586 # define _HAVE_STRING_ARCH_strcpy 1
587 # define strcpy(dest, src) \
588 (__extension__ (__builtin_constant_p (src) \
589 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
590 ? __strcpy_a_small ((dest), (src), strlen (src) + 1) \
591 : (char *) memcpy ((char *) (dest), \
592 (const char *) (src), \
593 strlen (src) + 1)) \
594 : __strcpy_g ((dest), (src))))
596 # define __strcpy_a_small(dest, src, srclen) \
597 (__extension__ ({ char *__dest = (dest); \
598 union { \
599 unsigned int __ui; \
600 unsigned short int __usi; \
601 unsigned char __uc; \
602 char __c; \
603 } *__u = (void *) __dest; \
604 switch (srclen) \
606 case 1: \
607 __u->__uc = '\0'; \
608 break; \
609 case 2: \
610 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
611 break; \
612 case 3: \
613 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
614 __u = __extension__ ((void *) __u + 2); \
615 __u->__uc = '\0'; \
616 break; \
617 case 4: \
618 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
619 break; \
620 case 5: \
621 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
622 __u = __extension__ ((void *) __u + 4); \
623 __u->__uc = '\0'; \
624 break; \
625 case 6: \
626 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
627 __u = __extension__ ((void *) __u + 4); \
628 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
629 break; \
630 case 7: \
631 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
632 __u = __extension__ ((void *) __u + 4); \
633 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
634 __u = __extension__ ((void *) __u + 2); \
635 __u->__uc = '\0'; \
636 break; \
637 case 8: \
638 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
639 __u = __extension__ ((void *) __u + 4); \
640 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
641 break; \
643 (char *) __dest; }))
645 __STRING_INLINE char *__strcpy_g (char *__dest, const char *__src);
647 __STRING_INLINE char *
648 __strcpy_g (char *__dest, const char *__src)
650 register char *__tmp = __dest;
651 register char __dummy;
652 __asm__ __volatile__
654 "1:\n\t"
655 "movb (%0),%b2\n\t"
656 "leal 1(%0),%0\n\t"
657 "movb %b2,(%1)\n\t"
658 "leal 1(%1),%1\n\t"
659 "testb %b2,%b2\n\t"
660 "jne 1b"
661 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy),
662 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
663 : "0" (__src), "1" (__tmp),
664 "m" ( *(struct { char __x[0xfffffff]; } *)__src)
665 : "cc");
666 return __dest;
670 # ifdef __USE_GNU
671 # define _HAVE_STRING_ARCH_stpcpy 1
672 /* Copy SRC to DEST. */
673 # define __stpcpy(dest, src) \
674 (__extension__ (__builtin_constant_p (src) \
675 ? (strlen (src) + 1 <= 8 \
676 ? __stpcpy_a_small ((dest), (src), strlen (src) + 1) \
677 : __stpcpy_c ((dest), (src), strlen (src) + 1)) \
678 : __stpcpy_g ((dest), (src))))
679 # define __stpcpy_c(dest, src, srclen) \
680 ((srclen) % 4 == 0 \
681 ? __mempcpy_by4 (dest, src, srclen) - 1 \
682 : ((srclen) % 2 == 0 \
683 ? __mempcpy_by2 (dest, src, srclen) - 1 \
684 : __mempcpy_byn (dest, src, srclen) - 1))
686 /* In glibc itself we use this symbol for namespace reasons. */
687 # define stpcpy(dest, src) __stpcpy ((dest), (src))
689 # define __stpcpy_a_small(dest, src, srclen) \
690 (__extension__ ({ union { \
691 unsigned int __ui; \
692 unsigned short int __usi; \
693 unsigned char __uc; \
694 char __c; \
695 } *__u = (void *) (dest); \
696 switch (srclen) \
698 case 1: \
699 __u->__uc = '\0'; \
700 break; \
701 case 2: \
702 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
703 __u = __extension__ ((void *) __u + 1); \
704 break; \
705 case 3: \
706 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
707 __u = __extension__ ((void *) __u + 2); \
708 __u->__uc = '\0'; \
709 break; \
710 case 4: \
711 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
712 __u = __extension__ ((void *) __u + 3); \
713 break; \
714 case 5: \
715 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
716 __u = __extension__ ((void *) __u + 4); \
717 __u->__uc = '\0'; \
718 break; \
719 case 6: \
720 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
721 __u = __extension__ ((void *) __u + 4); \
722 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
723 __u = __extension__ ((void *) __u + 1); \
724 break; \
725 case 7: \
726 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
727 __u = __extension__ ((void *) __u + 4); \
728 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
729 __u = __extension__ ((void *) __u + 2); \
730 __u->__uc = '\0'; \
731 break; \
732 case 8: \
733 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
734 __u = __extension__ ((void *) __u + 4); \
735 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
736 __u = __extension__ ((void *) __u + 3); \
737 break; \
739 (char *) __u; }))
741 __STRING_INLINE char *__mempcpy_by4 (char *__dest, const char *__src,
742 size_t __srclen);
744 __STRING_INLINE char *
745 __mempcpy_by4 (char *__dest, const char *__src, size_t __srclen)
747 register char *__tmp = __dest;
748 register unsigned long int __d0, __d1;
749 __asm__ __volatile__
750 ("1:\n\t"
751 "movl (%2),%0\n\t"
752 "leal 4(%2),%2\n\t"
753 "movl %0,(%1)\n\t"
754 "leal 4(%1),%1\n\t"
755 "decl %3\n\t"
756 "jnz 1b"
757 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
758 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
759 : "memory", "cc");
760 return __tmp;
763 __STRING_INLINE char *__mempcpy_by2 (char *__dest, const char *__src,
764 size_t __srclen);
766 __STRING_INLINE char *
767 __mempcpy_by2 (char *__dest, const char *__src, size_t __srclen)
769 register char *__tmp = __dest;
770 register unsigned long int __d0, __d1;
771 __asm__ __volatile__
772 ("shrl $1,%3\n\t"
773 "jz 2f\n" /* only a word */
774 "1:\n\t"
775 "movl (%2),%0\n\t"
776 "leal 4(%2),%2\n\t"
777 "movl %0,(%1)\n\t"
778 "leal 4(%1),%1\n\t"
779 "decl %3\n\t"
780 "jnz 1b\n"
781 "2:\n\t"
782 "movw (%2),%w0\n\t"
783 "movw %w0,(%1)"
784 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1),
785 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
786 : "1" (__tmp), "2" (__src), "3" (__srclen / 2),
787 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
788 : "cc");
789 return __tmp + 2;
792 __STRING_INLINE char *__mempcpy_byn (char *__dest, const char *__src,
793 size_t __srclen);
795 __STRING_INLINE char *
796 __mempcpy_byn (char *__dest, const char *__src, size_t __srclen)
798 register unsigned long __d0, __d1;
799 register char *__tmp = __dest;
800 __asm__ __volatile__
801 ("cld\n\t"
802 "shrl $1,%%ecx\n\t"
803 "jnc 1f\n\t"
804 "movsb\n"
805 "1:\n\t"
806 "shrl $1,%%ecx\n\t"
807 "jnc 2f\n\t"
808 "movsw\n"
809 "2:\n\t"
810 "rep; movsl"
811 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1),
812 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
813 : "0" (__tmp), "1" (__srclen), "2" (__src),
814 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
815 : "cc");
816 return __tmp;
819 __STRING_INLINE char *__stpcpy_g (char *__dest, const char *__src);
821 __STRING_INLINE char *
822 __stpcpy_g (char *__dest, const char *__src)
824 register char *__tmp = __dest;
825 register char __dummy;
826 __asm__ __volatile__
828 "1:\n\t"
829 "movb (%0),%b2\n\t"
830 "leal 1(%0),%0\n\t"
831 "movb %b2,(%1)\n\t"
832 "leal 1(%1),%1\n\t"
833 "testb %b2,%b2\n\t"
834 "jne 1b"
835 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy),
836 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
837 : "0" (__src), "1" (__tmp),
838 "m" ( *(struct { char __x[0xfffffff]; } *)__src)
839 : "cc");
840 return __tmp - 1;
842 # endif
845 /* Copy no more than N characters of SRC to DEST. */
846 # define _HAVE_STRING_ARCH_strncpy 1
847 # define strncpy(dest, src, n) \
848 (__extension__ (__builtin_constant_p (src) \
849 ? ((strlen (src) + 1 >= ((size_t) (n)) \
850 ? (char *) memcpy ((char *) (dest), \
851 (const char *) (src), n) \
852 : __strncpy_cg ((dest), (src), strlen (src) + 1, n))) \
853 : __strncpy_gg ((dest), (src), n)))
854 # define __strncpy_cg(dest, src, srclen, n) \
855 (((srclen) % 4 == 0) \
856 ? __strncpy_by4 (dest, src, srclen, n) \
857 : (((srclen) % 2 == 0) \
858 ? __strncpy_by2 (dest, src, srclen, n) \
859 : __strncpy_byn (dest, src, srclen, n)))
861 __STRING_INLINE char *__strncpy_by4 (char *__dest, const char __src[],
862 size_t __srclen, size_t __n);
864 __STRING_INLINE char *
865 __strncpy_by4 (char *__dest, const char __src[], size_t __srclen, size_t __n)
867 register char *__tmp = __dest;
868 register int __dummy1, __dummy2;
869 __asm__ __volatile__
870 ("1:\n\t"
871 "movl (%2),%0\n\t"
872 "leal 4(%2),%2\n\t"
873 "movl %0,(%1)\n\t"
874 "leal 4(%1),%1\n\t"
875 "decl %3\n\t"
876 "jnz 1b"
877 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2),
878 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
879 : "1" (__tmp), "2" (__src), "3" (__srclen / 4),
880 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
881 : "cc");
882 (void) memset (__tmp, '\0', __n - __srclen);
883 return __dest;
886 __STRING_INLINE char *__strncpy_by2 (char *__dest, const char __src[],
887 size_t __srclen, size_t __n);
889 __STRING_INLINE char *
890 __strncpy_by2 (char *__dest, const char __src[], size_t __srclen, size_t __n)
892 register char *__tmp = __dest;
893 register int __dummy1, __dummy2;
894 __asm__ __volatile__
895 ("shrl $1,%3\n\t"
896 "jz 2f\n" /* only a word */
897 "1:\n\t"
898 "movl (%2),%0\n\t"
899 "leal 4(%2),%2\n\t"
900 "movl %0,(%1)\n\t"
901 "leal 4(%1),%1\n\t"
902 "decl %3\n\t"
903 "jnz 1b\n"
904 "2:\n\t"
905 "movw (%2),%w0\n\t"
906 "movw %w0,(%1)\n\t"
907 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2),
908 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
909 : "1" (__tmp), "2" (__src), "3" (__srclen / 2),
910 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
911 : "cc");
912 (void) memset (__tmp + 2, '\0', __n - __srclen);
913 return __dest;
916 __STRING_INLINE char *__strncpy_byn (char *__dest, const char __src[],
917 size_t __srclen, size_t __n);
919 __STRING_INLINE char *
920 __strncpy_byn (char *__dest, const char __src[], size_t __srclen, size_t __n)
922 register unsigned long int __d0, __d1;
923 register char *__tmp = __dest;
924 __asm__ __volatile__
925 ("cld\n\t"
926 "shrl $1,%1\n\t"
927 "jnc 1f\n\t"
928 "movsb\n"
929 "1:\n\t"
930 "shrl $1,%1\n\t"
931 "jnc 2f\n\t"
932 "movsw\n"
933 "2:\n\t"
934 "rep; movsl"
935 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1),
936 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
937 : "1" (__srclen), "0" (__tmp),"2" (__src),
938 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
939 : "cc");
940 (void) memset (__tmp, '\0', __n - __srclen);
941 return __dest;
944 __STRING_INLINE char *__strncpy_gg (char *__dest, const char *__src,
945 size_t __n);
947 __STRING_INLINE char *
948 __strncpy_gg (char *__dest, const char *__src, size_t __n)
950 register char *__tmp = __dest;
951 register char __dummy;
952 if (__n > 0)
953 __asm__ __volatile__
954 ("1:\n\t"
955 "movb (%0),%2\n\t"
956 "incl %0\n\t"
957 "movb %2,(%1)\n\t"
958 "incl %1\n\t"
959 "decl %3\n\t"
960 "je 3f\n\t"
961 "testb %2,%2\n\t"
962 "jne 1b\n\t"
963 "2:\n\t"
964 "movb %2,(%1)\n\t"
965 "incl %1\n\t"
966 "decl %3\n\t"
967 "jne 2b\n\t"
968 "3:"
969 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
970 : "0" (__src), "1" (__tmp), "3" (__n)
971 : "memory", "cc");
973 return __dest;
977 /* Append SRC onto DEST. */
978 # define _HAVE_STRING_ARCH_strcat 1
979 # define strcat(dest, src) \
980 (__extension__ (__builtin_constant_p (src) \
981 ? __strcat_c ((dest), (src), strlen (src) + 1) \
982 : __strcat_g ((dest), (src))))
984 __STRING_INLINE char *__strcat_c (char *__dest, const char __src[],
985 size_t __srclen);
987 __STRING_INLINE char *
988 __strcat_c (char *__dest, const char __src[], size_t __srclen)
990 # ifdef __i686__
991 register unsigned long int __d0;
992 register char *__tmp;
993 __asm__ __volatile__
994 ("repne; scasb"
995 : "=D" (__tmp), "=&c" (__d0),
996 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
997 : "0" (__dest), "1" (0xffffffff), "a" (0),
998 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
999 : "cc");
1000 --__tmp;
1001 # else
1002 register char *__tmp = __dest - 1;
1003 __asm__ __volatile__
1004 ("1:\n\t"
1005 "incl %0\n\t"
1006 "cmpb $0,(%0)\n\t"
1007 "jne 1b\n"
1008 : "=r" (__tmp),
1009 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
1010 : "0" (__tmp),
1011 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
1012 : "cc");
1013 # endif
1014 (void) memcpy (__tmp, __src, __srclen);
1015 return __dest;
1018 __STRING_INLINE char *__strcat_g (char *__dest, const char *__src);
1020 __STRING_INLINE char *
1021 __strcat_g (char *__dest, const char *__src)
1023 register char *__tmp = __dest - 1;
1024 register char __dummy;
1025 __asm__ __volatile__
1026 ("1:\n\t"
1027 "incl %1\n\t"
1028 "cmpb $0,(%1)\n\t"
1029 "jne 1b\n"
1030 "2:\n\t"
1031 "movb (%2),%b0\n\t"
1032 "incl %2\n\t"
1033 "movb %b0,(%1)\n\t"
1034 "incl %1\n\t"
1035 "testb %b0,%b0\n\t"
1036 "jne 2b\n"
1037 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src),
1038 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
1039 : "1" (__tmp), "2" (__src),
1040 "m" ( *(struct { char __x[0xfffffff]; } *)__src)
1041 : "memory", "cc");
1042 return __dest;
1046 /* Append no more than N characters from SRC onto DEST. */
1047 # define _HAVE_STRING_ARCH_strncat 1
1048 # define strncat(dest, src, n) \
1049 (__extension__ ({ char *__dest = (dest); \
1050 __builtin_constant_p (src) && __builtin_constant_p (n) \
1051 ? (strlen (src) < ((size_t) (n)) \
1052 ? strcat (__dest, (src)) \
1053 : (*(char *)__mempcpy (strchr (__dest, '\0'), \
1054 (const char *) (src), \
1055 (n)) = 0, __dest)) \
1056 : __strncat_g (__dest, (src), (n)); }))
1058 __STRING_INLINE char *__strncat_g (char *__dest, const char __src[],
1059 size_t __n);
1061 __STRING_INLINE char *
1062 __strncat_g (char *__dest, const char __src[], size_t __n)
1064 register char *__tmp = __dest;
1065 register char __dummy;
1066 # ifdef __i686__
1067 __asm__ __volatile__
1068 ("repne; scasb\n"
1069 "movl %4, %3\n\t"
1070 "decl %1\n\t"
1071 "1:\n\t"
1072 "subl $1,%3\n\t"
1073 "jc 2f\n\t"
1074 "movb (%2),%b0\n\t"
1075 "movsb\n\t"
1076 "testb %b0,%b0\n\t"
1077 "jne 1b\n\t"
1078 "decl %1\n"
1079 "2:\n\t"
1080 "movb $0,(%1)"
1081 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&c" (__n)
1082 : "g" (__n), "0" (0), "1" (__tmp), "2" (__src), "3" (0xffffffff)
1083 : "memory", "cc");
1084 # else
1085 --__tmp;
1086 __asm__ __volatile__
1087 ("1:\n\t"
1088 "cmpb $0,1(%1)\n\t"
1089 "leal 1(%1),%1\n\t"
1090 "jne 1b\n"
1091 "2:\n\t"
1092 "subl $1,%3\n\t"
1093 "jc 3f\n\t"
1094 "movb (%2),%b0\n\t"
1095 "leal 1(%2),%2\n\t"
1096 "movb %b0,(%1)\n\t"
1097 "leal 1(%1),%1\n\t"
1098 "testb %b0,%b0\n\t"
1099 "jne 2b\n\t"
1100 "decl %1\n"
1101 "3:\n\t"
1102 "movb $0,(%1)"
1103 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1104 : "1" (__tmp), "2" (__src), "3" (__n)
1105 : "memory", "cc");
1106 #endif
1107 return __dest;
1111 /* Compare S1 and S2. */
1112 # define _HAVE_STRING_ARCH_strcmp 1
1113 # define strcmp(s1, s2) \
1114 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1115 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1116 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1117 ? memcmp ((const char *) (s1), (const char *) (s2), \
1118 (strlen (s1) < strlen (s2) \
1119 ? strlen (s1) : strlen (s2)) + 1) \
1120 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1121 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1122 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1123 ? __strcmp_cc ((const unsigned char *) (s1), \
1124 (const unsigned char *) (s2), \
1125 strlen (s1)) \
1126 : __strcmp_cg ((const unsigned char *) (s1), \
1127 (const unsigned char *) (s2), \
1128 strlen (s1))) \
1129 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1130 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1131 ? (__builtin_constant_p (s1) \
1132 ? __strcmp_cc ((const unsigned char *) (s1), \
1133 (const unsigned char *) (s2), \
1134 strlen (s2)) \
1135 : __strcmp_gc ((const unsigned char *) (s1), \
1136 (const unsigned char *) (s2), \
1137 strlen (s2))) \
1138 : __strcmp_gg ((s1), (s2))))))
1140 # define __strcmp_cc(s1, s2, l) \
1141 (__extension__ ({ register int __result = (s1)[0] - (s2)[0]; \
1142 if (l > 0 && __result == 0) \
1144 __result = (s1)[1] - (s2)[1]; \
1145 if (l > 1 && __result == 0) \
1147 __result = (s1)[2] - (s2)[2]; \
1148 if (l > 2 && __result == 0) \
1149 __result = (s1)[3] - (s2)[3]; \
1152 __result; }))
1154 # define __strcmp_cg(s1, s2, l1) \
1155 (__extension__ ({ const unsigned char *__s2 = (s2); \
1156 register int __result = (s1)[0] - __s2[0]; \
1157 if (l1 > 0 && __result == 0) \
1159 __result = (s1)[1] - __s2[1]; \
1160 if (l1 > 1 && __result == 0) \
1162 __result = (s1)[2] - __s2[2]; \
1163 if (l1 > 2 && __result == 0) \
1164 __result = (s1)[3] - __s2[3]; \
1167 __result; }))
1169 # define __strcmp_gc(s1, s2, l2) \
1170 (__extension__ ({ const unsigned char *__s1 = (s1); \
1171 register int __result = __s1[0] - (s2)[0]; \
1172 if (l2 > 0 && __result == 0) \
1174 __result = __s1[1] - (s2)[1]; \
1175 if (l2 > 1 && __result == 0) \
1177 __result = __s1[2] - (s2)[2]; \
1178 if (l2 > 2 && __result == 0) \
1179 __result = __s1[3] - (s2)[3]; \
1182 __result; }))
1184 __STRING_INLINE int __strcmp_gg (const char *__s1, const char *__s2);
1186 __STRING_INLINE int
1187 __strcmp_gg (const char *__s1, const char *__s2)
1189 register int __res;
1190 __asm__ __volatile__
1191 ("1:\n\t"
1192 "movb (%1),%b0\n\t"
1193 "leal 1(%1),%1\n\t"
1194 "cmpb %b0,(%2)\n\t"
1195 "jne 2f\n\t"
1196 "leal 1(%2),%2\n\t"
1197 "testb %b0,%b0\n\t"
1198 "jne 1b\n\t"
1199 "xorl %0,%0\n\t"
1200 "jmp 3f\n"
1201 "2:\n\t"
1202 "movl $1,%0\n\t"
1203 "jb 3f\n\t"
1204 "negl %0\n"
1205 "3:"
1206 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1207 : "1" (__s1), "2" (__s2),
1208 "m" ( *(struct { char __x[0xfffffff]; } *)__s1),
1209 "m" ( *(struct { char __x[0xfffffff]; } *)__s2)
1210 : "cc");
1211 return __res;
1215 /* Compare N characters of S1 and S2. */
1216 # define _HAVE_STRING_ARCH_strncmp 1
1217 # define strncmp(s1, s2, n) \
1218 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1219 ? strcmp ((s1), (s2)) \
1220 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1221 ? strcmp ((s1), (s2)) \
1222 : __strncmp_g ((s1), (s2), (n)))))
1224 __STRING_INLINE int __strncmp_g (const char *__s1, const char *__s2,
1225 size_t __n);
1227 __STRING_INLINE int
1228 __strncmp_g (const char *__s1, const char *__s2, size_t __n)
1230 register int __res;
1231 __asm__ __volatile__
1232 ("1:\n\t"
1233 "subl $1,%3\n\t"
1234 "jc 2f\n\t"
1235 "movb (%1),%b0\n\t"
1236 "incl %1\n\t"
1237 "cmpb %b0,(%2)\n\t"
1238 "jne 3f\n\t"
1239 "incl %2\n\t"
1240 "testb %b0,%b0\n\t"
1241 "jne 1b\n"
1242 "2:\n\t"
1243 "xorl %0,%0\n\t"
1244 "jmp 4f\n"
1245 "3:\n\t"
1246 "movl $1,%0\n\t"
1247 "jb 4f\n\t"
1248 "negl %0\n"
1249 "4:"
1250 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1251 : "1" (__s1), "2" (__s2), "3" (__n),
1252 "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
1253 "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
1254 : "cc");
1255 return __res;
1259 /* Find the first occurrence of C in S. */
1260 # define _HAVE_STRING_ARCH_strchr 1
1261 # define _USE_STRING_ARCH_strchr 1
1262 # define strchr(s, c) \
1263 (__extension__ (__builtin_constant_p (c) \
1264 ? ((c) == '\0' \
1265 ? (char *) __rawmemchr ((s), (c)) \
1266 : __strchr_c ((s), ((c) & 0xff) << 8)) \
1267 : __strchr_g ((s), (c))))
1269 __STRING_INLINE char *__strchr_c (const char *__s, int __c);
1271 __STRING_INLINE char *
1272 __strchr_c (const char *__s, int __c)
1274 register unsigned long int __d0;
1275 register char *__res;
1276 __asm__ __volatile__
1277 ("1:\n\t"
1278 "movb (%0),%%al\n\t"
1279 "cmpb %%ah,%%al\n\t"
1280 "je 2f\n\t"
1281 "leal 1(%0),%0\n\t"
1282 "testb %%al,%%al\n\t"
1283 "jne 1b\n\t"
1284 "xorl %0,%0\n"
1285 "2:"
1286 : "=r" (__res), "=&a" (__d0)
1287 : "0" (__s), "1" (__c),
1288 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1289 : "cc");
1290 return __res;
1293 __STRING_INLINE char *__strchr_g (const char *__s, int __c);
1295 __STRING_INLINE char *
1296 __strchr_g (const char *__s, int __c)
1298 register unsigned long int __d0;
1299 register char *__res;
1300 __asm__ __volatile__
1301 ("movb %%al,%%ah\n"
1302 "1:\n\t"
1303 "movb (%0),%%al\n\t"
1304 "cmpb %%ah,%%al\n\t"
1305 "je 2f\n\t"
1306 "leal 1(%0),%0\n\t"
1307 "testb %%al,%%al\n\t"
1308 "jne 1b\n\t"
1309 "xorl %0,%0\n"
1310 "2:"
1311 : "=r" (__res), "=&a" (__d0)
1312 : "0" (__s), "1" (__c),
1313 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1314 : "cc");
1315 return __res;
1319 /* Find the first occurrence of C in S or the final NUL byte. */
1320 # define _HAVE_STRING_ARCH_strchrnul 1
1321 # define __strchrnul(s, c) \
1322 (__extension__ (__builtin_constant_p (c) \
1323 ? ((c) == '\0' \
1324 ? (char *) __rawmemchr ((s), c) \
1325 : __strchrnul_c ((s), ((c) & 0xff) << 8)) \
1326 : __strchrnul_g ((s), c)))
1328 __STRING_INLINE char *__strchrnul_c (const char *__s, int __c);
1330 __STRING_INLINE char *
1331 __strchrnul_c (const char *__s, int __c)
1333 register unsigned long int __d0;
1334 register char *__res;
1335 __asm__ __volatile__
1336 ("1:\n\t"
1337 "movb (%0),%%al\n\t"
1338 "cmpb %%ah,%%al\n\t"
1339 "je 2f\n\t"
1340 "leal 1(%0),%0\n\t"
1341 "testb %%al,%%al\n\t"
1342 "jne 1b\n\t"
1343 "decl %0\n"
1344 "2:"
1345 : "=r" (__res), "=&a" (__d0)
1346 : "0" (__s), "1" (__c),
1347 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1348 : "cc");
1349 return __res;
1352 __STRING_INLINE char *__strchrnul_g (const char *__s, int __c);
1354 __STRING_INLINE char *
1355 __strchrnul_g (const char *__s, int __c)
1357 register unsigned long int __d0;
1358 register char *__res;
1359 __asm__ __volatile__
1360 ("movb %%al,%%ah\n"
1361 "1:\n\t"
1362 "movb (%0),%%al\n\t"
1363 "cmpb %%ah,%%al\n\t"
1364 "je 2f\n\t"
1365 "leal 1(%0),%0\n\t"
1366 "testb %%al,%%al\n\t"
1367 "jne 1b\n\t"
1368 "decl %0\n"
1369 "2:"
1370 : "=r" (__res), "=&a" (__d0)
1371 : "0" (__s), "1" (__c),
1372 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1373 : "cc");
1374 return __res;
1376 # ifdef __USE_GNU
1377 # define strchrnul(s, c) __strchrnul ((s), (c))
1378 # endif
1381 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1382 /* Find the first occurrence of C in S. This is the BSD name. */
1383 # define _HAVE_STRING_ARCH_index 1
1384 # define index(s, c) \
1385 (__extension__ (__builtin_constant_p (c) \
1386 ? __strchr_c ((s), ((c) & 0xff) << 8) \
1387 : __strchr_g ((s), (c))))
1388 # endif
1391 /* Find the last occurrence of C in S. */
1392 # define _HAVE_STRING_ARCH_strrchr 1
1393 # define strrchr(s, c) \
1394 (__extension__ (__builtin_constant_p (c) \
1395 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1396 : __strrchr_g ((s), (c))))
1398 # ifdef __i686__
1399 __STRING_INLINE char *__strrchr_c (const char *__s, int __c);
1401 __STRING_INLINE char *
1402 __strrchr_c (const char *__s, int __c)
1404 register unsigned long int __d0, __d1;
1405 register char *__res;
1406 __asm__ __volatile__
1407 ("cld\n"
1408 "1:\n\t"
1409 "lodsb\n\t"
1410 "cmpb %h2,%b2\n\t"
1411 "cmove %1,%0\n\t"
1412 "testb %b2,%b2\n\t"
1413 "jne 1b"
1414 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1415 : "0" (1), "1" (__s), "2" (__c),
1416 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1417 : "cc");
1418 return __res - 1;
1421 __STRING_INLINE char *__strrchr_g (const char *__s, int __c);
1423 __STRING_INLINE char *
1424 __strrchr_g (const char *__s, int __c)
1426 register unsigned long int __d0, __d1;
1427 register char *__res;
1428 __asm__ __volatile__
1429 ("movb %b2,%h2\n"
1430 "cld\n\t"
1431 "1:\n\t"
1432 "lodsb\n\t"
1433 "cmpb %h2,%b2\n\t"
1434 "cmove %1,%0\n\t"
1435 "testb %b2,%b2\n\t"
1436 "jne 1b"
1437 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1438 : "0" (1), "1" (__s), "2" (__c),
1439 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1440 : "cc");
1441 return __res - 1;
1443 # else
1444 __STRING_INLINE char *__strrchr_c (const char *__s, int __c);
1446 __STRING_INLINE char *
1447 __strrchr_c (const char *__s, int __c)
1449 register unsigned long int __d0, __d1;
1450 register char *__res;
1451 __asm__ __volatile__
1452 ("cld\n"
1453 "1:\n\t"
1454 "lodsb\n\t"
1455 "cmpb %%ah,%%al\n\t"
1456 "jne 2f\n\t"
1457 "leal -1(%%esi),%0\n"
1458 "2:\n\t"
1459 "testb %%al,%%al\n\t"
1460 "jne 1b"
1461 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1462 : "0" (0), "1" (__s), "2" (__c),
1463 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1464 : "cc");
1465 return __res;
1468 __STRING_INLINE char *__strrchr_g (const char *__s, int __c);
1470 __STRING_INLINE char *
1471 __strrchr_g (const char *__s, int __c)
1473 register unsigned long int __d0, __d1;
1474 register char *__res;
1475 __asm__ __volatile__
1476 ("movb %%al,%%ah\n"
1477 "cld\n\t"
1478 "1:\n\t"
1479 "lodsb\n\t"
1480 "cmpb %%ah,%%al\n\t"
1481 "jne 2f\n\t"
1482 "leal -1(%%esi),%0\n"
1483 "2:\n\t"
1484 "testb %%al,%%al\n\t"
1485 "jne 1b"
1486 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1487 : "0" (0), "1" (__s), "2" (__c),
1488 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1489 : "cc");
1490 return __res;
1492 # endif
1495 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1496 /* Find the last occurrence of C in S. This is the BSD name. */
1497 # define _HAVE_STRING_ARCH_rindex 1
1498 # define rindex(s, c) \
1499 (__extension__ (__builtin_constant_p (c) \
1500 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1501 : __strrchr_g ((s), (c))))
1502 # endif
1505 /* Return the length of the initial segment of S which
1506 consists entirely of characters not in REJECT. */
1507 # define _HAVE_STRING_ARCH_strcspn 1
1508 # define strcspn(s, reject) \
1509 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1510 ? ((reject)[0] == '\0' \
1511 ? strlen (s) \
1512 : ((reject)[1] == '\0' \
1513 ? __strcspn_c1 ((s), (((reject)[0] << 8) & 0xff00)) \
1514 : __strcspn_cg ((s), (reject), strlen (reject)))) \
1515 : __strcspn_g ((s), (reject))))
1517 __STRING_INLINE size_t __strcspn_c1 (const char *__s, int __reject);
1519 # ifndef _FORCE_INLINES
1520 __STRING_INLINE size_t
1521 __strcspn_c1 (const char *__s, int __reject)
1523 register unsigned long int __d0;
1524 register char *__res;
1525 __asm__ __volatile__
1526 ("1:\n\t"
1527 "movb (%0),%%al\n\t"
1528 "leal 1(%0),%0\n\t"
1529 "cmpb %%ah,%%al\n\t"
1530 "je 2f\n\t"
1531 "testb %%al,%%al\n\t"
1532 "jne 1b\n"
1533 "2:"
1534 : "=r" (__res), "=&a" (__d0)
1535 : "0" (__s), "1" (__reject),
1536 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1537 : "cc");
1538 return (__res - 1) - __s;
1540 # endif
1542 __STRING_INLINE size_t __strcspn_cg (const char *__s, const char __reject[],
1543 size_t __reject_len);
1545 __STRING_INLINE size_t
1546 __strcspn_cg (const char *__s, const char __reject[], size_t __reject_len)
1548 register unsigned long int __d0, __d1, __d2;
1549 register const char *__res;
1550 __asm__ __volatile__
1551 ("cld\n"
1552 "1:\n\t"
1553 "lodsb\n\t"
1554 "testb %%al,%%al\n\t"
1555 "je 2f\n\t"
1556 "movl %5,%%edi\n\t"
1557 "movl %6,%%ecx\n\t"
1558 "repne; scasb\n\t"
1559 "jne 1b\n"
1560 "2:"
1561 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1562 : "0" (__s), "d" (__reject), "g" (__reject_len)
1563 : "memory", "cc");
1564 return (__res - 1) - __s;
1567 __STRING_INLINE size_t __strcspn_g (const char *__s, const char *__reject);
1568 # ifdef __PIC__
1570 __STRING_INLINE size_t
1571 __strcspn_g (const char *__s, const char *__reject)
1573 register unsigned long int __d0, __d1, __d2;
1574 register const char *__res;
1575 __asm__ __volatile__
1576 ("pushl %%ebx\n\t"
1577 "movl %4,%%edi\n\t"
1578 "cld\n\t"
1579 "repne; scasb\n\t"
1580 "notl %%ecx\n\t"
1581 "leal -1(%%ecx),%%ebx\n"
1582 "1:\n\t"
1583 "lodsb\n\t"
1584 "testb %%al,%%al\n\t"
1585 "je 2f\n\t"
1586 "movl %4,%%edi\n\t"
1587 "movl %%ebx,%%ecx\n\t"
1588 "repne; scasb\n\t"
1589 "jne 1b\n"
1590 "2:\n\t"
1591 "popl %%ebx"
1592 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1593 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1594 : "memory", "cc");
1595 return (__res - 1) - __s;
1597 # else
1598 __STRING_INLINE size_t
1599 __strcspn_g (const char *__s, const char *__reject)
1601 register unsigned long int __d0, __d1, __d2, __d3;
1602 register const char *__res;
1603 __asm__ __volatile__
1604 ("cld\n\t"
1605 "repne; scasb\n\t"
1606 "notl %%ecx\n\t"
1607 "leal -1(%%ecx),%%edx\n"
1608 "1:\n\t"
1609 "lodsb\n\t"
1610 "testb %%al,%%al\n\t"
1611 "je 2f\n\t"
1612 "movl %%ebx,%%edi\n\t"
1613 "movl %%edx,%%ecx\n\t"
1614 "repne; scasb\n\t"
1615 "jne 1b\n"
1616 "2:"
1617 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1618 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1619 /* Clobber memory, otherwise GCC cannot handle this. */
1620 : "memory", "cc");
1621 return (__res - 1) - __s;
1623 # endif
1626 /* Return the length of the initial segment of S which
1627 consists entirely of characters in ACCEPT. */
1628 # define _HAVE_STRING_ARCH_strspn 1
1629 # define strspn(s, accept) \
1630 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1631 ? ((accept)[0] == '\0' \
1632 ? ((void) (s), 0) \
1633 : ((accept)[1] == '\0' \
1634 ? __strspn_c1 ((s), (((accept)[0] << 8 ) & 0xff00)) \
1635 : __strspn_cg ((s), (accept), strlen (accept)))) \
1636 : __strspn_g ((s), (accept))))
1638 # ifndef _FORCE_INLINES
1639 __STRING_INLINE size_t __strspn_c1 (const char *__s, int __accept);
1641 __STRING_INLINE size_t
1642 __strspn_c1 (const char *__s, int __accept)
1644 register unsigned long int __d0;
1645 register char *__res;
1646 /* Please note that __accept never can be '\0'. */
1647 __asm__ __volatile__
1648 ("1:\n\t"
1649 "movb (%0),%b1\n\t"
1650 "leal 1(%0),%0\n\t"
1651 "cmpb %h1,%b1\n\t"
1652 "je 1b"
1653 : "=r" (__res), "=&q" (__d0)
1654 : "0" (__s), "1" (__accept),
1655 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1656 : "cc");
1657 return (__res - 1) - __s;
1659 # endif
1661 __STRING_INLINE size_t __strspn_cg (const char *__s, const char __accept[],
1662 size_t __accept_len);
1664 __STRING_INLINE size_t
1665 __strspn_cg (const char *__s, const char __accept[], size_t __accept_len)
1667 register unsigned long int __d0, __d1, __d2;
1668 register const char *__res;
1669 __asm__ __volatile__
1670 ("cld\n"
1671 "1:\n\t"
1672 "lodsb\n\t"
1673 "testb %%al,%%al\n\t"
1674 "je 2f\n\t"
1675 "movl %5,%%edi\n\t"
1676 "movl %6,%%ecx\n\t"
1677 "repne; scasb\n\t"
1678 "je 1b\n"
1679 "2:"
1680 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1681 : "0" (__s), "g" (__accept), "g" (__accept_len),
1682 /* Since we do not know how large the memory we access it, use a
1683 really large amount. */
1684 "m" ( *(struct { char __x[0xfffffff]; } *)__s),
1685 "m" ( *(struct { __extension__ char __x[__accept_len]; } *)__accept)
1686 : "cc");
1687 return (__res - 1) - __s;
1690 __STRING_INLINE size_t __strspn_g (const char *__s, const char *__accept);
1691 # ifdef __PIC__
1693 __STRING_INLINE size_t
1694 __strspn_g (const char *__s, const char *__accept)
1696 register unsigned long int __d0, __d1, __d2;
1697 register const char *__res;
1698 __asm__ __volatile__
1699 ("pushl %%ebx\n\t"
1700 "cld\n\t"
1701 "repne; scasb\n\t"
1702 "notl %%ecx\n\t"
1703 "leal -1(%%ecx),%%ebx\n"
1704 "1:\n\t"
1705 "lodsb\n\t"
1706 "testb %%al,%%al\n\t"
1707 "je 2f\n\t"
1708 "movl %%edx,%%edi\n\t"
1709 "movl %%ebx,%%ecx\n\t"
1710 "repne; scasb\n\t"
1711 "je 1b\n"
1712 "2:\n\t"
1713 "popl %%ebx"
1714 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1715 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1716 : "memory", "cc");
1717 return (__res - 1) - __s;
1719 # else
1720 __STRING_INLINE size_t
1721 __strspn_g (const char *__s, const char *__accept)
1723 register unsigned long int __d0, __d1, __d2, __d3;
1724 register const char *__res;
1725 __asm__ __volatile__
1726 ("cld\n\t"
1727 "repne; scasb\n\t"
1728 "notl %%ecx\n\t"
1729 "leal -1(%%ecx),%%edx\n"
1730 "1:\n\t"
1731 "lodsb\n\t"
1732 "testb %%al,%%al\n\t"
1733 "je 2f\n\t"
1734 "movl %%ebx,%%edi\n\t"
1735 "movl %%edx,%%ecx\n\t"
1736 "repne; scasb\n\t"
1737 "je 1b\n"
1738 "2:"
1739 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1740 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1741 : "memory", "cc");
1742 return (__res - 1) - __s;
1744 # endif
1747 /* Find the first occurrence in S of any character in ACCEPT. */
1748 # define _HAVE_STRING_ARCH_strpbrk 1
1749 # define strpbrk(s, accept) \
1750 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1751 ? ((accept)[0] == '\0' \
1752 ? ((void) (s), (char *) 0) \
1753 : ((accept)[1] == '\0' \
1754 ? strchr ((s), (accept)[0]) \
1755 : __strpbrk_cg ((s), (accept), strlen (accept)))) \
1756 : __strpbrk_g ((s), (accept))))
1758 __STRING_INLINE char *__strpbrk_cg (const char *__s, const char __accept[],
1759 size_t __accept_len);
1761 __STRING_INLINE char *
1762 __strpbrk_cg (const char *__s, const char __accept[], size_t __accept_len)
1764 register unsigned long int __d0, __d1, __d2;
1765 register char *__res;
1766 __asm__ __volatile__
1767 ("cld\n"
1768 "1:\n\t"
1769 "lodsb\n\t"
1770 "testb %%al,%%al\n\t"
1771 "je 2f\n\t"
1772 "movl %5,%%edi\n\t"
1773 "movl %6,%%ecx\n\t"
1774 "repne; scasb\n\t"
1775 "jne 1b\n\t"
1776 "decl %0\n\t"
1777 "jmp 3f\n"
1778 "2:\n\t"
1779 "xorl %0,%0\n"
1780 "3:"
1781 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1782 : "0" (__s), "d" (__accept), "g" (__accept_len)
1783 : "memory", "cc");
1784 return __res;
1787 __STRING_INLINE char *__strpbrk_g (const char *__s, const char *__accept);
1788 # ifdef __PIC__
1790 __STRING_INLINE char *
1791 __strpbrk_g (const char *__s, const char *__accept)
1793 register unsigned long int __d0, __d1, __d2;
1794 register char *__res;
1795 __asm__ __volatile__
1796 ("pushl %%ebx\n\t"
1797 "movl %%edx,%%edi\n\t"
1798 "cld\n\t"
1799 "repne; scasb\n\t"
1800 "notl %%ecx\n\t"
1801 "leal -1(%%ecx),%%ebx\n"
1802 "1:\n\t"
1803 "lodsb\n\t"
1804 "testb %%al,%%al\n\t"
1805 "je 2f\n\t"
1806 "movl %%edx,%%edi\n\t"
1807 "movl %%ebx,%%ecx\n\t"
1808 "repne; scasb\n\t"
1809 "jne 1b\n\t"
1810 "decl %0\n\t"
1811 "jmp 3f\n"
1812 "2:\n\t"
1813 "xorl %0,%0\n"
1814 "3:\n\t"
1815 "popl %%ebx"
1816 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1817 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1818 : "memory", "cc");
1819 return __res;
1821 # else
1822 __STRING_INLINE char *
1823 __strpbrk_g (const char *__s, const char *__accept)
1825 register unsigned long int __d0, __d1, __d2, __d3;
1826 register char *__res;
1827 __asm__ __volatile__
1828 ("movl %%ebx,%%edi\n\t"
1829 "cld\n\t"
1830 "repne; scasb\n\t"
1831 "notl %%ecx\n\t"
1832 "leal -1(%%ecx),%%edx\n"
1833 "1:\n\t"
1834 "lodsb\n\t"
1835 "testb %%al,%%al\n\t"
1836 "je 2f\n\t"
1837 "movl %%ebx,%%edi\n\t"
1838 "movl %%edx,%%ecx\n\t"
1839 "repne; scasb\n\t"
1840 "jne 1b\n\t"
1841 "decl %0\n\t"
1842 "jmp 3f\n"
1843 "2:\n\t"
1844 "xorl %0,%0\n"
1845 "3:"
1846 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1847 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1848 : "memory", "cc");
1849 return __res;
1851 # endif
1854 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1855 # define _HAVE_STRING_ARCH_strstr 1
1856 # define strstr(haystack, needle) \
1857 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1858 ? ((needle)[0] == '\0' \
1859 ? (haystack) \
1860 : ((needle)[1] == '\0' \
1861 ? strchr ((haystack), (needle)[0]) \
1862 : __strstr_cg ((haystack), (needle), \
1863 strlen (needle)))) \
1864 : __strstr_g ((haystack), (needle))))
1866 /* Please note that this function need not handle NEEDLEs with a
1867 length shorter than two. */
1868 __STRING_INLINE char *__strstr_cg (const char *__haystack,
1869 const char __needle[],
1870 size_t __needle_len);
1872 __STRING_INLINE char *
1873 __strstr_cg (const char *__haystack, const char __needle[],
1874 size_t __needle_len)
1876 register unsigned long int __d0, __d1, __d2;
1877 register char *__res;
1878 __asm__ __volatile__
1879 ("cld\n" \
1880 "1:\n\t"
1881 "movl %6,%%edi\n\t"
1882 "movl %5,%%eax\n\t"
1883 "movl %4,%%ecx\n\t"
1884 "repe; cmpsb\n\t"
1885 "je 2f\n\t"
1886 "cmpb $0,-1(%%esi)\n\t"
1887 "leal 1(%%eax),%5\n\t"
1888 "jne 1b\n\t"
1889 "xorl %%eax,%%eax\n"
1890 "2:"
1891 : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1892 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1893 : "memory", "cc");
1894 return __res;
1897 __STRING_INLINE char *__strstr_g (const char *__haystack,
1898 const char *__needle);
1899 # ifdef __PIC__
1901 __STRING_INLINE char *
1902 __strstr_g (const char *__haystack, const char *__needle)
1904 register unsigned long int __d0, __d1, __d2;
1905 register char *__res;
1906 __asm__ __volatile__
1907 ("cld\n\t"
1908 "repne; scasb\n\t"
1909 "notl %%ecx\n\t"
1910 "pushl %%ebx\n\t"
1911 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1912 "movl %%ecx,%%ebx\n"
1913 "1:\n\t"
1914 "movl %%edx,%%edi\n\t"
1915 "movl %%esi,%%eax\n\t"
1916 "movl %%ebx,%%ecx\n\t"
1917 "repe; cmpsb\n\t"
1918 "je 2f\n\t" /* also works for empty string, see above */
1919 "cmpb $0,-1(%%esi)\n\t"
1920 "leal 1(%%eax),%%esi\n\t"
1921 "jne 1b\n\t"
1922 "xorl %%eax,%%eax\n"
1923 "2:\n\t"
1924 "popl %%ebx"
1925 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1926 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1927 "d" (__needle)
1928 : "memory", "cc");
1929 return __res;
1931 # else
1932 __STRING_INLINE char *
1933 __strstr_g (const char *__haystack, const char *__needle)
1935 register unsigned long int __d0, __d1, __d2, __d3;
1936 register char *__res;
1937 __asm__ __volatile__
1938 ("cld\n\t"
1939 "repne; scasb\n\t"
1940 "notl %%ecx\n\t"
1941 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1942 "movl %%ecx,%%edx\n"
1943 "1:\n\t"
1944 "movl %%ebx,%%edi\n\t"
1945 "movl %%esi,%%eax\n\t"
1946 "movl %%edx,%%ecx\n\t"
1947 "repe; cmpsb\n\t"
1948 "je 2f\n\t" /* also works for empty string, see above */
1949 "cmpb $0,-1(%%esi)\n\t"
1950 "leal 1(%%eax),%%esi\n\t"
1951 "jne 1b\n\t"
1952 "xorl %%eax,%%eax\n"
1953 "2:"
1954 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1955 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1956 "b" (__needle)
1957 : "memory", "cc");
1958 return __res;
1960 # endif
1963 /* Bit find functions. We define only the i686 version since for the other
1964 processors gcc generates good code. */
1965 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1966 # ifdef __i686__
1967 # define _HAVE_STRING_ARCH_ffs 1
1968 # define ffs(word) (__builtin_constant_p (word) \
1969 ? __builtin_ffs (word) \
1970 : ({ int __cnt, __tmp; \
1971 __asm__ __volatile__ \
1972 ("bsfl %2,%0\n\t" \
1973 "cmovel %1,%0" \
1974 : "=&r" (__cnt), "=r" (__tmp) \
1975 : "rm" (word), "1" (-1)); \
1976 __cnt + 1; }))
1978 # ifndef ffsl
1979 # define ffsl(word) ffs(word)
1980 # endif
1981 # endif /* i686 */
1982 # endif /* Misc || X/Open */
1984 # ifndef _FORCE_INLINES
1985 # undef __STRING_INLINE
1986 # endif
1988 # endif /* use string inlines && GNU CC */
1990 #endif