Avoid array-bounds warning for strncat on i586 (bug 20260)
[glibc.git] / sysdeps / x86 / bits / string.h
blob805d33f0a2d13743e763e18c5c474c9507186a15
1 /* Optimized, inlined string functions. i486/x86-64 version.
2 Copyright (C) 2001-2016 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 /* Use the unaligned string inline ABI. */
24 #define _STRING_INLINE_unaligned 1
26 /* Don't inline mempcpy into memcpy as x86 has an optimized mempcpy. */
27 #define _HAVE_STRING_ARCH_mempcpy 1
29 /* Enable inline functions only for i486 or better when compiling for
30 ia32. */
31 #if !defined __x86_64__ && (defined __i486__ || defined __pentium__ \
32 || defined __pentiumpro__ || defined __pentium4__ \
33 || defined __nocona__ || defined __atom__ \
34 || defined __core2__ || defined __corei7__ \
35 || defined __sandybridge__ || defined __haswell__ \
36 || defined __bonnell__ || defined __silvermont__ \
37 || defined __k6__ || defined __geode__ \
38 || defined __k8__ || defined __athlon__ \
39 || defined __amdfam10__ || defined __bdver1__ \
40 || defined __bdver2__ || defined __bdver3__ \
41 || defined __bdver4__ || defined __btver1__ \
42 || defined __btver2__)
44 /* We only provide optimizations if the user selects them and if
45 GNU CC is used. */
46 # if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
47 && defined __GNUC__ && __GNUC__ >= 2
49 # ifndef __STRING_INLINE
50 # ifndef __extern_inline
51 # define __STRING_INLINE inline
52 # else
53 # define __STRING_INLINE __extern_inline
54 # endif
55 # endif
57 /* The macros are used in some of the optimized implementations below. */
58 # define __STRING_SMALL_GET16(src, idx) \
59 ((((const unsigned char *) (src))[idx + 1] << 8) \
60 | ((const unsigned char *) (src))[idx])
61 # define __STRING_SMALL_GET32(src, idx) \
62 (((((const unsigned char *) (src))[idx + 3] << 8 \
63 | ((const unsigned char *) (src))[idx + 2]) << 8 \
64 | ((const unsigned char *) (src))[idx + 1]) << 8 \
65 | ((const unsigned char *) (src))[idx])
68 /* Copy N bytes of SRC to DEST. */
69 # define _HAVE_STRING_ARCH_memcpy 1
70 # define memcpy(dest, src, n) \
71 (__extension__ (__builtin_constant_p (n) \
72 ? __memcpy_c ((dest), (src), (n)) \
73 : __memcpy_g ((dest), (src), (n))))
74 # define __memcpy_c(dest, src, n) \
75 ((n) == 0 \
76 ? (dest) \
77 : (((n) % 4 == 0) \
78 ? __memcpy_by4 (dest, src, n) \
79 : (((n) % 2 == 0) \
80 ? __memcpy_by2 (dest, src, n) \
81 : __memcpy_g (dest, src, n))))
83 __STRING_INLINE void *__memcpy_by4 (void *__dest, const void *__src,
84 size_t __n);
86 __STRING_INLINE void *
87 __memcpy_by4 (void *__dest, const void *__src, size_t __n)
89 register unsigned long int __d0, __d1;
90 register void *__tmp = __dest;
91 __asm__ __volatile__
92 ("1:\n\t"
93 "movl (%2),%0\n\t"
94 "leal 4(%2),%2\n\t"
95 "movl %0,(%1)\n\t"
96 "leal 4(%1),%1\n\t"
97 "decl %3\n\t"
98 "jnz 1b"
99 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
100 : "1" (__tmp), "2" (__src), "3" (__n / 4)
101 : "memory", "cc");
102 return __dest;
105 __STRING_INLINE void *__memcpy_by2 (void *__dest, const void *__src,
106 size_t __n);
108 __STRING_INLINE void *
109 __memcpy_by2 (void *__dest, const void *__src, size_t __n)
111 register unsigned long int __d0, __d1;
112 register void *__tmp = __dest;
113 __asm__ __volatile__
114 ("shrl $1,%3\n\t"
115 "jz 2f\n" /* only a word */
116 "1:\n\t"
117 "movl (%2),%0\n\t"
118 "leal 4(%2),%2\n\t"
119 "movl %0,(%1)\n\t"
120 "leal 4(%1),%1\n\t"
121 "decl %3\n\t"
122 "jnz 1b\n"
123 "2:\n\t"
124 "movw (%2),%w0\n\t"
125 "movw %w0,(%1)"
126 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
127 : "1" (__tmp), "2" (__src), "3" (__n / 2)
128 : "memory", "cc");
129 return __dest;
132 __STRING_INLINE void *__memcpy_g (void *__dest, const void *__src, size_t __n);
134 __STRING_INLINE void *
135 __memcpy_g (void *__dest, const void *__src, size_t __n)
137 register unsigned long int __d0, __d1, __d2;
138 register void *__tmp = __dest;
139 __asm__ __volatile__
140 ("cld\n\t"
141 "shrl $1,%%ecx\n\t"
142 "jnc 1f\n\t"
143 "movsb\n"
144 "1:\n\t"
145 "shrl $1,%%ecx\n\t"
146 "jnc 2f\n\t"
147 "movsw\n"
148 "2:\n\t"
149 "rep; movsl"
150 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2),
151 "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
152 : "0" (__n), "1" (__tmp), "2" (__src),
153 "m" ( *(struct { __extension__ char __x[__n]; } *)__src)
154 : "cc");
155 return __dest;
158 # define _HAVE_STRING_ARCH_memmove 1
159 # ifndef _FORCE_INLINES
160 /* Copy N bytes of SRC to DEST, guaranteeing
161 correct behavior for overlapping strings. */
162 # define memmove(dest, src, n) __memmove_g (dest, src, n)
164 __STRING_INLINE void *__memmove_g (void *, const void *, size_t)
165 __asm__ ("memmove");
167 __STRING_INLINE void *
168 __memmove_g (void *__dest, const void *__src, size_t __n)
170 register unsigned long int __d0, __d1, __d2;
171 register void *__tmp = __dest;
172 if (__dest < __src)
173 __asm__ __volatile__
174 ("cld\n\t"
175 "rep; movsb"
176 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2),
177 "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
178 : "0" (__n), "1" (__src), "2" (__tmp),
179 "m" ( *(struct { __extension__ char __x[__n]; } *)__src));
180 else
181 __asm__ __volatile__
182 ("decl %1\n\t"
183 "decl %2\n\t"
184 "std\n\t"
185 "rep; movsb\n\t"
186 "cld"
187 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2),
188 "=m" ( *(struct { __extension__ char __x[__n]; } *)__dest)
189 : "0" (__n), "1" (__n + (const char *) __src),
190 "2" (__n + (char *) __tmp),
191 "m" ( *(struct { __extension__ char __x[__n]; } *)__src));
192 return __dest;
194 # endif
196 /* Compare N bytes of S1 and S2. */
197 # define _HAVE_STRING_ARCH_memcmp 1
198 # ifndef _FORCE_INLINES
199 # ifndef __PIC__
200 /* gcc has problems to spill registers when using PIC. */
201 __STRING_INLINE int
202 memcmp (const void *__s1, const void *__s2, size_t __n)
204 register unsigned long int __d0, __d1, __d2;
205 register int __res;
206 __asm__ __volatile__
207 ("cld\n\t"
208 "testl %3,%3\n\t"
209 "repe; cmpsb\n\t"
210 "je 1f\n\t"
211 "sbbl %0,%0\n\t"
212 "orl $1,%0\n"
213 "1:"
214 : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
215 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n),
216 "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
217 "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
218 : "cc");
219 return __res;
221 # endif
222 # endif
224 /* Set N bytes of S to C. */
225 # define _HAVE_STRING_ARCH_memset 1
226 # define _USE_STRING_ARCH_memset 1
227 # define memset(s, c, n) \
228 (__extension__ (__builtin_constant_p (n) && (n) <= 16 \
229 ? ((n) == 1 \
230 ? __memset_c1 ((s), (c)) \
231 : __memset_gc ((s), (c), (n))) \
232 : (__builtin_constant_p (c) \
233 ? (__builtin_constant_p (n) \
234 ? __memset_ccn ((s), (c), (n)) \
235 : memset ((s), (c), (n))) \
236 : (__builtin_constant_p (n) \
237 ? __memset_gcn ((s), (c), (n)) \
238 : memset ((s), (c), (n))))))
240 # define __memset_c1(s, c) ({ void *__s = (s); \
241 *((unsigned char *) __s) = (unsigned char) (c); \
242 __s; })
244 # define __memset_gc(s, c, n) \
245 ({ void *__s = (s); \
246 union { \
247 unsigned int __ui; \
248 unsigned short int __usi; \
249 unsigned char __uc; \
250 } *__u = __s; \
251 unsigned int __c = ((unsigned int) ((unsigned char) (c))) * 0x01010101; \
253 /* We apply a trick here. `gcc' would implement the following \
254 assignments using immediate operands. But this uses to much \
255 memory (7, instead of 4 bytes). So we force the value in a \
256 registers. */ \
257 if ((n) == 3 || (n) >= 5) \
258 __asm__ __volatile__ ("" : "=r" (__c) : "0" (__c)); \
260 /* This `switch' statement will be removed at compile-time. */ \
261 switch (n) \
263 case 15: \
264 __u->__ui = __c; \
265 __u = __extension__ ((void *) __u + 4); \
266 case 11: \
267 __u->__ui = __c; \
268 __u = __extension__ ((void *) __u + 4); \
269 case 7: \
270 __u->__ui = __c; \
271 __u = __extension__ ((void *) __u + 4); \
272 case 3: \
273 __u->__usi = (unsigned short int) __c; \
274 __u = __extension__ ((void *) __u + 2); \
275 __u->__uc = (unsigned char) __c; \
276 break; \
278 case 14: \
279 __u->__ui = __c; \
280 __u = __extension__ ((void *) __u + 4); \
281 case 10: \
282 __u->__ui = __c; \
283 __u = __extension__ ((void *) __u + 4); \
284 case 6: \
285 __u->__ui = __c; \
286 __u = __extension__ ((void *) __u + 4); \
287 case 2: \
288 __u->__usi = (unsigned short int) __c; \
289 break; \
291 case 13: \
292 __u->__ui = __c; \
293 __u = __extension__ ((void *) __u + 4); \
294 case 9: \
295 __u->__ui = __c; \
296 __u = __extension__ ((void *) __u + 4); \
297 case 5: \
298 __u->__ui = __c; \
299 __u = __extension__ ((void *) __u + 4); \
300 case 1: \
301 __u->__uc = (unsigned char) __c; \
302 break; \
304 case 16: \
305 __u->__ui = __c; \
306 __u = __extension__ ((void *) __u + 4); \
307 case 12: \
308 __u->__ui = __c; \
309 __u = __extension__ ((void *) __u + 4); \
310 case 8: \
311 __u->__ui = __c; \
312 __u = __extension__ ((void *) __u + 4); \
313 case 4: \
314 __u->__ui = __c; \
315 case 0: \
316 break; \
319 __s; })
321 # define __memset_ccn(s, c, n) \
322 (((n) % 4 == 0) \
323 ? __memset_ccn_by4 (s, ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
324 n) \
325 : (((n) % 2 == 0) \
326 ? __memset_ccn_by2 (s, \
327 ((unsigned int) ((unsigned char) (c))) * 0x01010101,\
328 n) \
329 : memset (s, c, n)))
331 __STRING_INLINE void *__memset_ccn_by4 (void *__s, unsigned int __c,
332 size_t __n);
334 __STRING_INLINE void *
335 __memset_ccn_by4 (void *__s, unsigned int __c, size_t __n)
337 register void *__tmp = __s;
338 register unsigned long int __d0;
339 # ifdef __i686__
340 __asm__ __volatile__
341 ("cld\n\t"
342 "rep; stosl"
343 : "=&a" (__c), "=&D" (__tmp), "=&c" (__d0),
344 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
345 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
346 : "cc");
347 # else
348 __asm__ __volatile__
349 ("1:\n\t"
350 "movl %0,(%1)\n\t"
351 "addl $4,%1\n\t"
352 "decl %2\n\t"
353 "jnz 1b\n"
354 : "=&r" (__c), "=&r" (__tmp), "=&r" (__d0),
355 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
356 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
357 : "cc");
358 # endif
359 return __s;
362 __STRING_INLINE void *__memset_ccn_by2 (void *__s, unsigned int __c,
363 size_t __n);
365 __STRING_INLINE void *
366 __memset_ccn_by2 (void *__s, unsigned int __c, size_t __n)
368 register unsigned long int __d0, __d1;
369 register void *__tmp = __s;
370 # ifdef __i686__
371 __asm__ __volatile__
372 ("cld\n\t"
373 "rep; stosl\n"
374 "stosw"
375 : "=&a" (__d0), "=&D" (__tmp), "=&c" (__d1),
376 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
377 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
378 : "cc");
379 # else
380 __asm__ __volatile__
381 ("1:\tmovl %0,(%1)\n\t"
382 "leal 4(%1),%1\n\t"
383 "decl %2\n\t"
384 "jnz 1b\n"
385 "movw %w0,(%1)"
386 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1),
387 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
388 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
389 : "cc");
390 #endif
391 return __s;
394 # define __memset_gcn(s, c, n) \
395 (((n) % 4 == 0) \
396 ? __memset_gcn_by4 (s, c, n) \
397 : (((n) % 2 == 0) \
398 ? __memset_gcn_by2 (s, c, n) \
399 : memset (s, c, n)))
401 __STRING_INLINE void *__memset_gcn_by4 (void *__s, int __c, size_t __n);
403 __STRING_INLINE void *
404 __memset_gcn_by4 (void *__s, int __c, size_t __n)
406 register void *__tmp = __s;
407 register unsigned long int __d0;
408 __asm__ __volatile__
409 ("movb %b0,%h0\n"
410 "pushw %w0\n\t"
411 "shll $16,%0\n\t"
412 "popw %w0\n"
413 "1:\n\t"
414 "movl %0,(%1)\n\t"
415 "addl $4,%1\n\t"
416 "decl %2\n\t"
417 "jnz 1b\n"
418 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0),
419 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
420 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
421 : "cc");
422 return __s;
425 __STRING_INLINE void *__memset_gcn_by2 (void *__s, int __c, size_t __n);
427 __STRING_INLINE void *
428 __memset_gcn_by2 (void *__s, int __c, size_t __n)
430 register unsigned long int __d0, __d1;
431 register void *__tmp = __s;
432 __asm__ __volatile__
433 ("movb %b0,%h0\n\t"
434 "pushw %w0\n\t"
435 "shll $16,%0\n\t"
436 "popw %w0\n"
437 "1:\n\t"
438 "movl %0,(%1)\n\t"
439 "leal 4(%1),%1\n\t"
440 "decl %2\n\t"
441 "jnz 1b\n"
442 "movw %w0,(%1)"
443 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1),
444 "=m" ( *(struct { __extension__ char __x[__n]; } *)__s)
445 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
446 : "cc");
447 return __s;
451 /* Search N bytes of S for C. */
452 # define _HAVE_STRING_ARCH_memchr 1
453 # ifndef _FORCE_INLINES
454 __STRING_INLINE void *
455 memchr (const void *__s, int __c, size_t __n)
457 register unsigned long int __d0;
458 # ifdef __i686__
459 register unsigned long int __d1;
460 # endif
461 register unsigned char *__res;
462 if (__n == 0)
463 return NULL;
464 # ifdef __i686__
465 __asm__ __volatile__
466 ("cld\n\t"
467 "repne; scasb\n\t"
468 "cmovne %2,%0"
469 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
470 : "a" (__c), "0" (__s), "1" (__n), "2" (1),
471 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
472 : "cc");
473 # else
474 __asm__ __volatile__
475 ("cld\n\t"
476 "repne; scasb\n\t"
477 "je 1f\n\t"
478 "movl $1,%0\n"
479 "1:"
480 : "=D" (__res), "=&c" (__d0)
481 : "a" (__c), "0" (__s), "1" (__n),
482 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
483 : "cc");
484 # endif
485 return __res - 1;
487 # endif
489 # define _HAVE_STRING_ARCH_memrchr 1
490 # ifndef _FORCE_INLINES
491 __STRING_INLINE void *__memrchr (const void *__s, int __c, size_t __n);
493 __STRING_INLINE void *
494 __memrchr (const void *__s, int __c, size_t __n)
496 register unsigned long int __d0;
497 # ifdef __i686__
498 register unsigned long int __d1;
499 # endif
500 register void *__res;
501 if (__n == 0)
502 return NULL;
503 # ifdef __i686__
504 __asm__ __volatile__
505 ("std\n\t"
506 "repne; scasb\n\t"
507 "cmovne %2,%0\n\t"
508 "cld\n\t"
509 "incl %0"
510 : "=D" (__res), "=&c" (__d0), "=&r" (__d1)
511 : "a" (__c), "0" (__s + __n - 1), "1" (__n), "2" (-1),
512 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
513 : "cc");
514 # else
515 __asm__ __volatile__
516 ("std\n\t"
517 "repne; scasb\n\t"
518 "je 1f\n\t"
519 "orl $-1,%0\n"
520 "1:\tcld\n\t"
521 "incl %0"
522 : "=D" (__res), "=&c" (__d0)
523 : "a" (__c), "0" (__s + __n - 1), "1" (__n),
524 "m" ( *(struct { __extension__ char __x[__n]; } *)__s)
525 : "cc");
526 # endif
527 return __res;
529 # ifdef __USE_GNU
530 # define memrchr(s, c, n) __memrchr ((s), (c), (n))
531 # endif
532 # endif
534 /* Return pointer to C in S. */
535 # define _HAVE_STRING_ARCH_rawmemchr 1
536 __STRING_INLINE void *__rawmemchr (const void *__s, int __c);
538 # ifndef _FORCE_INLINES
539 __STRING_INLINE void *
540 __rawmemchr (const void *__s, int __c)
542 register unsigned long int __d0;
543 register unsigned char *__res;
544 __asm__ __volatile__
545 ("cld\n\t"
546 "repne; scasb\n\t"
547 : "=D" (__res), "=&c" (__d0)
548 : "a" (__c), "0" (__s), "1" (0xffffffff),
549 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
550 : "cc");
551 return __res - 1;
553 # ifdef __USE_GNU
554 __STRING_INLINE void *
555 rawmemchr (const void *__s, int __c)
557 return __rawmemchr (__s, __c);
559 # endif /* use GNU */
560 # endif
563 /* Return the length of S. */
564 # define _HAVE_STRING_ARCH_strlen 1
565 # define strlen(str) \
566 (__extension__ (__builtin_constant_p (str) \
567 ? __builtin_strlen (str) \
568 : __strlen_g (str)))
569 __STRING_INLINE size_t __strlen_g (const char *__str);
571 __STRING_INLINE size_t
572 __strlen_g (const char *__str)
574 register char __dummy;
575 register const char *__tmp = __str;
576 __asm__ __volatile__
577 ("1:\n\t"
578 "movb (%0),%b1\n\t"
579 "leal 1(%0),%0\n\t"
580 "testb %b1,%b1\n\t"
581 "jne 1b"
582 : "=r" (__tmp), "=&q" (__dummy)
583 : "0" (__str),
584 "m" ( *(struct { char __x[0xfffffff]; } *)__str)
585 : "cc" );
586 return __tmp - __str - 1;
590 /* Copy SRC to DEST. */
591 # define _HAVE_STRING_ARCH_strcpy 1
592 # define strcpy(dest, src) \
593 (__extension__ (__builtin_constant_p (src) \
594 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
595 ? __strcpy_a_small ((dest), (src), strlen (src) + 1) \
596 : (char *) memcpy ((char *) (dest), \
597 (const char *) (src), \
598 strlen (src) + 1)) \
599 : __strcpy_g ((dest), (src))))
601 # define __strcpy_a_small(dest, src, srclen) \
602 (__extension__ ({ char *__dest = (dest); \
603 union { \
604 unsigned int __ui; \
605 unsigned short int __usi; \
606 unsigned char __uc; \
607 char __c; \
608 } *__u = (void *) __dest; \
609 switch (srclen) \
611 case 1: \
612 __u->__uc = '\0'; \
613 break; \
614 case 2: \
615 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
616 break; \
617 case 3: \
618 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
619 __u = __extension__ ((void *) __u + 2); \
620 __u->__uc = '\0'; \
621 break; \
622 case 4: \
623 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
624 break; \
625 case 5: \
626 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
627 __u = __extension__ ((void *) __u + 4); \
628 __u->__uc = '\0'; \
629 break; \
630 case 6: \
631 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
632 __u = __extension__ ((void *) __u + 4); \
633 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
634 break; \
635 case 7: \
636 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
637 __u = __extension__ ((void *) __u + 4); \
638 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
639 __u = __extension__ ((void *) __u + 2); \
640 __u->__uc = '\0'; \
641 break; \
642 case 8: \
643 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
644 __u = __extension__ ((void *) __u + 4); \
645 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
646 break; \
648 (char *) __dest; }))
650 __STRING_INLINE char *__strcpy_g (char *__dest, const char *__src);
652 __STRING_INLINE char *
653 __strcpy_g (char *__dest, const char *__src)
655 register char *__tmp = __dest;
656 register char __dummy;
657 __asm__ __volatile__
659 "1:\n\t"
660 "movb (%0),%b2\n\t"
661 "leal 1(%0),%0\n\t"
662 "movb %b2,(%1)\n\t"
663 "leal 1(%1),%1\n\t"
664 "testb %b2,%b2\n\t"
665 "jne 1b"
666 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy),
667 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
668 : "0" (__src), "1" (__tmp),
669 "m" ( *(struct { char __x[0xfffffff]; } *)__src)
670 : "cc");
671 return __dest;
675 # ifdef __USE_GNU
676 # define _HAVE_STRING_ARCH_stpcpy 1
677 /* Copy SRC to DEST. */
678 # define __stpcpy(dest, src) \
679 (__extension__ (__builtin_constant_p (src) \
680 ? (strlen (src) + 1 <= 8 \
681 ? __stpcpy_a_small ((dest), (src), strlen (src) + 1) \
682 : __stpcpy_c ((dest), (src), strlen (src) + 1)) \
683 : __stpcpy_g ((dest), (src))))
684 # define __stpcpy_c(dest, src, srclen) \
685 ((srclen) % 4 == 0 \
686 ? __mempcpy_by4 (dest, src, srclen) - 1 \
687 : ((srclen) % 2 == 0 \
688 ? __mempcpy_by2 (dest, src, srclen) - 1 \
689 : __mempcpy_byn (dest, src, srclen) - 1))
691 /* In glibc itself we use this symbol for namespace reasons. */
692 # define stpcpy(dest, src) __stpcpy ((dest), (src))
694 # define __stpcpy_a_small(dest, src, srclen) \
695 (__extension__ ({ union { \
696 unsigned int __ui; \
697 unsigned short int __usi; \
698 unsigned char __uc; \
699 char __c; \
700 } *__u = (void *) (dest); \
701 switch (srclen) \
703 case 1: \
704 __u->__uc = '\0'; \
705 break; \
706 case 2: \
707 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
708 __u = __extension__ ((void *) __u + 1); \
709 break; \
710 case 3: \
711 __u->__usi = __STRING_SMALL_GET16 (src, 0); \
712 __u = __extension__ ((void *) __u + 2); \
713 __u->__uc = '\0'; \
714 break; \
715 case 4: \
716 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
717 __u = __extension__ ((void *) __u + 3); \
718 break; \
719 case 5: \
720 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
721 __u = __extension__ ((void *) __u + 4); \
722 __u->__uc = '\0'; \
723 break; \
724 case 6: \
725 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
726 __u = __extension__ ((void *) __u + 4); \
727 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
728 __u = __extension__ ((void *) __u + 1); \
729 break; \
730 case 7: \
731 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
732 __u = __extension__ ((void *) __u + 4); \
733 __u->__usi = __STRING_SMALL_GET16 (src, 4); \
734 __u = __extension__ ((void *) __u + 2); \
735 __u->__uc = '\0'; \
736 break; \
737 case 8: \
738 __u->__ui = __STRING_SMALL_GET32 (src, 0); \
739 __u = __extension__ ((void *) __u + 4); \
740 __u->__ui = __STRING_SMALL_GET32 (src, 4); \
741 __u = __extension__ ((void *) __u + 3); \
742 break; \
744 (char *) __u; }))
746 __STRING_INLINE char *__mempcpy_by4 (char *__dest, const char *__src,
747 size_t __srclen);
749 __STRING_INLINE char *
750 __mempcpy_by4 (char *__dest, const char *__src, size_t __srclen)
752 register char *__tmp = __dest;
753 register unsigned long int __d0, __d1;
754 __asm__ __volatile__
755 ("1:\n\t"
756 "movl (%2),%0\n\t"
757 "leal 4(%2),%2\n\t"
758 "movl %0,(%1)\n\t"
759 "leal 4(%1),%1\n\t"
760 "decl %3\n\t"
761 "jnz 1b"
762 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
763 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
764 : "memory", "cc");
765 return __tmp;
768 __STRING_INLINE char *__mempcpy_by2 (char *__dest, const char *__src,
769 size_t __srclen);
771 __STRING_INLINE char *
772 __mempcpy_by2 (char *__dest, const char *__src, size_t __srclen)
774 register char *__tmp = __dest;
775 register unsigned long int __d0, __d1;
776 __asm__ __volatile__
777 ("shrl $1,%3\n\t"
778 "jz 2f\n" /* only a word */
779 "1:\n\t"
780 "movl (%2),%0\n\t"
781 "leal 4(%2),%2\n\t"
782 "movl %0,(%1)\n\t"
783 "leal 4(%1),%1\n\t"
784 "decl %3\n\t"
785 "jnz 1b\n"
786 "2:\n\t"
787 "movw (%2),%w0\n\t"
788 "movw %w0,(%1)"
789 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1),
790 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
791 : "1" (__tmp), "2" (__src), "3" (__srclen / 2),
792 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
793 : "cc");
794 return __tmp + 2;
797 __STRING_INLINE char *__mempcpy_byn (char *__dest, const char *__src,
798 size_t __srclen);
800 __STRING_INLINE char *
801 __mempcpy_byn (char *__dest, const char *__src, size_t __srclen)
803 register unsigned long __d0, __d1;
804 register char *__tmp = __dest;
805 __asm__ __volatile__
806 ("cld\n\t"
807 "shrl $1,%%ecx\n\t"
808 "jnc 1f\n\t"
809 "movsb\n"
810 "1:\n\t"
811 "shrl $1,%%ecx\n\t"
812 "jnc 2f\n\t"
813 "movsw\n"
814 "2:\n\t"
815 "rep; movsl"
816 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1),
817 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
818 : "0" (__tmp), "1" (__srclen), "2" (__src),
819 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
820 : "cc");
821 return __tmp;
824 __STRING_INLINE char *__stpcpy_g (char *__dest, const char *__src);
826 __STRING_INLINE char *
827 __stpcpy_g (char *__dest, const char *__src)
829 register char *__tmp = __dest;
830 register char __dummy;
831 __asm__ __volatile__
833 "1:\n\t"
834 "movb (%0),%b2\n\t"
835 "leal 1(%0),%0\n\t"
836 "movb %b2,(%1)\n\t"
837 "leal 1(%1),%1\n\t"
838 "testb %b2,%b2\n\t"
839 "jne 1b"
840 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy),
841 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
842 : "0" (__src), "1" (__tmp),
843 "m" ( *(struct { char __x[0xfffffff]; } *)__src)
844 : "cc");
845 return __tmp - 1;
847 # endif
850 /* Copy no more than N characters of SRC to DEST. */
851 # define _HAVE_STRING_ARCH_strncpy 1
852 # define strncpy(dest, src, n) \
853 (__extension__ (__builtin_constant_p (src) \
854 ? ((strlen (src) + 1 >= ((size_t) (n)) \
855 ? (char *) memcpy ((char *) (dest), \
856 (const char *) (src), n) \
857 : __strncpy_cg ((dest), (src), strlen (src) + 1, n))) \
858 : __strncpy_gg ((dest), (src), n)))
859 # define __strncpy_cg(dest, src, srclen, n) \
860 (((srclen) % 4 == 0) \
861 ? __strncpy_by4 (dest, src, srclen, n) \
862 : (((srclen) % 2 == 0) \
863 ? __strncpy_by2 (dest, src, srclen, n) \
864 : __strncpy_byn (dest, src, srclen, n)))
866 __STRING_INLINE char *__strncpy_by4 (char *__dest, const char __src[],
867 size_t __srclen, size_t __n);
869 __STRING_INLINE char *
870 __strncpy_by4 (char *__dest, const char __src[], size_t __srclen, size_t __n)
872 register char *__tmp = __dest;
873 register int __dummy1, __dummy2;
874 __asm__ __volatile__
875 ("1:\n\t"
876 "movl (%2),%0\n\t"
877 "leal 4(%2),%2\n\t"
878 "movl %0,(%1)\n\t"
879 "leal 4(%1),%1\n\t"
880 "decl %3\n\t"
881 "jnz 1b"
882 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2),
883 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
884 : "1" (__tmp), "2" (__src), "3" (__srclen / 4),
885 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
886 : "cc");
887 (void) memset (__tmp, '\0', __n - __srclen);
888 return __dest;
891 __STRING_INLINE char *__strncpy_by2 (char *__dest, const char __src[],
892 size_t __srclen, size_t __n);
894 __STRING_INLINE char *
895 __strncpy_by2 (char *__dest, const char __src[], size_t __srclen, size_t __n)
897 register char *__tmp = __dest;
898 register int __dummy1, __dummy2;
899 __asm__ __volatile__
900 ("shrl $1,%3\n\t"
901 "jz 2f\n" /* only a word */
902 "1:\n\t"
903 "movl (%2),%0\n\t"
904 "leal 4(%2),%2\n\t"
905 "movl %0,(%1)\n\t"
906 "leal 4(%1),%1\n\t"
907 "decl %3\n\t"
908 "jnz 1b\n"
909 "2:\n\t"
910 "movw (%2),%w0\n\t"
911 "movw %w0,(%1)\n\t"
912 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2),
913 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
914 : "1" (__tmp), "2" (__src), "3" (__srclen / 2),
915 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
916 : "cc");
917 (void) memset (__tmp + 2, '\0', __n - __srclen);
918 return __dest;
921 __STRING_INLINE char *__strncpy_byn (char *__dest, const char __src[],
922 size_t __srclen, size_t __n);
924 __STRING_INLINE char *
925 __strncpy_byn (char *__dest, const char __src[], size_t __srclen, size_t __n)
927 register unsigned long int __d0, __d1;
928 register char *__tmp = __dest;
929 __asm__ __volatile__
930 ("cld\n\t"
931 "shrl $1,%1\n\t"
932 "jnc 1f\n\t"
933 "movsb\n"
934 "1:\n\t"
935 "shrl $1,%1\n\t"
936 "jnc 2f\n\t"
937 "movsw\n"
938 "2:\n\t"
939 "rep; movsl"
940 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1),
941 "=m" ( *(struct { __extension__ char __x[__srclen]; } *)__dest)
942 : "1" (__srclen), "0" (__tmp),"2" (__src),
943 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
944 : "cc");
945 (void) memset (__tmp, '\0', __n - __srclen);
946 return __dest;
949 __STRING_INLINE char *__strncpy_gg (char *__dest, const char *__src,
950 size_t __n);
952 __STRING_INLINE char *
953 __strncpy_gg (char *__dest, const char *__src, size_t __n)
955 register char *__tmp = __dest;
956 register char __dummy;
957 if (__n > 0)
958 __asm__ __volatile__
959 ("1:\n\t"
960 "movb (%0),%2\n\t"
961 "incl %0\n\t"
962 "movb %2,(%1)\n\t"
963 "incl %1\n\t"
964 "decl %3\n\t"
965 "je 3f\n\t"
966 "testb %2,%2\n\t"
967 "jne 1b\n\t"
968 "2:\n\t"
969 "movb %2,(%1)\n\t"
970 "incl %1\n\t"
971 "decl %3\n\t"
972 "jne 2b\n\t"
973 "3:"
974 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
975 : "0" (__src), "1" (__tmp), "3" (__n)
976 : "memory", "cc");
978 return __dest;
982 /* Append SRC onto DEST. */
983 # define _HAVE_STRING_ARCH_strcat 1
984 # define strcat(dest, src) \
985 (__extension__ (__builtin_constant_p (src) \
986 ? __strcat_c ((dest), (src), strlen (src) + 1) \
987 : __strcat_g ((dest), (src))))
989 __STRING_INLINE char *__strcat_c (char *__dest, const char __src[],
990 size_t __srclen);
992 __STRING_INLINE char *
993 __strcat_c (char *__dest, const char __src[], size_t __srclen)
995 # ifdef __i686__
996 register unsigned long int __d0;
997 register char *__tmp;
998 __asm__ __volatile__
999 ("repne; scasb"
1000 : "=D" (__tmp), "=&c" (__d0),
1001 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
1002 : "0" (__dest), "1" (0xffffffff), "a" (0),
1003 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
1004 : "cc");
1005 --__tmp;
1006 # else
1007 register char *__tmp = __dest;
1008 __asm__ __volatile__
1009 ("decl %0\n\t"
1010 "1:\n\t"
1011 "incl %0\n\t"
1012 "cmpb $0,(%0)\n\t"
1013 "jne 1b\n"
1014 : "=r" (__tmp),
1015 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
1016 : "0" (__tmp),
1017 "m" ( *(struct { __extension__ char __x[__srclen]; } *)__src)
1018 : "cc");
1019 # endif
1020 (void) memcpy (__tmp, __src, __srclen);
1021 return __dest;
1024 __STRING_INLINE char *__strcat_g (char *__dest, const char *__src);
1026 __STRING_INLINE char *
1027 __strcat_g (char *__dest, const char *__src)
1029 register char *__tmp = __dest;
1030 register char __dummy;
1031 __asm__ __volatile__
1032 ("decl %1\n\t"
1033 "1:\n\t"
1034 "incl %1\n\t"
1035 "cmpb $0,(%1)\n\t"
1036 "jne 1b\n"
1037 "2:\n\t"
1038 "movb (%2),%b0\n\t"
1039 "incl %2\n\t"
1040 "movb %b0,(%1)\n\t"
1041 "incl %1\n\t"
1042 "testb %b0,%b0\n\t"
1043 "jne 2b\n"
1044 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src),
1045 "=m" ( *(struct { char __x[0xfffffff]; } *)__dest)
1046 : "1" (__tmp), "2" (__src),
1047 "m" ( *(struct { char __x[0xfffffff]; } *)__src)
1048 : "memory", "cc");
1049 return __dest;
1053 /* Append no more than N characters from SRC onto DEST. */
1054 # define _HAVE_STRING_ARCH_strncat 1
1055 # define strncat(dest, src, n) \
1056 (__extension__ ({ char *__dest = (dest); \
1057 __builtin_constant_p (src) && __builtin_constant_p (n) \
1058 ? (strlen (src) < ((size_t) (n)) \
1059 ? strcat (__dest, (src)) \
1060 : (*(char *)__mempcpy (strchr (__dest, '\0'), \
1061 (const char *) (src), \
1062 (n)) = 0, __dest)) \
1063 : __strncat_g (__dest, (src), (n)); }))
1065 __STRING_INLINE char *__strncat_g (char *__dest, const char __src[],
1066 size_t __n);
1068 __STRING_INLINE char *
1069 __strncat_g (char *__dest, const char __src[], size_t __n)
1071 register char *__tmp = __dest;
1072 register char __dummy;
1073 # ifdef __i686__
1074 __asm__ __volatile__
1075 ("repne; scasb\n"
1076 "movl %4, %3\n\t"
1077 "decl %1\n\t"
1078 "1:\n\t"
1079 "subl $1,%3\n\t"
1080 "jc 2f\n\t"
1081 "movb (%2),%b0\n\t"
1082 "movsb\n\t"
1083 "testb %b0,%b0\n\t"
1084 "jne 1b\n\t"
1085 "decl %1\n"
1086 "2:\n\t"
1087 "movb $0,(%1)"
1088 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&c" (__n)
1089 : "g" (__n), "0" (0), "1" (__tmp), "2" (__src), "3" (0xffffffff)
1090 : "memory", "cc");
1091 # else
1092 __asm__ __volatile__
1093 ("1:\n\t"
1094 "cmpb $0,1(%1)\n\t"
1095 "leal 1(%1),%1\n\t"
1096 "jne 1b\n"
1097 "2:\n\t"
1098 "subl $1,%3\n\t"
1099 "jc 3f\n\t"
1100 "movb (%2),%b0\n\t"
1101 "leal 1(%2),%2\n\t"
1102 "movb %b0,(%1)\n\t"
1103 "leal 1(%1),%1\n\t"
1104 "testb %b0,%b0\n\t"
1105 "jne 2b\n\t"
1106 "decl %1\n"
1107 "3:\n\t"
1108 "movb $0,(%1)"
1109 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
1110 : "1" ((unsigned long) __tmp - 1), "2" (__src), "3" (__n)
1111 : "memory", "cc");
1112 #endif
1113 return __dest;
1117 /* Compare S1 and S2. */
1118 # define _HAVE_STRING_ARCH_strcmp 1
1119 # define strcmp(s1, s2) \
1120 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
1121 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
1122 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
1123 ? memcmp ((const char *) (s1), (const char *) (s2), \
1124 (strlen (s1) < strlen (s2) \
1125 ? strlen (s1) : strlen (s2)) + 1) \
1126 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
1127 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
1128 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
1129 ? __strcmp_cc ((const unsigned char *) (s1), \
1130 (const unsigned char *) (s2), \
1131 strlen (s1)) \
1132 : __strcmp_cg ((const unsigned char *) (s1), \
1133 (const unsigned char *) (s2), \
1134 strlen (s1))) \
1135 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
1136 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
1137 ? (__builtin_constant_p (s1) \
1138 ? __strcmp_cc ((const unsigned char *) (s1), \
1139 (const unsigned char *) (s2), \
1140 strlen (s2)) \
1141 : __strcmp_gc ((const unsigned char *) (s1), \
1142 (const unsigned char *) (s2), \
1143 strlen (s2))) \
1144 : __strcmp_gg ((s1), (s2))))))
1146 # define __strcmp_cc(s1, s2, l) \
1147 (__extension__ ({ register int __result = (s1)[0] - (s2)[0]; \
1148 if (l > 0 && __result == 0) \
1150 __result = (s1)[1] - (s2)[1]; \
1151 if (l > 1 && __result == 0) \
1153 __result = (s1)[2] - (s2)[2]; \
1154 if (l > 2 && __result == 0) \
1155 __result = (s1)[3] - (s2)[3]; \
1158 __result; }))
1160 # define __strcmp_cg(s1, s2, l1) \
1161 (__extension__ ({ const unsigned char *__s2 = (s2); \
1162 register int __result = (s1)[0] - __s2[0]; \
1163 if (l1 > 0 && __result == 0) \
1165 __result = (s1)[1] - __s2[1]; \
1166 if (l1 > 1 && __result == 0) \
1168 __result = (s1)[2] - __s2[2]; \
1169 if (l1 > 2 && __result == 0) \
1170 __result = (s1)[3] - __s2[3]; \
1173 __result; }))
1175 # define __strcmp_gc(s1, s2, l2) \
1176 (__extension__ ({ const unsigned char *__s1 = (s1); \
1177 register int __result = __s1[0] - (s2)[0]; \
1178 if (l2 > 0 && __result == 0) \
1180 __result = __s1[1] - (s2)[1]; \
1181 if (l2 > 1 && __result == 0) \
1183 __result = __s1[2] - (s2)[2]; \
1184 if (l2 > 2 && __result == 0) \
1185 __result = __s1[3] - (s2)[3]; \
1188 __result; }))
1190 __STRING_INLINE int __strcmp_gg (const char *__s1, const char *__s2);
1192 __STRING_INLINE int
1193 __strcmp_gg (const char *__s1, const char *__s2)
1195 register int __res;
1196 __asm__ __volatile__
1197 ("1:\n\t"
1198 "movb (%1),%b0\n\t"
1199 "leal 1(%1),%1\n\t"
1200 "cmpb %b0,(%2)\n\t"
1201 "jne 2f\n\t"
1202 "leal 1(%2),%2\n\t"
1203 "testb %b0,%b0\n\t"
1204 "jne 1b\n\t"
1205 "xorl %0,%0\n\t"
1206 "jmp 3f\n"
1207 "2:\n\t"
1208 "movl $1,%0\n\t"
1209 "jb 3f\n\t"
1210 "negl %0\n"
1211 "3:"
1212 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1213 : "1" (__s1), "2" (__s2),
1214 "m" ( *(struct { char __x[0xfffffff]; } *)__s1),
1215 "m" ( *(struct { char __x[0xfffffff]; } *)__s2)
1216 : "cc");
1217 return __res;
1221 /* Compare N characters of S1 and S2. */
1222 # define _HAVE_STRING_ARCH_strncmp 1
1223 # define strncmp(s1, s2, n) \
1224 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1225 ? strcmp ((s1), (s2)) \
1226 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1227 ? strcmp ((s1), (s2)) \
1228 : __strncmp_g ((s1), (s2), (n)))))
1230 __STRING_INLINE int __strncmp_g (const char *__s1, const char *__s2,
1231 size_t __n);
1233 __STRING_INLINE int
1234 __strncmp_g (const char *__s1, const char *__s2, size_t __n)
1236 register int __res;
1237 __asm__ __volatile__
1238 ("1:\n\t"
1239 "subl $1,%3\n\t"
1240 "jc 2f\n\t"
1241 "movb (%1),%b0\n\t"
1242 "incl %1\n\t"
1243 "cmpb %b0,(%2)\n\t"
1244 "jne 3f\n\t"
1245 "incl %2\n\t"
1246 "testb %b0,%b0\n\t"
1247 "jne 1b\n"
1248 "2:\n\t"
1249 "xorl %0,%0\n\t"
1250 "jmp 4f\n"
1251 "3:\n\t"
1252 "movl $1,%0\n\t"
1253 "jb 4f\n\t"
1254 "negl %0\n"
1255 "4:"
1256 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1257 : "1" (__s1), "2" (__s2), "3" (__n),
1258 "m" ( *(struct { __extension__ char __x[__n]; } *)__s1),
1259 "m" ( *(struct { __extension__ char __x[__n]; } *)__s2)
1260 : "cc");
1261 return __res;
1265 /* Find the first occurrence of C in S. */
1266 # define _HAVE_STRING_ARCH_strchr 1
1267 # define _USE_STRING_ARCH_strchr 1
1268 # define strchr(s, c) \
1269 (__extension__ (__builtin_constant_p (c) \
1270 ? ((c) == '\0' \
1271 ? (char *) __rawmemchr ((s), (c)) \
1272 : __strchr_c ((s), ((c) & 0xff) << 8)) \
1273 : __strchr_g ((s), (c))))
1275 __STRING_INLINE char *__strchr_c (const char *__s, int __c);
1277 __STRING_INLINE char *
1278 __strchr_c (const char *__s, int __c)
1280 register unsigned long int __d0;
1281 register char *__res;
1282 __asm__ __volatile__
1283 ("1:\n\t"
1284 "movb (%0),%%al\n\t"
1285 "cmpb %%ah,%%al\n\t"
1286 "je 2f\n\t"
1287 "leal 1(%0),%0\n\t"
1288 "testb %%al,%%al\n\t"
1289 "jne 1b\n\t"
1290 "xorl %0,%0\n"
1291 "2:"
1292 : "=r" (__res), "=&a" (__d0)
1293 : "0" (__s), "1" (__c),
1294 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1295 : "cc");
1296 return __res;
1299 __STRING_INLINE char *__strchr_g (const char *__s, int __c);
1301 __STRING_INLINE char *
1302 __strchr_g (const char *__s, int __c)
1304 register unsigned long int __d0;
1305 register char *__res;
1306 __asm__ __volatile__
1307 ("movb %%al,%%ah\n"
1308 "1:\n\t"
1309 "movb (%0),%%al\n\t"
1310 "cmpb %%ah,%%al\n\t"
1311 "je 2f\n\t"
1312 "leal 1(%0),%0\n\t"
1313 "testb %%al,%%al\n\t"
1314 "jne 1b\n\t"
1315 "xorl %0,%0\n"
1316 "2:"
1317 : "=r" (__res), "=&a" (__d0)
1318 : "0" (__s), "1" (__c),
1319 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1320 : "cc");
1321 return __res;
1325 /* Find the first occurrence of C in S or the final NUL byte. */
1326 # define _HAVE_STRING_ARCH_strchrnul 1
1327 # define __strchrnul(s, c) \
1328 (__extension__ (__builtin_constant_p (c) \
1329 ? ((c) == '\0' \
1330 ? (char *) __rawmemchr ((s), c) \
1331 : __strchrnul_c ((s), ((c) & 0xff) << 8)) \
1332 : __strchrnul_g ((s), c)))
1334 __STRING_INLINE char *__strchrnul_c (const char *__s, int __c);
1336 __STRING_INLINE char *
1337 __strchrnul_c (const char *__s, int __c)
1339 register unsigned long int __d0;
1340 register char *__res;
1341 __asm__ __volatile__
1342 ("1:\n\t"
1343 "movb (%0),%%al\n\t"
1344 "cmpb %%ah,%%al\n\t"
1345 "je 2f\n\t"
1346 "leal 1(%0),%0\n\t"
1347 "testb %%al,%%al\n\t"
1348 "jne 1b\n\t"
1349 "decl %0\n"
1350 "2:"
1351 : "=r" (__res), "=&a" (__d0)
1352 : "0" (__s), "1" (__c),
1353 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1354 : "cc");
1355 return __res;
1358 __STRING_INLINE char *__strchrnul_g (const char *__s, int __c);
1360 __STRING_INLINE char *
1361 __strchrnul_g (const char *__s, int __c)
1363 register unsigned long int __d0;
1364 register char *__res;
1365 __asm__ __volatile__
1366 ("movb %%al,%%ah\n"
1367 "1:\n\t"
1368 "movb (%0),%%al\n\t"
1369 "cmpb %%ah,%%al\n\t"
1370 "je 2f\n\t"
1371 "leal 1(%0),%0\n\t"
1372 "testb %%al,%%al\n\t"
1373 "jne 1b\n\t"
1374 "decl %0\n"
1375 "2:"
1376 : "=r" (__res), "=&a" (__d0)
1377 : "0" (__s), "1" (__c),
1378 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1379 : "cc");
1380 return __res;
1382 # ifdef __USE_GNU
1383 # define strchrnul(s, c) __strchrnul ((s), (c))
1384 # endif
1387 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1388 /* Find the first occurrence of C in S. This is the BSD name. */
1389 # define _HAVE_STRING_ARCH_index 1
1390 # define index(s, c) \
1391 (__extension__ (__builtin_constant_p (c) \
1392 ? __strchr_c ((s), ((c) & 0xff) << 8) \
1393 : __strchr_g ((s), (c))))
1394 # endif
1397 /* Find the last occurrence of C in S. */
1398 # define _HAVE_STRING_ARCH_strrchr 1
1399 # define strrchr(s, c) \
1400 (__extension__ (__builtin_constant_p (c) \
1401 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1402 : __strrchr_g ((s), (c))))
1404 # ifdef __i686__
1405 __STRING_INLINE char *__strrchr_c (const char *__s, int __c);
1407 __STRING_INLINE char *
1408 __strrchr_c (const char *__s, int __c)
1410 register unsigned long int __d0, __d1;
1411 register char *__res;
1412 __asm__ __volatile__
1413 ("cld\n"
1414 "1:\n\t"
1415 "lodsb\n\t"
1416 "cmpb %h2,%b2\n\t"
1417 "cmove %1,%0\n\t"
1418 "testb %b2,%b2\n\t"
1419 "jne 1b"
1420 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1421 : "0" (1), "1" (__s), "2" (__c),
1422 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1423 : "cc");
1424 return __res - 1;
1427 __STRING_INLINE char *__strrchr_g (const char *__s, int __c);
1429 __STRING_INLINE char *
1430 __strrchr_g (const char *__s, int __c)
1432 register unsigned long int __d0, __d1;
1433 register char *__res;
1434 __asm__ __volatile__
1435 ("movb %b2,%h2\n"
1436 "cld\n\t"
1437 "1:\n\t"
1438 "lodsb\n\t"
1439 "cmpb %h2,%b2\n\t"
1440 "cmove %1,%0\n\t"
1441 "testb %b2,%b2\n\t"
1442 "jne 1b"
1443 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1444 : "0" (1), "1" (__s), "2" (__c),
1445 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1446 : "cc");
1447 return __res - 1;
1449 # else
1450 __STRING_INLINE char *__strrchr_c (const char *__s, int __c);
1452 __STRING_INLINE char *
1453 __strrchr_c (const char *__s, int __c)
1455 register unsigned long int __d0, __d1;
1456 register char *__res;
1457 __asm__ __volatile__
1458 ("cld\n"
1459 "1:\n\t"
1460 "lodsb\n\t"
1461 "cmpb %%ah,%%al\n\t"
1462 "jne 2f\n\t"
1463 "leal -1(%%esi),%0\n"
1464 "2:\n\t"
1465 "testb %%al,%%al\n\t"
1466 "jne 1b"
1467 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1468 : "0" (0), "1" (__s), "2" (__c),
1469 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1470 : "cc");
1471 return __res;
1474 __STRING_INLINE char *__strrchr_g (const char *__s, int __c);
1476 __STRING_INLINE char *
1477 __strrchr_g (const char *__s, int __c)
1479 register unsigned long int __d0, __d1;
1480 register char *__res;
1481 __asm__ __volatile__
1482 ("movb %%al,%%ah\n"
1483 "cld\n\t"
1484 "1:\n\t"
1485 "lodsb\n\t"
1486 "cmpb %%ah,%%al\n\t"
1487 "jne 2f\n\t"
1488 "leal -1(%%esi),%0\n"
1489 "2:\n\t"
1490 "testb %%al,%%al\n\t"
1491 "jne 1b"
1492 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1493 : "0" (0), "1" (__s), "2" (__c),
1494 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1495 : "cc");
1496 return __res;
1498 # endif
1501 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1502 /* Find the last occurrence of C in S. This is the BSD name. */
1503 # define _HAVE_STRING_ARCH_rindex 1
1504 # define rindex(s, c) \
1505 (__extension__ (__builtin_constant_p (c) \
1506 ? __strrchr_c ((s), ((c) & 0xff) << 8) \
1507 : __strrchr_g ((s), (c))))
1508 # endif
1511 /* Return the length of the initial segment of S which
1512 consists entirely of characters not in REJECT. */
1513 # define _HAVE_STRING_ARCH_strcspn 1
1514 # define strcspn(s, reject) \
1515 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1516 ? ((reject)[0] == '\0' \
1517 ? strlen (s) \
1518 : ((reject)[1] == '\0' \
1519 ? __strcspn_c1 ((s), (((reject)[0] << 8) & 0xff00)) \
1520 : __strcspn_cg ((s), (reject), strlen (reject)))) \
1521 : __strcspn_g ((s), (reject))))
1523 __STRING_INLINE size_t __strcspn_c1 (const char *__s, int __reject);
1525 # ifndef _FORCE_INLINES
1526 __STRING_INLINE size_t
1527 __strcspn_c1 (const char *__s, int __reject)
1529 register unsigned long int __d0;
1530 register char *__res;
1531 __asm__ __volatile__
1532 ("1:\n\t"
1533 "movb (%0),%%al\n\t"
1534 "leal 1(%0),%0\n\t"
1535 "cmpb %%ah,%%al\n\t"
1536 "je 2f\n\t"
1537 "testb %%al,%%al\n\t"
1538 "jne 1b\n"
1539 "2:"
1540 : "=r" (__res), "=&a" (__d0)
1541 : "0" (__s), "1" (__reject),
1542 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1543 : "cc");
1544 return (__res - 1) - __s;
1546 # endif
1548 __STRING_INLINE size_t __strcspn_cg (const char *__s, const char __reject[],
1549 size_t __reject_len);
1551 __STRING_INLINE size_t
1552 __strcspn_cg (const char *__s, const char __reject[], size_t __reject_len)
1554 register unsigned long int __d0, __d1, __d2;
1555 register const char *__res;
1556 __asm__ __volatile__
1557 ("cld\n"
1558 "1:\n\t"
1559 "lodsb\n\t"
1560 "testb %%al,%%al\n\t"
1561 "je 2f\n\t"
1562 "movl %5,%%edi\n\t"
1563 "movl %6,%%ecx\n\t"
1564 "repne; scasb\n\t"
1565 "jne 1b\n"
1566 "2:"
1567 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1568 : "0" (__s), "d" (__reject), "g" (__reject_len)
1569 : "memory", "cc");
1570 return (__res - 1) - __s;
1573 __STRING_INLINE size_t __strcspn_g (const char *__s, const char *__reject);
1574 # ifdef __PIC__
1576 __STRING_INLINE size_t
1577 __strcspn_g (const char *__s, const char *__reject)
1579 register unsigned long int __d0, __d1, __d2;
1580 register const char *__res;
1581 __asm__ __volatile__
1582 ("pushl %%ebx\n\t"
1583 "movl %4,%%edi\n\t"
1584 "cld\n\t"
1585 "repne; scasb\n\t"
1586 "notl %%ecx\n\t"
1587 "leal -1(%%ecx),%%ebx\n"
1588 "1:\n\t"
1589 "lodsb\n\t"
1590 "testb %%al,%%al\n\t"
1591 "je 2f\n\t"
1592 "movl %4,%%edi\n\t"
1593 "movl %%ebx,%%ecx\n\t"
1594 "repne; scasb\n\t"
1595 "jne 1b\n"
1596 "2:\n\t"
1597 "popl %%ebx"
1598 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1599 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1600 : "memory", "cc");
1601 return (__res - 1) - __s;
1603 # else
1604 __STRING_INLINE size_t
1605 __strcspn_g (const char *__s, const char *__reject)
1607 register unsigned long int __d0, __d1, __d2, __d3;
1608 register const char *__res;
1609 __asm__ __volatile__
1610 ("cld\n\t"
1611 "repne; scasb\n\t"
1612 "notl %%ecx\n\t"
1613 "leal -1(%%ecx),%%edx\n"
1614 "1:\n\t"
1615 "lodsb\n\t"
1616 "testb %%al,%%al\n\t"
1617 "je 2f\n\t"
1618 "movl %%ebx,%%edi\n\t"
1619 "movl %%edx,%%ecx\n\t"
1620 "repne; scasb\n\t"
1621 "jne 1b\n"
1622 "2:"
1623 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1624 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1625 /* Clobber memory, otherwise GCC cannot handle this. */
1626 : "memory", "cc");
1627 return (__res - 1) - __s;
1629 # endif
1632 /* Return the length of the initial segment of S which
1633 consists entirely of characters in ACCEPT. */
1634 # define _HAVE_STRING_ARCH_strspn 1
1635 # define strspn(s, accept) \
1636 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1637 ? ((accept)[0] == '\0' \
1638 ? ((void) (s), 0) \
1639 : ((accept)[1] == '\0' \
1640 ? __strspn_c1 ((s), (((accept)[0] << 8 ) & 0xff00)) \
1641 : __strspn_cg ((s), (accept), strlen (accept)))) \
1642 : __strspn_g ((s), (accept))))
1644 # ifndef _FORCE_INLINES
1645 __STRING_INLINE size_t __strspn_c1 (const char *__s, int __accept);
1647 __STRING_INLINE size_t
1648 __strspn_c1 (const char *__s, int __accept)
1650 register unsigned long int __d0;
1651 register char *__res;
1652 /* Please note that __accept never can be '\0'. */
1653 __asm__ __volatile__
1654 ("1:\n\t"
1655 "movb (%0),%b1\n\t"
1656 "leal 1(%0),%0\n\t"
1657 "cmpb %h1,%b1\n\t"
1658 "je 1b"
1659 : "=r" (__res), "=&q" (__d0)
1660 : "0" (__s), "1" (__accept),
1661 "m" ( *(struct { char __x[0xfffffff]; } *)__s)
1662 : "cc");
1663 return (__res - 1) - __s;
1665 # endif
1667 __STRING_INLINE size_t __strspn_cg (const char *__s, const char __accept[],
1668 size_t __accept_len);
1670 __STRING_INLINE size_t
1671 __strspn_cg (const char *__s, const char __accept[], size_t __accept_len)
1673 register unsigned long int __d0, __d1, __d2;
1674 register const char *__res;
1675 __asm__ __volatile__
1676 ("cld\n"
1677 "1:\n\t"
1678 "lodsb\n\t"
1679 "testb %%al,%%al\n\t"
1680 "je 2f\n\t"
1681 "movl %5,%%edi\n\t"
1682 "movl %6,%%ecx\n\t"
1683 "repne; scasb\n\t"
1684 "je 1b\n"
1685 "2:"
1686 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1687 : "0" (__s), "g" (__accept), "g" (__accept_len),
1688 /* Since we do not know how large the memory we access it, use a
1689 really large amount. */
1690 "m" ( *(struct { char __x[0xfffffff]; } *)__s),
1691 "m" ( *(struct { __extension__ char __x[__accept_len]; } *)__accept)
1692 : "cc");
1693 return (__res - 1) - __s;
1696 __STRING_INLINE size_t __strspn_g (const char *__s, const char *__accept);
1697 # ifdef __PIC__
1699 __STRING_INLINE size_t
1700 __strspn_g (const char *__s, const char *__accept)
1702 register unsigned long int __d0, __d1, __d2;
1703 register const char *__res;
1704 __asm__ __volatile__
1705 ("pushl %%ebx\n\t"
1706 "cld\n\t"
1707 "repne; scasb\n\t"
1708 "notl %%ecx\n\t"
1709 "leal -1(%%ecx),%%ebx\n"
1710 "1:\n\t"
1711 "lodsb\n\t"
1712 "testb %%al,%%al\n\t"
1713 "je 2f\n\t"
1714 "movl %%edx,%%edi\n\t"
1715 "movl %%ebx,%%ecx\n\t"
1716 "repne; scasb\n\t"
1717 "je 1b\n"
1718 "2:\n\t"
1719 "popl %%ebx"
1720 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1721 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1722 : "memory", "cc");
1723 return (__res - 1) - __s;
1725 # else
1726 __STRING_INLINE size_t
1727 __strspn_g (const char *__s, const char *__accept)
1729 register unsigned long int __d0, __d1, __d2, __d3;
1730 register const char *__res;
1731 __asm__ __volatile__
1732 ("cld\n\t"
1733 "repne; scasb\n\t"
1734 "notl %%ecx\n\t"
1735 "leal -1(%%ecx),%%edx\n"
1736 "1:\n\t"
1737 "lodsb\n\t"
1738 "testb %%al,%%al\n\t"
1739 "je 2f\n\t"
1740 "movl %%ebx,%%edi\n\t"
1741 "movl %%edx,%%ecx\n\t"
1742 "repne; scasb\n\t"
1743 "je 1b\n"
1744 "2:"
1745 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1746 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1747 : "memory", "cc");
1748 return (__res - 1) - __s;
1750 # endif
1753 /* Find the first occurrence in S of any character in ACCEPT. */
1754 # define _HAVE_STRING_ARCH_strpbrk 1
1755 # define strpbrk(s, accept) \
1756 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1757 ? ((accept)[0] == '\0' \
1758 ? ((void) (s), (char *) 0) \
1759 : ((accept)[1] == '\0' \
1760 ? strchr ((s), (accept)[0]) \
1761 : __strpbrk_cg ((s), (accept), strlen (accept)))) \
1762 : __strpbrk_g ((s), (accept))))
1764 __STRING_INLINE char *__strpbrk_cg (const char *__s, const char __accept[],
1765 size_t __accept_len);
1767 __STRING_INLINE char *
1768 __strpbrk_cg (const char *__s, const char __accept[], size_t __accept_len)
1770 register unsigned long int __d0, __d1, __d2;
1771 register char *__res;
1772 __asm__ __volatile__
1773 ("cld\n"
1774 "1:\n\t"
1775 "lodsb\n\t"
1776 "testb %%al,%%al\n\t"
1777 "je 2f\n\t"
1778 "movl %5,%%edi\n\t"
1779 "movl %6,%%ecx\n\t"
1780 "repne; scasb\n\t"
1781 "jne 1b\n\t"
1782 "decl %0\n\t"
1783 "jmp 3f\n"
1784 "2:\n\t"
1785 "xorl %0,%0\n"
1786 "3:"
1787 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1788 : "0" (__s), "d" (__accept), "g" (__accept_len)
1789 : "memory", "cc");
1790 return __res;
1793 __STRING_INLINE char *__strpbrk_g (const char *__s, const char *__accept);
1794 # ifdef __PIC__
1796 __STRING_INLINE char *
1797 __strpbrk_g (const char *__s, const char *__accept)
1799 register unsigned long int __d0, __d1, __d2;
1800 register char *__res;
1801 __asm__ __volatile__
1802 ("pushl %%ebx\n\t"
1803 "movl %%edx,%%edi\n\t"
1804 "cld\n\t"
1805 "repne; scasb\n\t"
1806 "notl %%ecx\n\t"
1807 "leal -1(%%ecx),%%ebx\n"
1808 "1:\n\t"
1809 "lodsb\n\t"
1810 "testb %%al,%%al\n\t"
1811 "je 2f\n\t"
1812 "movl %%edx,%%edi\n\t"
1813 "movl %%ebx,%%ecx\n\t"
1814 "repne; scasb\n\t"
1815 "jne 1b\n\t"
1816 "decl %0\n\t"
1817 "jmp 3f\n"
1818 "2:\n\t"
1819 "xorl %0,%0\n"
1820 "3:\n\t"
1821 "popl %%ebx"
1822 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1823 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1824 : "memory", "cc");
1825 return __res;
1827 # else
1828 __STRING_INLINE char *
1829 __strpbrk_g (const char *__s, const char *__accept)
1831 register unsigned long int __d0, __d1, __d2, __d3;
1832 register char *__res;
1833 __asm__ __volatile__
1834 ("movl %%ebx,%%edi\n\t"
1835 "cld\n\t"
1836 "repne; scasb\n\t"
1837 "notl %%ecx\n\t"
1838 "leal -1(%%ecx),%%edx\n"
1839 "1:\n\t"
1840 "lodsb\n\t"
1841 "testb %%al,%%al\n\t"
1842 "je 2f\n\t"
1843 "movl %%ebx,%%edi\n\t"
1844 "movl %%edx,%%ecx\n\t"
1845 "repne; scasb\n\t"
1846 "jne 1b\n\t"
1847 "decl %0\n\t"
1848 "jmp 3f\n"
1849 "2:\n\t"
1850 "xorl %0,%0\n"
1851 "3:"
1852 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1853 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1854 : "memory", "cc");
1855 return __res;
1857 # endif
1860 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1861 # define _HAVE_STRING_ARCH_strstr 1
1862 # define strstr(haystack, needle) \
1863 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1864 ? ((needle)[0] == '\0' \
1865 ? (haystack) \
1866 : ((needle)[1] == '\0' \
1867 ? strchr ((haystack), (needle)[0]) \
1868 : __strstr_cg ((haystack), (needle), \
1869 strlen (needle)))) \
1870 : __strstr_g ((haystack), (needle))))
1872 /* Please note that this function need not handle NEEDLEs with a
1873 length shorter than two. */
1874 __STRING_INLINE char *__strstr_cg (const char *__haystack,
1875 const char __needle[],
1876 size_t __needle_len);
1878 __STRING_INLINE char *
1879 __strstr_cg (const char *__haystack, const char __needle[],
1880 size_t __needle_len)
1882 register unsigned long int __d0, __d1, __d2;
1883 register char *__res;
1884 __asm__ __volatile__
1885 ("cld\n" \
1886 "1:\n\t"
1887 "movl %6,%%edi\n\t"
1888 "movl %5,%%eax\n\t"
1889 "movl %4,%%ecx\n\t"
1890 "repe; cmpsb\n\t"
1891 "je 2f\n\t"
1892 "cmpb $0,-1(%%esi)\n\t"
1893 "leal 1(%%eax),%5\n\t"
1894 "jne 1b\n\t"
1895 "xorl %%eax,%%eax\n"
1896 "2:"
1897 : "=&a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1898 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1899 : "memory", "cc");
1900 return __res;
1903 __STRING_INLINE char *__strstr_g (const char *__haystack,
1904 const char *__needle);
1905 # ifdef __PIC__
1907 __STRING_INLINE char *
1908 __strstr_g (const char *__haystack, const char *__needle)
1910 register unsigned long int __d0, __d1, __d2;
1911 register char *__res;
1912 __asm__ __volatile__
1913 ("cld\n\t"
1914 "repne; scasb\n\t"
1915 "notl %%ecx\n\t"
1916 "pushl %%ebx\n\t"
1917 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1918 "movl %%ecx,%%ebx\n"
1919 "1:\n\t"
1920 "movl %%edx,%%edi\n\t"
1921 "movl %%esi,%%eax\n\t"
1922 "movl %%ebx,%%ecx\n\t"
1923 "repe; cmpsb\n\t"
1924 "je 2f\n\t" /* also works for empty string, see above */
1925 "cmpb $0,-1(%%esi)\n\t"
1926 "leal 1(%%eax),%%esi\n\t"
1927 "jne 1b\n\t"
1928 "xorl %%eax,%%eax\n"
1929 "2:\n\t"
1930 "popl %%ebx"
1931 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1932 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1933 "d" (__needle)
1934 : "memory", "cc");
1935 return __res;
1937 # else
1938 __STRING_INLINE char *
1939 __strstr_g (const char *__haystack, const char *__needle)
1941 register unsigned long int __d0, __d1, __d2, __d3;
1942 register char *__res;
1943 __asm__ __volatile__
1944 ("cld\n\t"
1945 "repne; scasb\n\t"
1946 "notl %%ecx\n\t"
1947 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1948 "movl %%ecx,%%edx\n"
1949 "1:\n\t"
1950 "movl %%ebx,%%edi\n\t"
1951 "movl %%esi,%%eax\n\t"
1952 "movl %%edx,%%ecx\n\t"
1953 "repe; cmpsb\n\t"
1954 "je 2f\n\t" /* also works for empty string, see above */
1955 "cmpb $0,-1(%%esi)\n\t"
1956 "leal 1(%%eax),%%esi\n\t"
1957 "jne 1b\n\t"
1958 "xorl %%eax,%%eax\n"
1959 "2:"
1960 : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1961 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1962 "b" (__needle)
1963 : "memory", "cc");
1964 return __res;
1966 # endif
1969 /* Bit find functions. We define only the i686 version since for the other
1970 processors gcc generates good code. */
1971 # if defined __USE_MISC || defined __USE_XOPEN_EXTENDED
1972 # ifdef __i686__
1973 # define _HAVE_STRING_ARCH_ffs 1
1974 # define ffs(word) (__builtin_constant_p (word) \
1975 ? __builtin_ffs (word) \
1976 : ({ int __cnt, __tmp; \
1977 __asm__ __volatile__ \
1978 ("bsfl %2,%0\n\t" \
1979 "cmovel %1,%0" \
1980 : "=&r" (__cnt), "=r" (__tmp) \
1981 : "rm" (word), "1" (-1)); \
1982 __cnt + 1; }))
1984 # ifndef ffsl
1985 # define ffsl(word) ffs(word)
1986 # endif
1987 # endif /* i686 */
1988 # endif /* Misc || X/Open */
1990 # ifndef _FORCE_INLINES
1991 # undef __STRING_INLINE
1992 # endif
1994 # endif /* use string inlines && GNU CC */
1996 #endif