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