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