Update.
[glibc.git] / sysdeps / i386 / i486 / bits / string.h
blob921c66498e00fad687b9f51aa1d24f2170f1a6af
1 /* Optimized, inlined string functions. i486 version.
2 Copyright (C) 1997, 1998 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
20 #ifndef _STRING_H
21 # error "Never use <bits/string.h> directly; include <string.h> instead."
22 #endif
24 /* The ix86 processors can access unaligned multi-byte variables. */
25 #define _STRING_ARCH_unaligned 1
28 /* We only provide optimizations if the user selects them and if
29 GNU CC is used. */
30 #if !defined __NO_STRING_INLINES && defined __USE_STRING_INLINES \
31 && defined __GNUC__ && __GNUC__ >= 2
33 #ifdef __cplusplus
34 # define __STRING_INLINE inline
35 #else
36 # define __STRING_INLINE extern __inline
37 #endif
39 /* The macros are used in some of the optimized implementations below. */
40 #define __STRING_SMALL_GET16(src, idx) \
41 (((src)[idx + 1] << 8) | (src)[idx])
42 #define __STRING_SMALL_GET32(src, idx) \
43 ((((src)[idx + 3] << 8 | (src)[idx + 2]) << 8 \
44 | (src)[idx + 1]) << 8 | (src)[idx])
47 /* Copy N bytes of SRC to DEST. */
48 #define _HAVE_STRING_ARCH_memcpy 1
49 #define memcpy(dest, src, n) \
50 (__extension__ (__builtin_constant_p (n) \
51 ? __memcpy_c (dest, src, n) \
52 : __memcpy_g (dest, src, n)))
53 #define __memcpy_c(dest, src, n) \
54 ((n) == 0 \
55 ? (dest) \
56 : (((n) % 4 == 0) \
57 ? __memcpy_by4 (dest, src, n) \
58 : (((n) % 2 == 0) \
59 ? __memcpy_by2 (dest, src, n) \
60 : __memcpy_g (dest, src, n))))
62 __STRING_INLINE void *
63 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
65 register unsigned long int __d0, __d1;
66 register void *__tmp = __dest;
67 __asm__ __volatile__
68 ("1:\n\t"
69 "movl (%2),%0\n\t"
70 "leal 4(%2),%2\n\t"
71 "movl %0,(%1)\n\t"
72 "leal 4(%1),%1\n\t"
73 "decl %3\n\t"
74 "jnz 1b"
75 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
76 : "1" (__tmp), "2" (__src), "3" (__n / 4)
77 : "memory", "cc");
78 return __dest;
81 __STRING_INLINE void *
82 __memcpy_by2 (void *__dest, __const void *__src, size_t __n)
84 register unsigned long int __d0, __d1;
85 register void *__tmp = __dest;
86 __asm__ __volatile__
87 ("shrl $1,%3\n\t"
88 "jz 2f\n" /* only a word */
89 "1:\n\t"
90 "movl (%2),%0\n\t"
91 "leal 4(%2),%2\n\t"
92 "movl %0,(%1)\n\t"
93 "leal 4(%1),%1\n\t"
94 "decl %3\n\t"
95 "jnz 1b\n"
96 "2:\n\t"
97 "movw (%2),%w0\n\t"
98 "movw %w0,(%1)"
99 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
100 : "1" (__tmp), "2" (__src), "3" (__n / 2)
101 : "memory", "cc");
102 return __dest;
105 __STRING_INLINE void *
106 __memcpy_g (void *__dest, __const void *__src, size_t __n)
108 register unsigned long int __d0, __d1, __d2;
109 register void *__tmp = __dest;
110 __asm__ __volatile__
111 ("cld\n\t"
112 "shrl $1,%%ecx\n\t"
113 "jnc 1f\n\t"
114 "movsb\n"
115 "1:\n\t"
116 "shrl $1,%%ecx\n\t"
117 "jnc 2f\n\t"
118 "movsw\n"
119 "2:\n\t"
120 "rep; movsl"
121 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
122 : "0" (__n), "1" (__tmp), "2" (__src)
123 : "memory", "cc");
124 return __dest;
128 /* Copy N bytes of SRC to DEST, guaranteeing
129 correct behavior for overlapping strings. */
130 __STRING_INLINE void *
131 memmove (void *__dest, __const void *__src, size_t __n)
133 register unsigned long int __d0, __d1, __d2;
134 register void *__tmp = __dest;
135 if (__dest < __src)
136 __asm__ __volatile__
137 ("cld\n\t"
138 "rep; movsb"
139 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
140 : "0" (__n), "1" (__src), "2" (__tmp)
141 : "memory");
142 else
143 __asm__ __volatile__
144 ("std\n\t"
145 "rep; movsb\n\t"
146 "cld"
147 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
148 : "0" (__n), "1" (__n - 1 + (__const char *) __src),
149 "2" (__n - 1 + (char *) __tmp)
150 : "memory");
151 return __dest;
155 /* Compare N bytes of S1 and S2. */
156 #define _HAVE_STRING_ARCH_memcmp 1
157 #ifndef __PIC__
158 /* gcc has problems to spill registers when using PIC. */
159 __STRING_INLINE int
160 memcmp (__const void *__s1, __const void *__s2, size_t __n)
162 register unsigned long int __d0, __d1, __d2;
163 register int __res;
164 __asm__ __volatile__
165 ("cld\n\t"
166 "repe; cmpsb\n\t"
167 "je 1f\n\t"
168 "sbbl %0,%0\n\t"
169 "orb $1,%b0\n"
170 "1:"
171 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
172 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n)
173 : "cc");
174 return __res;
176 #endif
179 /* Set N bytes of S to C. */
180 #define _HAVE_STRING_ARCH_memset 1
181 #define memset(s, c, n) \
182 (__extension__ (__builtin_constant_p (c) \
183 ? (__builtin_constant_p (n) \
184 ? __memset_cc (s, c, n) \
185 : __memset_cg (s, c, n)) \
186 : (__builtin_constant_p (n) \
187 ? __memset_gc (s, c, n) \
188 : __memset_gg (s, c, n))))
189 #define __memset_cc(s, c, n) \
190 ((n) == 0 \
191 ? (s) \
192 : (((n) % 4 == 0) \
193 ? __memset_cc_by4 (s, c, n) \
194 : (((n) % 2== 0) \
195 ? __memset_cc_by2 (s, c, n) \
196 : __memset_cg (s, c, n))))
197 #define __memset_gc(s, c, n) \
198 ((n) == 0 \
199 ? (s) \
200 : (((n) % 4== 0) \
201 ? __memset_gc_by4 (s, c, n) \
202 : (((n) % 2 == 0) \
203 ? __memset_gc_by2 (s, c, n) \
204 : __memset_gg (s, c, n))))
206 __STRING_INLINE void *
207 __memset_cc_by4 (void *__s, int __c, size_t __n)
209 register unsigned long int __d0;
210 register char *__tmp = __s;
211 __asm__ __volatile__
212 ("1:\n\t"
213 "movl %2,(%0)\n\t"
214 "leal 4(%0),%0\n\t"
215 "decl %1\n\t"
216 "jnz 1b"
217 : "=&r" (__tmp), "=&r" (__d0)
218 : "q" (0x01010101UL * (unsigned char) __c), "0" (__tmp), "1" (__n / 4)
219 : "memory", "cc");
220 return __s;
223 __STRING_INLINE void *
224 __memset_cc_by2 (void *__s, int __c, size_t __n)
226 register unsigned long int __d0;
227 register void *__tmp = __s;
228 __asm__ __volatile__
229 ("shrl $1,%1\n\t" /* may be divisible also by 4 */
230 "jz 2f\n"
231 "1:\n\t"
232 "movl %2,(%0)\n\t"
233 "leal 4(%0),%0\n\t"
234 "decl %1\n\t"
235 "jnz 1b\n"
236 "2:\n\t"
237 "movw %w2,(%0)"
238 : "=&r" (__tmp), "=&r" (__d0)
239 : "q" (0x01010101UL * (unsigned char) __c), "0" (__tmp), "1" (__n / 2)
240 : "memory", "cc");
241 return __s;
244 __STRING_INLINE void *
245 __memset_gc_by4 (void *__s, int __c, size_t __n)
247 register void *__tmp = __s;
248 register unsigned long int __d0;
249 __asm__ __volatile__
250 ("movb %b0,%h0\n"
251 "pushw %w0\n\t"
252 "shll $16,%0\n\t"
253 "popw %w0\n"
254 "1:\n\t"
255 "movl %0,(%1)\n\t"
256 "addl $4,%1\n\t"
257 "decl %2\n\t"
258 "jnz 1b\n"
259 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0)
260 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
261 : "memory", "cc");
262 return __s;
265 __STRING_INLINE void *
266 __memset_gc_by2 (void *__s, int __c, size_t __n)
268 register unsigned long int __d0, __d1;
269 register void *__tmp = __s;
270 __asm__ __volatile__
271 ("movb %b0,%h0\n\t"
272 "shrl $1,%2\n\t" /* may be divisible also by 4 */
273 "jz 2f\n\t"
274 "pushw %w0\n\t"
275 "shll $16,%0\n\t"
276 "popw %w0\n"
277 "1:\n\t"
278 "movl %0,(%1)\n\t"
279 "leal 4(%1),%1\n\t"
280 "decl %2\n\t"
281 "jnz 1b\n"
282 "2:\n\t"
283 "movw %w0,(%1)"
284 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
285 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 2)
286 : "memory", "cc");
287 return __s;
290 __STRING_INLINE void *
291 __memset_cg (void *__s, int __c, size_t __n)
293 register unsigned long __d0, __d1;
294 register void *__tmp = __s;
295 __asm__ __volatile__
296 ("shrl $1,%%ecx\n\t"
297 "rep; stosw\n\t"
298 "jnc 1f\n\t"
299 "movb %%al,(%%edi)\n"
300 "1:"
301 : "=&c" (__d0), "=&D" (__d1)
302 : "0" (__n), "1" (__tmp), "a" (0x0101U * (unsigned char) __c)
303 : "memory", "cc");
304 return __s;
307 __STRING_INLINE void *
308 __memset_gg (void *__s, int __c, size_t __n)
310 register unsigned long int __d0, __d1;
311 register void *__tmp = __s;
312 __asm__ __volatile__
313 ("movb %%al,%%ah\n\t"
314 "shrl $1,%%ecx\n\t"
315 "rep; stosw\n\t"
316 "jnc 1f\n\t"
317 "movb %%al,(%%edi)\n"
318 "1:"
319 : "=&c" (__d0), "=&D" (__d1)
320 : "0" (__n), "1" (__tmp), "a" (__c)
321 : "memory", "cc");
322 return __s;
326 /* Search N bytes of S for C. */
327 #define _HAVE_STRING_ARCH_memchr 1
328 __STRING_INLINE void *
329 memchr (__const void *__s, int __c, size_t __n)
331 register unsigned long int __d0;
332 register void *__res;
333 if (__n == 0)
334 return NULL;
335 #ifdef __i686__
336 __asm__ __volatile__
337 ("movl $1, %%edx\n\t"
338 "cld\n\t"
339 "repne; scasb\n\t"
340 "cmovne %%edx,%0"
341 : "=D" (__res), "=&c" (__d0)
342 : "a" (__c), "0" (__s), "1" (__n)
343 : "dx", "cc");
344 #else
345 __asm__ __volatile__
346 ("cld\n\t"
347 "repne; scasb\n\t"
348 "je 1f\n\t"
349 "movl $1,%0\n"
350 "1:"
351 : "=D" (__res), "=&c" (__d0)
352 : "a" (__c), "0" (__s), "1" (__n)
353 : "cc");
354 #endif
355 return __res - 1;
359 /* Return the length of S. */
360 #define _HAVE_STRING_ARCH_strlen 1
361 #define strlen(str) \
362 (__extension__ (__builtin_constant_p (str) \
363 ? __builtin_strlen (str) \
364 : __strlen_g (str)))
365 __STRING_INLINE size_t
366 __strlen_g (__const char *__str)
368 register char __dummy;
369 register __const char *__tmp = __str;
370 __asm__ __volatile__
371 ("1:\n\t"
372 "movb (%0),%b1\n\t"
373 "leal 1(%0),%0\n\t"
374 "testb %b1,%b1\n\t"
375 "jne 1b"
376 : "=r" (__tmp), "=&q" (__dummy)
377 : "0" (__str)
378 : "memory", "cc" );
379 return __tmp - __str - 1;
383 /* Copy SRC to DEST. */
384 #define _HAVE_STRING_ARCH_strcpy 1
385 #define strcpy(dest, src) \
386 (__extension__ (__builtin_constant_p (src) \
387 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
388 ? __strcpy_small (dest, src, strlen (src) + 1) \
389 : (char *) memcpy ((char *) dest, \
390 (__const char *) src, \
391 strlen (src) + 1)) \
392 : __strcpy_g (dest, src)))
394 #define __strcpy_small(dest, src, srclen) \
395 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
396 switch (srclen) \
398 case 1: \
399 *__dest = '\0'; \
400 break; \
401 case 2: \
402 *((__uint16_t *) __dest) = \
403 __STRING_SMALL_GET16 (src, 0); \
404 break; \
405 case 3: \
406 *((__uint16_t *) __dest) = \
407 __STRING_SMALL_GET16 (src, 0); \
408 *(__dest + 2) = '\0'; \
409 break; \
410 case 4: \
411 *((__uint32_t *) __dest) = \
412 __STRING_SMALL_GET32 (src, 0); \
413 break; \
414 case 5: \
415 *((__uint32_t *) __dest) = \
416 __STRING_SMALL_GET32 (src, 0); \
417 *(__dest + 4) = '\0'; \
418 break; \
419 case 6: \
420 *((__uint32_t *) __dest) = \
421 __STRING_SMALL_GET32 (src, 0); \
422 *((__uint16_t *) (__dest + 4)) = \
423 __STRING_SMALL_GET16 (src, 4); \
424 break; \
425 case 7: \
426 *((__uint32_t *) __dest) = \
427 __STRING_SMALL_GET32 (src, 0); \
428 *((__uint16_t *) (__dest + 4)) = \
429 __STRING_SMALL_GET16 (src, 4); \
430 *(__dest + 6) = '\0'; \
431 break; \
432 case 8: \
433 *((__uint32_t *) __dest) = \
434 __STRING_SMALL_GET32 (src, 0); \
435 *((__uint32_t *) (__dest + 4)) = \
436 __STRING_SMALL_GET32 (src, 4); \
437 break; \
439 (char *) __dest; }))
441 __STRING_INLINE char *
442 __strcpy_g (char *__dest, __const char *__src)
444 register char *__tmp = __dest;
445 register char __dummy;
446 __asm__ __volatile__
448 "1:\n\t"
449 "movb (%0),%b2\n\t"
450 "leal 1(%0),%0\n\t"
451 "movb %b2,(%1)\n\t"
452 "leal 1(%1),%1\n\t"
453 "testb %b2,%b2\n\t"
454 "jne 1b"
455 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
456 : "0" (__src), "1" (__tmp)
457 : "memory", "cc");
458 return __dest;
462 #ifdef __USE_GNU
463 # define _HAVE_STRING_ARCH_stpcpy 1
464 /* Copy SRC to DEST. */
465 # define __stpcpy(dest, src) \
466 (__extension__ (__builtin_constant_p (src) \
467 ? (strlen (src) + 1 <= 8 \
468 ? __stpcpy_small (dest, src, strlen (src) + 1) \
469 : __stpcpy_c (dest, src, strlen (src) + 1)) \
470 : __stpcpy_g (dest, src)))
471 # define __stpcpy_c(dest, src, srclen) \
472 ((srclen) % 4 == 0 \
473 ? __mempcpy_by4 (dest, src, srclen) - 1 \
474 : ((srclen) % 2 == 0 \
475 ? __mempcpy_by2 (dest, src, srclen) - 1 \
476 : __mempcpy_byn (dest, src, srclen) - 1))
478 /* In glibc itself we use this symbol for namespace reasons. */
479 # define stpcpy(dest, src) __stpcpy (dest, src)
481 # define __stpcpy_small(dest, src, srclen) \
482 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
483 switch (srclen) \
485 case 1: \
486 *__dest = '\0'; \
487 break; \
488 case 2: \
489 *((__uint16_t *) __dest) = \
490 __STRING_SMALL_GET16 (src, 0); \
491 ++__dest; \
492 break; \
493 case 3: \
494 *((__uint16_t *) __dest)++ = \
495 __STRING_SMALL_GET16 (src, 0); \
496 *__dest = '\0'; \
497 break; \
498 case 4: \
499 *((__uint32_t *) __dest) = \
500 __STRING_SMALL_GET32 (src, 0); \
501 __dest += 3; \
502 break; \
503 case 5: \
504 *((__uint32_t *) __dest)++ = \
505 __STRING_SMALL_GET32 (src, 0); \
506 *__dest = '\0'; \
507 break; \
508 case 6: \
509 *((__uint32_t *) __dest) = \
510 __STRING_SMALL_GET32 (src, 0); \
511 *((__uint16_t *) (__dest + 4)) = \
512 __STRING_SMALL_GET16 (src, 4); \
513 __dest += 5; \
514 break; \
515 case 7: \
516 *((__uint32_t *) __dest) = \
517 __STRING_SMALL_GET32 (src, 0); \
518 *((__uint16_t *) (__dest + 4)) = \
519 __STRING_SMALL_GET16 (src, 4); \
520 __dest += 6; \
521 *__dest = '\0'; \
522 break; \
523 case 8: \
524 *((__uint32_t *) __dest) = \
525 __STRING_SMALL_GET32 (src, 0); \
526 *((__uint32_t *) (__dest + 4)) = \
527 __STRING_SMALL_GET32 (src, 4); \
528 __dest += 7; \
529 break; \
531 (char *) __dest; }))
533 __STRING_INLINE char *
534 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
536 register char *__tmp = __dest;
537 register unsigned long int __d0, __d1;
538 __asm__ __volatile__
539 ("1:\n\t"
540 "movl (%2),%0\n\t"
541 "leal 4(%2),%2\n\t"
542 "movl %0,(%1)\n\t"
543 "leal 4(%1),%1\n\t"
544 "decl %3\n\t"
545 "jnz 1b"
546 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
547 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
548 : "memory", "cc");
549 return __tmp;
552 __STRING_INLINE char *
553 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
555 register char *__tmp = __dest;
556 register unsigned long int __d0, __d1;
557 __asm__ __volatile__
558 ("shrl $1,%3\n\t"
559 "jz 2f\n" /* only a word */
560 "1:\n\t"
561 "movl (%2),%0\n\t"
562 "leal 4(%2),%2\n\t"
563 "movl %0,(%1)\n\t"
564 "leal 4(%1),%1\n\t"
565 "decl %3\n\t"
566 "jnz 1b\n"
567 "2:\n\t"
568 "movw (%2),%w0\n\t"
569 "movw %w0,(%1)"
570 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
571 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
572 : "memory", "cc");
573 return __tmp + 2;
576 __STRING_INLINE char *
577 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
579 register unsigned long __d0, __d1;
580 register char *__tmp = __dest;
581 __asm__ __volatile__
582 ("cld\n\t"
583 "shrl $1,%%ecx\n\t"
584 "jnc 1f\n\t"
585 "movsb\n"
586 "1:\n\t"
587 "shrl $1,%%ecx\n\t"
588 "jnc 2f\n\t"
589 "movsw\n"
590 "2:\n\t"
591 "rep; movsl"
592 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
593 : "0" (__tmp), "1" (__srclen), "2" (__src)
594 : "memory", "cc");
595 return __tmp;
598 __STRING_INLINE char *
599 __stpcpy_g (char *__dest, __const char *__src)
601 register char *__tmp = __dest;
602 register char __dummy;
603 __asm__ __volatile__
605 "1:\n\t"
606 "movb (%0),%b2\n\t"
607 "leal 1(%0),%0\n\t"
608 "movb %b2,(%1)\n\t"
609 "leal 1(%1),%1\n\t"
610 "testb %b2,%b2\n\t"
611 "jne 1b"
612 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
613 : "0" (__src), "1" (__tmp)
614 : "memory", "cc");
615 return __tmp - 1;
617 #endif
620 /* Copy no more than N characters of SRC to DEST. */
621 #define _HAVE_STRING_ARCH_strncpy 1
622 #define strncpy(dest, src, n) \
623 (__extension__ (__builtin_constant_p (src) \
624 ? ((strlen (src) + 1 >= ((size_t) (n)) \
625 ? (char *) memcpy ((char *) dest, \
626 (__const char *) src, n) \
627 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
628 : __strncpy_gg (dest, src, n)))
629 #define __strncpy_cg(dest, src, srclen, n) \
630 (((srclen) % 4 == 0) \
631 ? __strncpy_by4 (dest, src, srclen, n) \
632 : (((srclen) % 2 == 0) \
633 ? __strncpy_by2 (dest, src, srclen, n) \
634 : __strncpy_byn (dest, src, srclen, n)))
636 __STRING_INLINE char *
637 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
639 register char *__tmp = __dest;
640 register int __dummy1, __dummy2;
641 __asm__ __volatile__
642 ("1:\n\t"
643 "movl (%2),%0\n\t"
644 "leal 4(%2),%2\n\t"
645 "movl %0,(%1)\n\t"
646 "leal 4(%1),%1\n\t"
647 "decl %3\n\t"
648 "jnz 1b"
649 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
650 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
651 : "memory", "cc");
652 (void) memset (__tmp, '\0', __n - __srclen);
653 return __dest;
656 __STRING_INLINE char *
657 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
659 register char *__tmp = __dest;
660 register int __dummy1, __dummy2;
661 __asm__ __volatile__
662 ("shrl $1,%3\n\t"
663 "jz 2f\n" /* only a word */
664 "1:\n\t"
665 "movl (%2),%0\n\t"
666 "leal 4(%2),%2\n\t"
667 "movl %0,(%1)\n\t"
668 "leal 4(%1),%1\n\t"
669 "decl %3\n\t"
670 "jnz 1b\n"
671 "2:\n\t"
672 "movw (%2),%w0\n\t"
673 "movw %w0,(%1)\n\t"
674 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
675 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
676 : "memory", "cc");
677 (void) memset (__tmp + 2, '\0', __n - __srclen);
678 return __dest;
681 __STRING_INLINE char *
682 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
684 register unsigned long int __d0, __d1;
685 register char *__tmp = __dest;
686 __asm__ __volatile__
687 ("cld\n\t"
688 "shrl $1,%1\n\t"
689 "jnc 1f\n\t"
690 "movsb\n"
691 "1:\n\t"
692 "shrl $1,%1\n\t"
693 "jnc 2f\n\t"
694 "movsw\n"
695 "2:\n\t"
696 "rep; movsl"
697 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
698 : "1" (__srclen), "0" (__tmp),"2" (__src)
699 : "memory", "cc");
700 (void) memset (__tmp, '\0', __n - __srclen);
701 return __dest;
704 __STRING_INLINE char *
705 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
707 register char *__tmp = __dest;
708 register char __dummy;
709 if (__n > 0)
710 __asm__ __volatile__
711 ("1:\n\t"
712 "movb (%0),%2\n\t"
713 "incl %0\n\t"
714 "movb %2,(%1)\n\t"
715 "incl %1\n\t"
716 "decl %3\n\t"
717 "je 3f\n\t"
718 "testb %2,%2\n\t"
719 "jne 1b\n\t"
720 "2:\n\t"
721 "movb %2,(%1)\n\t"
722 "incl %1\n\t"
723 "decl %3\n\t"
724 "jne 2b\n\t"
725 "3:"
726 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
727 : "0" (__src), "1" (__tmp), "3" (__n)
728 : "memory", "cc");
730 return __dest;
734 /* Append SRC onto DEST. */
735 #define _HAVE_STRING_ARCH_strcat 1
736 #define strcat(dest, src) \
737 (__extension__ (__builtin_constant_p (src) \
738 ? __strcat_c (dest, src, strlen (src) + 1) \
739 : __strcat_g (dest, src)))
741 __STRING_INLINE char *
742 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
744 #ifdef __i686__
745 register unsigned long int __d0;
746 register char *__tmp;
747 __asm__ __volatile__
748 ("repne; scasb"
749 : "=D" (__tmp), "=&c" (__d0)
750 : "0" (__dest), "1" (0xffffffff), "a" (0)
751 : "cc");
752 --__tmp;
753 #else
754 register char *__tmp = __dest - 1;
755 __asm__ __volatile__
756 ("1:\n\t"
757 "incl %0\n\t"
758 "cmpb $0,(%0)\n\t"
759 "jne 1b\n"
760 : "=r" (__tmp)
761 : "0" (__tmp)
762 : "cc");
763 #endif
764 (void) memcpy (__tmp, __src, __srclen);
765 return __dest;
768 __STRING_INLINE char *
769 __strcat_g (char *__dest, __const char *__src)
771 register char *__tmp = __dest - 1;
772 register char __dummy;
773 __asm__ __volatile__
774 ("1:\n\t"
775 "incl %1\n\t"
776 "cmpb $0,(%1)\n\t"
777 "jne 1b\n"
778 "2:\n\t"
779 "movb (%2),%b0\n\t"
780 "incl %2\n\t"
781 "movb %b0,(%1)\n\t"
782 "incl %1\n\t"
783 "testb %b0,%b0\n\t"
784 "jne 2b\n"
785 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
786 : "1" (__tmp), "2" (__src)
787 : "memory", "cc");
788 return __dest;
792 /* Append no more than N characters from SRC onto DEST. */
793 #define _HAVE_STRING_ARCH_strncat 1
794 #define strncat(dest, src, n) \
795 (__extension__ ({ char *__dest = (dest); \
796 __builtin_constant_p (src) && __builtin_constant_p (n) \
797 ? (strlen (src) < ((size_t) (n)) \
798 ? strcat (__dest, src) \
799 : (memcpy (strchr (__dest, '\0'), \
800 (__const char *) src, n), __dest)) \
801 : __strncat_g (__dest, src, n); }))
803 __STRING_INLINE char *
804 __strncat_g (char *__dest, __const char __src[], size_t __n)
806 register char *__tmp = __dest;
807 register char __dummy;
808 #ifdef __i686__
809 __asm__ __volatile__
810 ("repne; scasb\n"
811 "decl %1\n\t"
812 "1:\n\t"
813 "decl %3\n\t"
814 "js 2f\n\t"
815 "movb (%2),%b0\n\t"
816 "movsb\n\t"
817 "testb %b0,%b0\n\t"
818 "jne 1b\n\t"
819 "decl %1\n"
820 "2:\n\t"
821 "movb $0,(%1)"
822 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
823 : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
824 : "memory", "cc");
825 #else
826 --__tmp;
827 __asm__ __volatile__
828 ("1:\n\t"
829 "cmpb $0,1(%1)\n\t"
830 "leal 1(%1),%1\n\t"
831 "jne 1b\n"
832 "2:\n\t"
833 "decl %3\n\t"
834 "js 3f\n\t"
835 "movb (%2),%b0\n\t"
836 "leal 1(%2),%2\n\t"
837 "movb %b0,(%1)\n\t"
838 "leal 1(%1),%1\n\t"
839 "testb %b0,%b0\n\t"
840 "jne 2b\n\t"
841 "decl %1\n"
842 "3:\n\t"
843 "movb $0,(%1)"
844 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
845 : "1" (__tmp), "2" (__src), "3" (__n)
846 : "memory", "cc");
847 #endif
848 return __dest;
852 /* Compare S1 and S2. */
853 #define _HAVE_STRING_ARCH_strcmp 1
854 #define strcmp(s1, s2) \
855 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
856 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
857 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
858 ? memcmp ((__const char *) s1, (__const char *) s2, \
859 (strlen (s1) < strlen (s2) \
860 ? strlen (s1) : strlen (s2)) + 1) \
861 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
862 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
863 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
864 ? __strcmp_cc (s1, s2, strlen (s1)) \
865 : __strcmp_cg (s1, s2, strlen (s1))) \
866 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
867 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
868 ? (__builtin_constant_p (s1) \
869 ? __strcmp_cc (s1, s2, strlen (s2)) \
870 : __strcmp_gc (s1, s2, strlen (s2))) \
871 : __strcmp_gg (s1, s2)))))
873 #define __strcmp_cc(s1, s2, l) \
874 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
875 - (unsigned char) (s2)[0]); \
876 if (l > 0 && __result == 0) \
878 __result = ((unsigned char) (s1)[1] \
879 - (unsigned char) (s2)[1]); \
880 if (l > 1 && __result == 0) \
882 __result = ((unsigned char) (s1)[2] \
883 - (unsigned char) (s2)[2]); \
884 if (l > 2 && __result == 0) \
885 __result = ((unsigned char) (s1)[3] \
886 - (unsigned char) (s2)[3]); \
889 __result; }))
891 #define __strcmp_cg(s1, s2, l1) \
892 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
893 register int __result = (unsigned char) (s1)[0] - __s2[0];\
894 if (l1 > 0 && __result == 0) \
896 __result = (unsigned char) (s1)[1] - __s2[1]; \
897 if (l1 > 1 && __result == 0) \
899 __result = (unsigned char) (s1)[2] - __s2[2]; \
900 if (l1 > 2 && __result == 0) \
901 __result = (unsigned char) (s1)[3] - __s2[3]; \
904 __result; }))
906 #define __strcmp_gc(s1, s2, l2) \
907 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
908 register int __result = __s1[0] - (unsigned char) (s2)[0];\
909 if (l2 > 0 && __result == 0) \
911 __result = __s1[1] - (unsigned char) (s2)[1]; \
912 if (l2 > 1 && __result == 0) \
914 __result = __s1[2] - (unsigned char) (s2)[2]; \
915 if (l2 > 2 && __result == 0) \
916 __result = __s1[3] - (unsigned char) (s2)[3]; \
919 __result; }))
921 __STRING_INLINE int
922 __strcmp_gg (__const char *__s1, __const char *__s2)
924 register int __res;
925 __asm__ __volatile__
926 ("1:\n\t"
927 "movb (%1),%b0\n\t"
928 "leal 1(%1),%1\n\t"
929 "cmpb %b0,(%2)\n\t"
930 "jne 2f\n\t"
931 "leal 1(%2),%2\n\t"
932 "testb %b0,%b0\n\t"
933 "jne 1b\n\t"
934 "xorl %0,%0\n\t"
935 "jmp 3f\n"
936 "2:\n\t"
937 "movl $1,%0\n\t"
938 "jb 3f\n\t"
939 "negl %0\n"
940 "3:"
941 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
942 : "1" (__s1), "2" (__s2)
943 : "cc");
944 return __res;
948 /* Compare N characters of S1 and S2. */
949 #define _HAVE_STRING_ARCH_strncmp 1
950 #define strncmp(s1, s2, n) \
951 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
952 ? strcmp (s1, s2) \
953 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
954 ? strcmp (s1, s2) \
955 : __strncmp_g (s1, s2, n))))
957 __STRING_INLINE int
958 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
960 register int __res;
961 __asm__ __volatile__
962 ("1:\n\t"
963 "decl %3\n\t"
964 "js 2f\n\t"
965 "movb (%1),%b0\n\t"
966 "incl %1\n\t"
967 "cmpb %b0,(%2)\n\t"
968 "jne 3f\n\t"
969 "incl %2\n\t"
970 "testb %b0,%b0\n\t"
971 "jne 1b\n"
972 "2:\n\t"
973 "xorl %0,%0\n\t"
974 "jmp 4f\n"
975 "3:\n\t"
976 "movl $1,%0\n\t"
977 "jb 4f\n\t"
978 "negl %0\n"
979 "4:"
980 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
981 : "1" (__s1), "2" (__s2), "3" (__n)
982 : "cc");
983 return __res;
987 /* Find the first occurrence of C in S. */
988 #define _HAVE_STRING_ARCH_strchr 1
989 #define strchr(s, c) \
990 (__extension__ (__builtin_constant_p (c) \
991 ? __strchr_c (s, ((c) & 0xff) << 8) \
992 : __strchr_g (s, c)))
994 __STRING_INLINE char *
995 __strchr_c (__const char *__s, int __c)
997 register unsigned long int __d0;
998 register char *__res;
999 __asm__ __volatile__
1000 ("1:\n\t"
1001 "movb (%0),%%al\n\t"
1002 "cmpb %%ah,%%al\n\t"
1003 "je 2f\n\t"
1004 "leal 1(%0),%0\n\t"
1005 "testb %%al,%%al\n\t"
1006 "jne 1b\n\t"
1007 "xorl %0,%0\n"
1008 "2:"
1009 : "=r" (__res), "=&a" (__d0)
1010 : "0" (__s), "1" (__c)
1011 : "cc");
1012 return __res;
1015 __STRING_INLINE char *
1016 __strchr_g (__const char *__s, int __c)
1018 register unsigned long int __d0;
1019 register char *__res;
1020 __asm__ __volatile__
1021 ("movb %%al,%%ah\n"
1022 "1:\n\t"
1023 "movb (%0),%%al\n\t"
1024 "cmpb %%ah,%%al\n\t"
1025 "je 2f\n\t"
1026 "leal 1(%0),%0\n\t"
1027 "testb %%al,%%al\n\t"
1028 "jne 1b\n\t"
1029 "xorl %0,%0\n"
1030 "2:"
1031 : "=r" (__res), "=&a" (__d0)
1032 : "0" (__s), "1" (__c)
1033 : "cc");
1034 return __res;
1038 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1039 /* Find the first occurrence of C in S. This is the BSD name. */
1040 # define _HAVE_STRING_ARCH_index 1
1041 # define index(s, c) \
1042 (__extension__ (__builtin_constant_p (c) \
1043 ? __strchr_c (s, ((c) & 0xff) << 8) \
1044 : __strchr_g (s, c)))
1045 #endif
1048 /* Find the last occurrence of C in S. */
1049 #define _HAVE_STRING_ARCH_strrchr 1
1050 #define strrchr(s, c) \
1051 (__extension__ (__builtin_constant_p (c) \
1052 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1053 : __strrchr_g (s, c)))
1055 #ifdef __i686__
1056 __STRING_INLINE char *
1057 __strrchr_c (__const char *__s, int __c)
1059 register unsigned long int __d0, __d1;
1060 register char *__res;
1061 __asm__ __volatile__
1062 ("cld\n"
1063 "1:\n\t"
1064 "lodsb\n\t"
1065 "cmpb %h2,%b2\n\t"
1066 "cmove %1,%0\n\t"
1067 "testb %b2,%b2\n\t"
1068 "jne 1b"
1069 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1070 : "0" (1), "1" (__s), "2" (__c)
1071 : "cc");
1072 return __res - 1;
1075 __STRING_INLINE char *
1076 __strrchr_g (__const char *__s, int __c)
1078 register unsigned long int __d0, __d1;
1079 register char *__res;
1080 __asm__ __volatile__
1081 ("movb %b2,%h2\n"
1082 "cld\n\t"
1083 "1:\n\t"
1084 "lodsb\n\t"
1085 "cmpb %h2,%b2\n\t"
1086 "cmove %1,%0\n\t"
1087 "testb %b2,%b2\n\t"
1088 "jne 1b"
1089 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1090 : "0" (1), "1" (__s), "2" (__c)
1091 : "cc");
1092 return __res - 1;
1094 #else
1095 __STRING_INLINE char *
1096 __strrchr_c (__const char *__s, int __c)
1098 register unsigned long int __d0, __d1;
1099 register char *__res;
1100 __asm__ __volatile__
1101 ("cld\n"
1102 "1:\n\t"
1103 "lodsb\n\t"
1104 "cmpb %%ah,%%al\n\t"
1105 "jne 2f\n\t"
1106 "leal -1(%%esi),%0\n"
1107 "2:\n\t"
1108 "testb %%al,%%al\n\t"
1109 "jne 1b"
1110 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1111 : "0" (0), "1" (__s), "2" (__c)
1112 : "cc");
1113 return __res;
1116 __STRING_INLINE char *
1117 __strrchr_g (__const char *__s, int __c)
1119 register unsigned long int __d0, __d1;
1120 register char *__res;
1121 __asm__ __volatile__
1122 ("movb %%al,%%ah\n"
1123 "cld\n\t"
1124 "1:\n\t"
1125 "lodsb\n\t"
1126 "cmpb %%ah,%%al\n\t"
1127 "jne 2f\n\t"
1128 "leal -1(%%esi),%0\n"
1129 "2:\n\t"
1130 "testb %%al,%%al\n\t"
1131 "jne 1b"
1132 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1133 : "0" (0), "1" (__s), "2" (__c)
1134 : "cc");
1135 return __res;
1137 #endif
1140 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1141 /* Find the last occurrence of C in S. This is the BSD name. */
1142 # define _HAVE_STRING_ARCH_rindex 1
1143 # define rindex(s, c) \
1144 (__extension__ (__builtin_constant_p (c) \
1145 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1146 : __strrchr_g (s, c)))
1147 #endif
1150 /* Return the length of the initial segment of S which
1151 consists entirely of characters not in REJECT. */
1152 #define _HAVE_STRING_ARCH_strcspn 1
1153 #define strcspn(s, reject) \
1154 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1155 ? ((reject)[0] == '\0' \
1156 ? strlen (s) \
1157 : ((reject)[1] == '\0' \
1158 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1159 : __strcspn_cg (s, reject, strlen (reject)))) \
1160 : __strcspn_g (s, reject)))
1162 __STRING_INLINE size_t
1163 __strcspn_c1 (__const char *__s, int __reject)
1165 register unsigned long int __d0;
1166 register char *__res;
1167 __asm__ __volatile__
1168 ("1:\n\t"
1169 "movb (%0),%%al\n\t"
1170 "leal 1(%0),%0\n\t"
1171 "cmpb %%ah,%%al\n\t"
1172 "je 2f\n\t"
1173 "testb %%al,%%al\n\t"
1174 "jne 1b\n"
1175 "2:"
1176 : "=r" (__res), "=&a" (__d0)
1177 : "0" (__s), "1" (__reject)
1178 : "cc");
1179 return (__res - 1) - __s;
1182 __STRING_INLINE size_t
1183 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1185 register unsigned long int __d0, __d1, __d2;
1186 register __const char *__res;
1187 __asm__ __volatile__
1188 ("cld\n"
1189 "1:\n\t"
1190 "lodsb\n\t"
1191 "testb %%al,%%al\n\t"
1192 "je 2f\n\t"
1193 "movl %5,%%edi\n\t"
1194 "movl %6,%%ecx\n\t"
1195 "repne; scasb\n\t"
1196 "jne 1b\n"
1197 "2:"
1198 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1199 : "0" (__s), "d" (__reject), "g" (__reject_len)
1200 : "cc");
1201 return (__res - 1) - __s;
1204 #ifdef __PIC__
1205 __STRING_INLINE size_t
1206 __strcspn_g (__const char *__s, __const char *__reject)
1208 register unsigned long int __d0, __d1, __d2;
1209 register __const char *__res;
1210 __asm__ __volatile__
1211 ("pushl %%ebx\n\t"
1212 "movl %4,%%edi\n\t"
1213 "cld\n\t"
1214 "repne; scasb\n\t"
1215 "notl %%ecx\n\t"
1216 "leal -1(%%ecx),%%ebx\n"
1217 "1:\n\t"
1218 "lodsb\n\t"
1219 "testb %%al,%%al\n\t"
1220 "je 2f\n\t"
1221 "movl %4,%%edi\n\t"
1222 "movl %%ebx,%%ecx\n\t"
1223 "repne; scasb\n\t"
1224 "jne 1b\n"
1225 "2:\n\t"
1226 "popl %%ebx"
1227 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1228 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1229 : "cc");
1230 return (__res - 1) - __s;
1232 #else
1233 __STRING_INLINE size_t
1234 __strcspn_g (__const char *__s, __const char *__reject)
1236 register unsigned long int __d0, __d1, __d2, __d3;
1237 register __const char *__res;
1238 __asm__ __volatile__
1239 ("cld\n\t"
1240 "repne; scasb\n\t"
1241 "notl %%ecx\n\t"
1242 "leal -1(%%ecx),%%edx\n"
1243 "1:\n\t"
1244 "lodsb\n\t"
1245 "testb %%al,%%al\n\t"
1246 "je 2f\n\t"
1247 "movl %%ebx,%%edi\n\t"
1248 "movl %%edx,%%ecx\n\t"
1249 "repne; scasb\n\t"
1250 "jne 1b\n"
1251 "2:"
1252 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1253 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1254 : "cc");
1255 return (__res - 1) - __s;
1257 #endif
1260 /* Return the length of the initial segment of S which
1261 consists entirely of characters in ACCEPT. */
1262 #define _HAVE_STRING_ARCH_strspn 1
1263 #define strspn(s, accept) \
1264 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1265 ? ((accept)[0] == '\0' \
1266 ? 0 \
1267 : ((accept)[1] == '\0' \
1268 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1269 : __strspn_cg (s, accept, strlen (accept)))) \
1270 : __strspn_g (s, accept)))
1272 __STRING_INLINE size_t
1273 __strspn_c1 (__const char *__s, int __accept)
1275 register unsigned long int __d0;
1276 register char *__res;
1277 /* Please note that __accept never can be '\0'. */
1278 __asm__ __volatile__
1279 ("1:\n\t"
1280 "movb (%0),%b1\n\t"
1281 "leal 1(%0),%0\n\t"
1282 "cmpb %h1,%b1\n\t"
1283 "je 1b"
1284 : "=r" (__res), "=&q" (__d0)
1285 : "0" (__s), "1" (__accept)
1286 : "cc");
1287 return (__res - 1) - __s;
1290 __STRING_INLINE size_t
1291 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1293 register unsigned long int __d0, __d1, __d2;
1294 register __const char *__res;
1295 __asm__ __volatile__
1296 ("cld\n"
1297 "1:\n\t"
1298 "lodsb\n\t"
1299 "testb %%al,%%al\n\t"
1300 "je 2f\n\t"
1301 "movl %1,%%edi\n\t"
1302 "movl %6,%%ecx\n\t"
1303 "repne; scasb\n\t"
1304 "je 1b\n"
1305 "2:"
1306 : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1307 : "0" (__s), "1" (__accept), "g" (__accept_len)
1308 : "cc");
1309 return (__res - 1) - __s;
1312 #ifdef __PIC__
1313 __STRING_INLINE size_t
1314 __strspn_g (__const char *__s, __const char *__accept)
1316 register unsigned long int __d0, __d1, __d2;
1317 register __const char *__res;
1318 __asm__ __volatile__
1319 ("pushl %%ebx\n\t"
1320 "cld\n\t"
1321 "repne; scasb\n\t"
1322 "notl %%ecx\n\t"
1323 "leal -1(%%ecx),%%ebx\n"
1324 "1:\n\t"
1325 "lodsb\n\t"
1326 "testb %%al,%%al\n\t"
1327 "je 2f\n\t"
1328 "movl %%edx,%%edi\n\t"
1329 "movl %%ebx,%%ecx\n\t"
1330 "repne; scasb\n\t"
1331 "je 1b\n"
1332 "2:\n\t"
1333 "popl %%ebx"
1334 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1335 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1336 : "cc");
1337 return (__res - 1) - __s;
1339 #else
1340 __STRING_INLINE size_t
1341 __strspn_g (__const char *__s, __const char *__accept)
1343 register unsigned long int __d0, __d1, __d2, __d3;
1344 register __const char *__res;
1345 __asm__ __volatile__
1346 ("cld\n\t"
1347 "repne; scasb\n\t"
1348 "notl %%ecx\n\t"
1349 "leal -1(%%ecx),%%edx\n"
1350 "1:\n\t"
1351 "lodsb\n\t"
1352 "testb %%al,%%al\n\t"
1353 "je 2f\n\t"
1354 "movl %%ebx,%%edi\n\t"
1355 "movl %%edx,%%ecx\n\t"
1356 "repne; scasb\n\t"
1357 "je 1b\n"
1358 "2:"
1359 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1360 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1361 : "cc");
1362 return (__res - 1) - __s;
1364 #endif
1367 /* Find the first occurrence in S of any character in ACCEPT. */
1368 #define _HAVE_STRING_ARCH_strpbrk 1
1369 #define strpbrk(s, accept) \
1370 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1371 ? ((accept)[0] == '\0' \
1372 ? NULL \
1373 : ((accept)[1] == '\0' \
1374 ? strchr (s, (accept)[0]) \
1375 : __strpbrk_cg (s, accept, strlen (accept)))) \
1376 : __strpbrk_g (s, accept)))
1378 __STRING_INLINE char *
1379 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1381 register unsigned long int __d0, __d1, __d2;
1382 register char *__res;
1383 __asm__ __volatile__
1384 ("cld\n"
1385 "1:\n\t"
1386 "lodsb\n\t"
1387 "testb %%al,%%al\n\t"
1388 "je 2f\n\t"
1389 "movl %5,%%edi\n\t"
1390 "movl %6,%%ecx\n\t"
1391 "repne; scasb\n\t"
1392 "jne 1b\n\t"
1393 "decl %0\n\t"
1394 "jmp 3f\n"
1395 "2:\n\t"
1396 "xorl %0,%0\n"
1397 "3:"
1398 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1399 : "0" (__s), "d" (__accept), "g" (__accept_len)
1400 : "cc");
1401 return __res;
1404 #ifdef __PIC__
1405 __STRING_INLINE char *
1406 __strpbrk_g (__const char *__s, __const char *__accept)
1408 register unsigned long int __d0, __d1, __d2;
1409 register char *__res;
1410 __asm__ __volatile__
1411 ("pushl %%ebx\n\t"
1412 "movl %%edx,%%edi\n\t"
1413 "cld\n\t"
1414 "repne; scasb\n\t"
1415 "notl %%ecx\n\t"
1416 "leal -1(%%ecx),%%ebx\n"
1417 "1:\n\t"
1418 "lodsb\n\t"
1419 "testb %%al,%%al\n\t"
1420 "je 2f\n\t"
1421 "movl %%edx,%%edi\n\t"
1422 "movl %%ebx,%%ecx\n\t"
1423 "repne; scasb\n\t"
1424 "jne 1b\n\t"
1425 "decl %0\n\t"
1426 "jmp 3f\n"
1427 "2:\n\t"
1428 "xorl %0,%0\n"
1429 "3:\n\t"
1430 "popl %%ebx"
1431 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1432 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1433 : "cc");
1434 return __res;
1436 #else
1437 __STRING_INLINE char *
1438 __strpbrk_g (__const char *__s, __const char *__accept)
1440 register unsigned long int __d0, __d1, __d2, __d3;
1441 register char *__res;
1442 __asm__ __volatile__
1443 ("movl %%ebx,%%edi\n\t"
1444 "cld\n\t"
1445 "repne; scasb\n\t"
1446 "notl %%ecx\n\t"
1447 "leal -1(%%ecx),%%edx\n"
1448 "1:\n\t"
1449 "lodsb\n\t"
1450 "testb %%al,%%al\n\t"
1451 "je 2f\n\t"
1452 "movl %%ebx,%%edi\n\t"
1453 "movl %%edx,%%ecx\n\t"
1454 "repne; scasb\n\t"
1455 "jne 1b\n\t"
1456 "decl %0\n\t"
1457 "jmp 3f\n"
1458 "2:\n\t"
1459 "xorl %0,%0\n"
1460 "3:"
1461 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1462 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1463 : "cc");
1464 return __res;
1466 #endif
1469 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1470 #define _HAVE_STRING_ARCH_strstr 1
1471 #define strstr(haystack, needle) \
1472 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1473 ? ((needle)[0] == '\0' \
1474 ? haystack \
1475 : ((needle)[1] == '\0' \
1476 ? strchr (haystack, (needle)[0]) \
1477 : __strstr_cg (haystack, needle, strlen (needle)))) \
1478 : __strstr_g (haystack, needle)))
1480 /* Please note that this function need not handle NEEDLEs with a
1481 length shorter than two. */
1482 __STRING_INLINE char *
1483 __strstr_cg (__const char *__haystack, __const char __needle[],
1484 size_t __needle_len)
1486 register unsigned long int __d0, __d1, __d2;
1487 register char *__res;
1488 __asm__ __volatile__
1489 ("cld\n" \
1490 "1:\n\t"
1491 "movl %6,%%edi\n\t"
1492 "movl %5,%%eax\n\t"
1493 "movl %4,%%ecx\n\t"
1494 "repe; cmpsb\n\t"
1495 "je 2f\n\t"
1496 "cmpb $0,-1(%%esi)\n\t"
1497 "leal 1(%%eax),%5\n\t"
1498 "jne 1b\n\t"
1499 "xorl %%eax,%%eax\n"
1500 "2:"
1501 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1502 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1503 : "cc");
1504 return __res;
1507 #ifdef __PIC__
1508 __STRING_INLINE char *
1509 __strstr_g (__const char *__haystack, __const char *__needle)
1511 register unsigned long int __d0, __d1, __d2;
1512 register char *__res;
1513 __asm__ __volatile__
1514 ("cld\n\t"
1515 "repne; scasb\n\t"
1516 "notl %%ecx\n\t"
1517 "pushl %%ebx\n\t"
1518 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1519 "movl %%ecx,%%ebx\n"
1520 "1:\n\t"
1521 "movl %%edx,%%edi\n\t"
1522 "movl %%esi,%%eax\n\t"
1523 "movl %%ebx,%%ecx\n\t"
1524 "repe; cmpsb\n\t"
1525 "je 2f\n\t" /* also works for empty string, see above */
1526 "cmpb $0,-1(%%esi)\n\t"
1527 "leal 1(%%eax),%%esi\n\t"
1528 "jne 1b\n\t"
1529 "xorl %%eax,%%eax\n"
1530 "2:\n\t"
1531 "popl %%ebx"
1532 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1533 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1534 "d" (__needle)
1535 : "cc");
1536 return __res;
1538 #else
1539 __STRING_INLINE char *
1540 __strstr_g (__const char *__haystack, __const char *__needle)
1542 register unsigned long int __d0, __d1, __d2, __d3;
1543 register char *__res;
1544 __asm__ __volatile__
1545 ("cld\n\t"
1546 "repne; scasb\n\t"
1547 "notl %%ecx\n\t"
1548 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1549 "movl %%ecx,%%edx\n"
1550 "1:\n\t"
1551 "movl %%ebx,%%edi\n\t"
1552 "movl %%esi,%%eax\n\t"
1553 "movl %%edx,%%ecx\n\t"
1554 "repe; cmpsb\n\t"
1555 "je 2f\n\t" /* also works for empty string, see above */
1556 "cmpb $0,-1(%%esi)\n\t"
1557 "leal 1(%%eax),%%esi\n\t"
1558 "jne 1b\n\t"
1559 "xorl %%eax,%%eax\n"
1560 "2:"
1561 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1562 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1563 "b" (__needle)
1564 : "cc");
1565 return __res;
1567 #endif
1570 /* Bit find functions. We define only the i686 version since for the other
1571 processors gcc generates good code. */
1572 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1573 # ifdef __i686__
1574 # define _HAVE_STRING_ARCH_ffs 1
1575 # define ffs(word) (__builtin_constant_p (word) \
1576 ? __builtin_ffs (word) \
1577 : ({ int __cnt, __tmp; \
1578 __asm__ __volatile__ \
1579 ("bsfl %2,%0\n\t" \
1580 "cmovel %1,%0" \
1581 : "=&r" (__cnt), "=r" (__tmp) \
1582 : "rm" (word), "1" (-1)); \
1583 __cnt + 1; }))
1585 # define ffsl(word) ffs(word)
1586 # endif /* i686 */
1587 #endif /* BSD || X/Open */
1589 #undef __STRING_INLINE
1591 #endif /* use string inlines && GNU CC */