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