Update.
[glibc.git] / sysdeps / i386 / i486 / bits / string.h
blob5fe206224c5e6db635f87fc1f8fc7218771ece93
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 *__memcpy_by4 (void *__dest, __const void *__src,
63 size_t __n);
65 __STRING_INLINE void *
66 __memcpy_by4 (void *__dest, __const void *__src, size_t __n)
68 register unsigned long int __d0, __d1;
69 register void *__tmp = __dest;
70 __asm__ __volatile__
71 ("1:\n\t"
72 "movl (%2),%0\n\t"
73 "leal 4(%2),%2\n\t"
74 "movl %0,(%1)\n\t"
75 "leal 4(%1),%1\n\t"
76 "decl %3\n\t"
77 "jnz 1b"
78 : "=&r" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
79 : "1" (__tmp), "2" (__src), "3" (__n / 4)
80 : "memory", "cc");
81 return __dest;
84 __STRING_INLINE void *__memcpy_by2 (void *__dest, __const void *__src,
85 size_t __n);
87 __STRING_INLINE void *
88 __memcpy_by2 (void *__dest, __const void *__src, size_t __n)
90 register unsigned long int __d0, __d1;
91 register void *__tmp = __dest;
92 __asm__ __volatile__
93 ("shrl $1,%3\n\t"
94 "jz 2f\n" /* only a word */
95 "1:\n\t"
96 "movl (%2),%0\n\t"
97 "leal 4(%2),%2\n\t"
98 "movl %0,(%1)\n\t"
99 "leal 4(%1),%1\n\t"
100 "decl %3\n\t"
101 "jnz 1b\n"
102 "2:\n\t"
103 "movw (%2),%w0\n\t"
104 "movw %w0,(%1)"
105 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__src), "=&r" (__d1)
106 : "1" (__tmp), "2" (__src), "3" (__n / 2)
107 : "memory", "cc");
108 return __dest;
111 __STRING_INLINE void *__memcpy_g (void *__dest, __const void *__src,
112 size_t __n);
114 __STRING_INLINE void *
115 __memcpy_g (void *__dest, __const void *__src, size_t __n)
117 register unsigned long int __d0, __d1, __d2;
118 register void *__tmp = __dest;
119 __asm__ __volatile__
120 ("cld\n\t"
121 "shrl $1,%%ecx\n\t"
122 "jnc 1f\n\t"
123 "movsb\n"
124 "1:\n\t"
125 "shrl $1,%%ecx\n\t"
126 "jnc 2f\n\t"
127 "movsw\n"
128 "2:\n\t"
129 "rep; movsl"
130 : "=&c" (__d0), "=&D" (__d1), "=&S" (__d2)
131 : "0" (__n), "1" (__tmp), "2" (__src)
132 : "memory", "cc");
133 return __dest;
137 /* Copy N bytes of SRC to DEST, guaranteeing
138 correct behavior for overlapping strings. */
139 __STRING_INLINE void *
140 memmove (void *__dest, __const void *__src, size_t __n)
142 register unsigned long int __d0, __d1, __d2;
143 register void *__tmp = __dest;
144 if (__dest < __src)
145 __asm__ __volatile__
146 ("cld\n\t"
147 "rep; movsb"
148 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
149 : "0" (__n), "1" (__src), "2" (__tmp)
150 : "memory");
151 else
152 __asm__ __volatile__
153 ("std\n\t"
154 "rep; movsb\n\t"
155 "cld"
156 : "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
157 : "0" (__n), "1" (__n - 1 + (__const char *) __src),
158 "2" (__n - 1 + (char *) __tmp)
159 : "memory");
160 return __dest;
164 /* Compare N bytes of S1 and S2. */
165 #define _HAVE_STRING_ARCH_memcmp 1
166 #ifndef __PIC__
167 /* gcc has problems to spill registers when using PIC. */
168 __STRING_INLINE int
169 memcmp (__const void *__s1, __const void *__s2, size_t __n)
171 register unsigned long int __d0, __d1, __d2;
172 register int __res;
173 __asm__ __volatile__
174 ("cld\n\t"
175 "repe; cmpsb\n\t"
176 "je 1f\n\t"
177 "sbbl %0,%0\n\t"
178 "orb $1,%b0\n"
179 "1:"
180 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
181 : "0" (0), "1" (__s1), "2" (__s2), "3" (__n)
182 : "cc");
183 return __res;
185 #endif
188 /* Set N bytes of S to C. */
189 #define _HAVE_STRING_ARCH_memset 1
190 #define memset(s, c, n) \
191 (__extension__ (__builtin_constant_p (c) \
192 ? (__builtin_constant_p (n) \
193 ? __memset_cc (s, c, n) \
194 : __memset_cg (s, c, n)) \
195 : (__builtin_constant_p (n) \
196 ? __memset_gc (s, c, n) \
197 : __memset_gg (s, c, n))))
198 #define __memset_cc(s, c, n) \
199 ((n) == 0 \
200 ? (s) \
201 : (((n) % 4 == 0) \
202 ? __memset_cc_by4 (s, c, n) \
203 : (((n) % 2== 0) \
204 ? __memset_cc_by2 (s, c, n) \
205 : __memset_cg (s, c, n))))
206 #define __memset_gc(s, c, n) \
207 ((n) == 0 \
208 ? (s) \
209 : (((n) % 4== 0) \
210 ? __memset_gc_by4 (s, c, n) \
211 : (((n) % 2 == 0) \
212 ? __memset_gc_by2 (s, c, n) \
213 : __memset_gg (s, c, n))))
215 __STRING_INLINE void *__memset_cc_by4 (void *__s, int __c, size_t __n);
217 __STRING_INLINE void *
218 __memset_cc_by4 (void *__s, int __c, size_t __n)
220 register unsigned long int __d0;
221 register char *__tmp = __s;
222 __asm__ __volatile__
223 ("1:\n\t"
224 "movl %2,(%0)\n\t"
225 "leal 4(%0),%0\n\t"
226 "decl %1\n\t"
227 "jnz 1b"
228 : "=&r" (__tmp), "=&r" (__d0)
229 : "q" (0x01010101UL * (unsigned char) __c), "0" (__tmp), "1" (__n / 4)
230 : "memory", "cc");
231 return __s;
234 __STRING_INLINE void *__memset_cc_by2 (void *__s, int __c, size_t __n);
236 __STRING_INLINE void *
237 __memset_cc_by2 (void *__s, int __c, size_t __n)
239 register unsigned long int __d0;
240 register void *__tmp = __s;
241 __asm__ __volatile__
242 ("shrl $1,%1\n\t" /* may be divisible also by 4 */
243 "jz 2f\n"
244 "1:\n\t"
245 "movl %2,(%0)\n\t"
246 "leal 4(%0),%0\n\t"
247 "decl %1\n\t"
248 "jnz 1b\n"
249 "2:\n\t"
250 "movw %w2,(%0)"
251 : "=&r" (__tmp), "=&r" (__d0)
252 : "q" (0x01010101UL * (unsigned char) __c), "0" (__tmp), "1" (__n / 2)
253 : "memory", "cc");
254 return __s;
257 __STRING_INLINE void *__memset_gc_by4 (void *__s, int __c, size_t __n);
259 __STRING_INLINE void *
260 __memset_gc_by4 (void *__s, int __c, size_t __n)
262 register void *__tmp = __s;
263 register unsigned long int __d0;
264 __asm__ __volatile__
265 ("movb %b0,%h0\n"
266 "pushw %w0\n\t"
267 "shll $16,%0\n\t"
268 "popw %w0\n"
269 "1:\n\t"
270 "movl %0,(%1)\n\t"
271 "addl $4,%1\n\t"
272 "decl %2\n\t"
273 "jnz 1b\n"
274 : "=&q" (__c), "=&r" (__tmp), "=&r" (__d0)
275 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 4)
276 : "memory", "cc");
277 return __s;
280 __STRING_INLINE void *__memset_gc_by2 (void *__s, int __c, size_t __n);
282 __STRING_INLINE void *
283 __memset_gc_by2 (void *__s, int __c, size_t __n)
285 register unsigned long int __d0, __d1;
286 register void *__tmp = __s;
287 __asm__ __volatile__
288 ("movb %b0,%h0\n\t"
289 "shrl $1,%2\n\t" /* may be divisible also by 4 */
290 "jz 2f\n\t"
291 "pushw %w0\n\t"
292 "shll $16,%0\n\t"
293 "popw %w0\n"
294 "1:\n\t"
295 "movl %0,(%1)\n\t"
296 "leal 4(%1),%1\n\t"
297 "decl %2\n\t"
298 "jnz 1b\n"
299 "2:\n\t"
300 "movw %w0,(%1)"
301 : "=&q" (__d0), "=&r" (__tmp), "=&r" (__d1)
302 : "0" ((unsigned int) __c), "1" (__tmp), "2" (__n / 2)
303 : "memory", "cc");
304 return __s;
307 __STRING_INLINE void *__memset_cg (void *__s, int __c, size_t __n);
309 __STRING_INLINE void *
310 __memset_cg (void *__s, int __c, size_t __n)
312 register unsigned long __d0, __d1;
313 register void *__tmp = __s;
314 __asm__ __volatile__
315 ("shrl $1,%%ecx\n\t"
316 "rep; stosw\n\t"
317 "jnc 1f\n\t"
318 "movb %%al,(%%edi)\n"
319 "1:"
320 : "=&c" (__d0), "=&D" (__d1)
321 : "0" (__n), "1" (__tmp), "a" (0x0101U * (unsigned char) __c)
322 : "memory", "cc");
323 return __s;
326 __STRING_INLINE void *__memset_gg (void *__s, int __c, size_t __n);
328 __STRING_INLINE void *
329 __memset_gg (void *__s, int __c, size_t __n)
331 register unsigned long int __d0, __d1;
332 register void *__tmp = __s;
333 __asm__ __volatile__
334 ("movb %%al,%%ah\n\t"
335 "shrl $1,%%ecx\n\t"
336 "rep; stosw\n\t"
337 "jnc 1f\n\t"
338 "movb %%al,(%%edi)\n"
339 "1:"
340 : "=&c" (__d0), "=&D" (__d1)
341 : "0" (__n), "1" (__tmp), "a" (__c)
342 : "memory", "cc");
343 return __s;
347 /* Search N bytes of S for C. */
348 #define _HAVE_STRING_ARCH_memchr 1
349 __STRING_INLINE void *
350 memchr (__const void *__s, int __c, size_t __n)
352 register unsigned long int __d0;
353 register unsigned char *__res;
354 if (__n == 0)
355 return NULL;
356 #ifdef __i686__
357 __asm__ __volatile__
358 ("movl $1, %%edx\n\t"
359 "cld\n\t"
360 "repne; scasb\n\t"
361 "cmovne %%edx,%0"
362 : "=D" (__res), "=&c" (__d0)
363 : "a" (__c), "0" (__s), "1" (__n)
364 : "dx", "cc");
365 #else
366 __asm__ __volatile__
367 ("cld\n\t"
368 "repne; scasb\n\t"
369 "je 1f\n\t"
370 "movl $1,%0\n"
371 "1:"
372 : "=D" (__res), "=&c" (__d0)
373 : "a" (__c), "0" (__s), "1" (__n)
374 : "cc");
375 #endif
376 return __res - 1;
380 /* Return the length of S. */
381 #define _HAVE_STRING_ARCH_strlen 1
382 #define strlen(str) \
383 (__extension__ (__builtin_constant_p (str) \
384 ? __builtin_strlen (str) \
385 : __strlen_g (str)))
386 __STRING_INLINE size_t __strlen_g (__const char *__str);
388 __STRING_INLINE size_t
389 __strlen_g (__const char *__str)
391 register char __dummy;
392 register __const char *__tmp = __str;
393 __asm__ __volatile__
394 ("1:\n\t"
395 "movb (%0),%b1\n\t"
396 "leal 1(%0),%0\n\t"
397 "testb %b1,%b1\n\t"
398 "jne 1b"
399 : "=r" (__tmp), "=&q" (__dummy)
400 : "0" (__str)
401 : "memory", "cc" );
402 return __tmp - __str - 1;
406 /* Copy SRC to DEST. */
407 #define _HAVE_STRING_ARCH_strcpy 1
408 #define strcpy(dest, src) \
409 (__extension__ (__builtin_constant_p (src) \
410 ? (sizeof ((src)[0]) == 1 && strlen (src) + 1 <= 8 \
411 ? __strcpy_small (dest, src, strlen (src) + 1) \
412 : (char *) memcpy ((char *) dest, \
413 (__const char *) src, \
414 strlen (src) + 1)) \
415 : __strcpy_g (dest, src)))
417 #define __strcpy_small(dest, src, srclen) \
418 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
419 switch (srclen) \
421 case 1: \
422 *__dest = '\0'; \
423 break; \
424 case 2: \
425 *((__uint16_t *) __dest) = \
426 __STRING_SMALL_GET16 (src, 0); \
427 break; \
428 case 3: \
429 *((__uint16_t *) __dest) = \
430 __STRING_SMALL_GET16 (src, 0); \
431 *(__dest + 2) = '\0'; \
432 break; \
433 case 4: \
434 *((__uint32_t *) __dest) = \
435 __STRING_SMALL_GET32 (src, 0); \
436 break; \
437 case 5: \
438 *((__uint32_t *) __dest) = \
439 __STRING_SMALL_GET32 (src, 0); \
440 *(__dest + 4) = '\0'; \
441 break; \
442 case 6: \
443 *((__uint32_t *) __dest) = \
444 __STRING_SMALL_GET32 (src, 0); \
445 *((__uint16_t *) (__dest + 4)) = \
446 __STRING_SMALL_GET16 (src, 4); \
447 break; \
448 case 7: \
449 *((__uint32_t *) __dest) = \
450 __STRING_SMALL_GET32 (src, 0); \
451 *((__uint16_t *) (__dest + 4)) = \
452 __STRING_SMALL_GET16 (src, 4); \
453 *(__dest + 6) = '\0'; \
454 break; \
455 case 8: \
456 *((__uint32_t *) __dest) = \
457 __STRING_SMALL_GET32 (src, 0); \
458 *((__uint32_t *) (__dest + 4)) = \
459 __STRING_SMALL_GET32 (src, 4); \
460 break; \
462 (char *) __dest; }))
464 __STRING_INLINE char *__strcpy_g (char *__dest, __const char *__src);
466 __STRING_INLINE char *
467 __strcpy_g (char *__dest, __const char *__src)
469 register char *__tmp = __dest;
470 register char __dummy;
471 __asm__ __volatile__
473 "1:\n\t"
474 "movb (%0),%b2\n\t"
475 "leal 1(%0),%0\n\t"
476 "movb %b2,(%1)\n\t"
477 "leal 1(%1),%1\n\t"
478 "testb %b2,%b2\n\t"
479 "jne 1b"
480 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy)
481 : "0" (__src), "1" (__tmp)
482 : "memory", "cc");
483 return __dest;
487 #ifdef __USE_GNU
488 # define _HAVE_STRING_ARCH_stpcpy 1
489 /* Copy SRC to DEST. */
490 # define __stpcpy(dest, src) \
491 (__extension__ (__builtin_constant_p (src) \
492 ? (strlen (src) + 1 <= 8 \
493 ? __stpcpy_small (dest, src, strlen (src) + 1) \
494 : __stpcpy_c (dest, src, strlen (src) + 1)) \
495 : __stpcpy_g (dest, src)))
496 # define __stpcpy_c(dest, src, srclen) \
497 ((srclen) % 4 == 0 \
498 ? __mempcpy_by4 (dest, src, srclen) - 1 \
499 : ((srclen) % 2 == 0 \
500 ? __mempcpy_by2 (dest, src, srclen) - 1 \
501 : __mempcpy_byn (dest, src, srclen) - 1))
503 /* In glibc itself we use this symbol for namespace reasons. */
504 # define stpcpy(dest, src) __stpcpy (dest, src)
506 # define __stpcpy_small(dest, src, srclen) \
507 (__extension__ ({ unsigned char *__dest = (unsigned char *) (dest); \
508 switch (srclen) \
510 case 1: \
511 *__dest = '\0'; \
512 break; \
513 case 2: \
514 *((__uint16_t *) __dest) = \
515 __STRING_SMALL_GET16 (src, 0); \
516 ++__dest; \
517 break; \
518 case 3: \
519 *((__uint16_t *) __dest)++ = \
520 __STRING_SMALL_GET16 (src, 0); \
521 *__dest = '\0'; \
522 break; \
523 case 4: \
524 *((__uint32_t *) __dest) = \
525 __STRING_SMALL_GET32 (src, 0); \
526 __dest += 3; \
527 break; \
528 case 5: \
529 *((__uint32_t *) __dest)++ = \
530 __STRING_SMALL_GET32 (src, 0); \
531 *__dest = '\0'; \
532 break; \
533 case 6: \
534 *((__uint32_t *) __dest) = \
535 __STRING_SMALL_GET32 (src, 0); \
536 *((__uint16_t *) (__dest + 4)) = \
537 __STRING_SMALL_GET16 (src, 4); \
538 __dest += 5; \
539 break; \
540 case 7: \
541 *((__uint32_t *) __dest) = \
542 __STRING_SMALL_GET32 (src, 0); \
543 *((__uint16_t *) (__dest + 4)) = \
544 __STRING_SMALL_GET16 (src, 4); \
545 __dest += 6; \
546 *__dest = '\0'; \
547 break; \
548 case 8: \
549 *((__uint32_t *) __dest) = \
550 __STRING_SMALL_GET32 (src, 0); \
551 *((__uint32_t *) (__dest + 4)) = \
552 __STRING_SMALL_GET32 (src, 4); \
553 __dest += 7; \
554 break; \
556 (char *) __dest; }))
558 __STRING_INLINE char *__mempcpy_by4 (char *__dest, __const char *__src,
559 size_t __srclen);
561 __STRING_INLINE char *
562 __mempcpy_by4 (char *__dest, __const char *__src, size_t __srclen)
564 register char *__tmp = __dest;
565 register unsigned long int __d0, __d1;
566 __asm__ __volatile__
567 ("1:\n\t"
568 "movl (%2),%0\n\t"
569 "leal 4(%2),%2\n\t"
570 "movl %0,(%1)\n\t"
571 "leal 4(%1),%1\n\t"
572 "decl %3\n\t"
573 "jnz 1b"
574 : "=&r" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
575 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
576 : "memory", "cc");
577 return __tmp;
580 __STRING_INLINE char *__mempcpy_by2 (char *__dest, __const char *__src,
581 size_t __srclen);
583 __STRING_INLINE char *
584 __mempcpy_by2 (char *__dest, __const char *__src, size_t __srclen)
586 register char *__tmp = __dest;
587 register unsigned long int __d0, __d1;
588 __asm__ __volatile__
589 ("shrl $1,%3\n\t"
590 "jz 2f\n" /* only a word */
591 "1:\n\t"
592 "movl (%2),%0\n\t"
593 "leal 4(%2),%2\n\t"
594 "movl %0,(%1)\n\t"
595 "leal 4(%1),%1\n\t"
596 "decl %3\n\t"
597 "jnz 1b\n"
598 "2:\n\t"
599 "movw (%2),%w0\n\t"
600 "movw %w0,(%1)"
601 : "=&q" (__d0), "=r" (__tmp), "=&r" (__src), "=&r" (__d1)
602 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
603 : "memory", "cc");
604 return __tmp + 2;
607 __STRING_INLINE char *__mempcpy_byn (char *__dest, __const char *__src,
608 size_t __srclen);
610 __STRING_INLINE char *
611 __mempcpy_byn (char *__dest, __const char *__src, size_t __srclen)
613 register unsigned long __d0, __d1;
614 register char *__tmp = __dest;
615 __asm__ __volatile__
616 ("cld\n\t"
617 "shrl $1,%%ecx\n\t"
618 "jnc 1f\n\t"
619 "movsb\n"
620 "1:\n\t"
621 "shrl $1,%%ecx\n\t"
622 "jnc 2f\n\t"
623 "movsw\n"
624 "2:\n\t"
625 "rep; movsl"
626 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
627 : "0" (__tmp), "1" (__srclen), "2" (__src)
628 : "memory", "cc");
629 return __tmp;
632 __STRING_INLINE char *__stpcpy_g (char *__dest, __const char *__src);
634 __STRING_INLINE char *
635 __stpcpy_g (char *__dest, __const char *__src)
637 register char *__tmp = __dest;
638 register char __dummy;
639 __asm__ __volatile__
641 "1:\n\t"
642 "movb (%0),%b2\n\t"
643 "leal 1(%0),%0\n\t"
644 "movb %b2,(%1)\n\t"
645 "leal 1(%1),%1\n\t"
646 "testb %b2,%b2\n\t"
647 "jne 1b"
648 : "=&r" (__src), "=r" (__tmp), "=&q" (__dummy)
649 : "0" (__src), "1" (__tmp)
650 : "memory", "cc");
651 return __tmp - 1;
653 #endif
656 /* Copy no more than N characters of SRC to DEST. */
657 #define _HAVE_STRING_ARCH_strncpy 1
658 #define strncpy(dest, src, n) \
659 (__extension__ (__builtin_constant_p (src) \
660 ? ((strlen (src) + 1 >= ((size_t) (n)) \
661 ? (char *) memcpy ((char *) dest, \
662 (__const char *) src, n) \
663 : __strncpy_cg (dest, src, strlen (src) + 1, n))) \
664 : __strncpy_gg (dest, src, n)))
665 #define __strncpy_cg(dest, src, srclen, n) \
666 (((srclen) % 4 == 0) \
667 ? __strncpy_by4 (dest, src, srclen, n) \
668 : (((srclen) % 2 == 0) \
669 ? __strncpy_by2 (dest, src, srclen, n) \
670 : __strncpy_byn (dest, src, srclen, n)))
672 __STRING_INLINE char *__strncpy_by4 (char *__dest, __const char __src[],
673 size_t __srclen, size_t __n);
675 __STRING_INLINE char *
676 __strncpy_by4 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
678 register char *__tmp = __dest;
679 register int __dummy1, __dummy2;
680 __asm__ __volatile__
681 ("1:\n\t"
682 "movl (%2),%0\n\t"
683 "leal 4(%2),%2\n\t"
684 "movl %0,(%1)\n\t"
685 "leal 4(%1),%1\n\t"
686 "decl %3\n\t"
687 "jnz 1b"
688 : "=&r" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
689 : "1" (__tmp), "2" (__src), "3" (__srclen / 4)
690 : "memory", "cc");
691 (void) memset (__tmp, '\0', __n - __srclen);
692 return __dest;
695 __STRING_INLINE char *__strncpy_by2 (char *__dest, __const char __src[],
696 size_t __srclen, size_t __n);
698 __STRING_INLINE char *
699 __strncpy_by2 (char *__dest, __const char __src[], size_t __srclen, size_t __n)
701 register char *__tmp = __dest;
702 register int __dummy1, __dummy2;
703 __asm__ __volatile__
704 ("shrl $1,%3\n\t"
705 "jz 2f\n" /* only a word */
706 "1:\n\t"
707 "movl (%2),%0\n\t"
708 "leal 4(%2),%2\n\t"
709 "movl %0,(%1)\n\t"
710 "leal 4(%1),%1\n\t"
711 "decl %3\n\t"
712 "jnz 1b\n"
713 "2:\n\t"
714 "movw (%2),%w0\n\t"
715 "movw %w0,(%1)\n\t"
716 : "=&q" (__dummy1), "=r" (__tmp), "=&r" (__src), "=&r" (__dummy2)
717 : "1" (__tmp), "2" (__src), "3" (__srclen / 2)
718 : "memory", "cc");
719 (void) memset (__tmp + 2, '\0', __n - __srclen);
720 return __dest;
723 __STRING_INLINE char *__strncpy_byn (char *__dest, __const char __src[],
724 size_t __srclen, size_t __n);
726 __STRING_INLINE char *
727 __strncpy_byn (char *__dest, __const char __src[], size_t __srclen, size_t __n)
729 register unsigned long int __d0, __d1;
730 register char *__tmp = __dest;
731 __asm__ __volatile__
732 ("cld\n\t"
733 "shrl $1,%1\n\t"
734 "jnc 1f\n\t"
735 "movsb\n"
736 "1:\n\t"
737 "shrl $1,%1\n\t"
738 "jnc 2f\n\t"
739 "movsw\n"
740 "2:\n\t"
741 "rep; movsl"
742 : "=D" (__tmp), "=&c" (__d0), "=&S" (__d1)
743 : "1" (__srclen), "0" (__tmp),"2" (__src)
744 : "memory", "cc");
745 (void) memset (__tmp, '\0', __n - __srclen);
746 return __dest;
749 __STRING_INLINE char *__strncpy_gg (char *__dest, __const char *__src,
750 size_t __n);
752 __STRING_INLINE char *
753 __strncpy_gg (char *__dest, __const char *__src, size_t __n)
755 register char *__tmp = __dest;
756 register char __dummy;
757 if (__n > 0)
758 __asm__ __volatile__
759 ("1:\n\t"
760 "movb (%0),%2\n\t"
761 "incl %0\n\t"
762 "movb %2,(%1)\n\t"
763 "incl %1\n\t"
764 "decl %3\n\t"
765 "je 3f\n\t"
766 "testb %2,%2\n\t"
767 "jne 1b\n\t"
768 "2:\n\t"
769 "movb %2,(%1)\n\t"
770 "incl %1\n\t"
771 "decl %3\n\t"
772 "jne 2b\n\t"
773 "3:"
774 : "=&r" (__src), "=&r" (__tmp), "=&q" (__dummy), "=&r" (__n)
775 : "0" (__src), "1" (__tmp), "3" (__n)
776 : "memory", "cc");
778 return __dest;
782 /* Append SRC onto DEST. */
783 #define _HAVE_STRING_ARCH_strcat 1
784 #define strcat(dest, src) \
785 (__extension__ (__builtin_constant_p (src) \
786 ? __strcat_c (dest, src, strlen (src) + 1) \
787 : __strcat_g (dest, src)))
789 __STRING_INLINE char *__strcat_c (char *__dest, __const char __src[],
790 size_t __srclen);
792 __STRING_INLINE char *
793 __strcat_c (char *__dest, __const char __src[], size_t __srclen)
795 #ifdef __i686__
796 register unsigned long int __d0;
797 register char *__tmp;
798 __asm__ __volatile__
799 ("repne; scasb"
800 : "=D" (__tmp), "=&c" (__d0)
801 : "0" (__dest), "1" (0xffffffff), "a" (0)
802 : "cc");
803 --__tmp;
804 #else
805 register char *__tmp = __dest - 1;
806 __asm__ __volatile__
807 ("1:\n\t"
808 "incl %0\n\t"
809 "cmpb $0,(%0)\n\t"
810 "jne 1b\n"
811 : "=r" (__tmp)
812 : "0" (__tmp)
813 : "cc");
814 #endif
815 (void) memcpy (__tmp, __src, __srclen);
816 return __dest;
819 __STRING_INLINE char *__strcat_g (char *__dest, __const char *__src);
821 __STRING_INLINE char *
822 __strcat_g (char *__dest, __const char *__src)
824 register char *__tmp = __dest - 1;
825 register char __dummy;
826 __asm__ __volatile__
827 ("1:\n\t"
828 "incl %1\n\t"
829 "cmpb $0,(%1)\n\t"
830 "jne 1b\n"
831 "2:\n\t"
832 "movb (%2),%b0\n\t"
833 "incl %2\n\t"
834 "movb %b0,(%1)\n\t"
835 "incl %1\n\t"
836 "testb %b0,%b0\n\t"
837 "jne 2b\n"
838 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src)
839 : "1" (__tmp), "2" (__src)
840 : "memory", "cc");
841 return __dest;
845 /* Append no more than N characters from SRC onto DEST. */
846 #define _HAVE_STRING_ARCH_strncat 1
847 #define strncat(dest, src, n) \
848 (__extension__ ({ char *__dest = (dest); \
849 __builtin_constant_p (src) && __builtin_constant_p (n) \
850 ? (strlen (src) < ((size_t) (n)) \
851 ? strcat (__dest, src) \
852 : (memcpy (strchr (__dest, '\0'), \
853 (__const char *) src, n), __dest)) \
854 : __strncat_g (__dest, src, n); }))
856 __STRING_INLINE char *__strncat_g (char *__dest, __const char __src[],
857 size_t __n);
859 __STRING_INLINE char *
860 __strncat_g (char *__dest, __const char __src[], size_t __n)
862 register char *__tmp = __dest;
863 register char __dummy;
864 #ifdef __i686__
865 __asm__ __volatile__
866 ("repne; scasb\n"
867 "decl %1\n\t"
868 "1:\n\t"
869 "decl %3\n\t"
870 "js 2f\n\t"
871 "movb (%2),%b0\n\t"
872 "movsb\n\t"
873 "testb %b0,%b0\n\t"
874 "jne 1b\n\t"
875 "decl %1\n"
876 "2:\n\t"
877 "movb $0,(%1)"
878 : "=&a" (__dummy), "=&D" (__tmp), "=&S" (__src), "=&r" (__n)
879 : "0" (0), "1" (__tmp), "2" (__src), "3" (__n)
880 : "memory", "cc");
881 #else
882 --__tmp;
883 __asm__ __volatile__
884 ("1:\n\t"
885 "cmpb $0,1(%1)\n\t"
886 "leal 1(%1),%1\n\t"
887 "jne 1b\n"
888 "2:\n\t"
889 "decl %3\n\t"
890 "js 3f\n\t"
891 "movb (%2),%b0\n\t"
892 "leal 1(%2),%2\n\t"
893 "movb %b0,(%1)\n\t"
894 "leal 1(%1),%1\n\t"
895 "testb %b0,%b0\n\t"
896 "jne 2b\n\t"
897 "decl %1\n"
898 "3:\n\t"
899 "movb $0,(%1)"
900 : "=&q" (__dummy), "=&r" (__tmp), "=&r" (__src), "=&r" (__n)
901 : "1" (__tmp), "2" (__src), "3" (__n)
902 : "memory", "cc");
903 #endif
904 return __dest;
908 /* Compare S1 and S2. */
909 #define _HAVE_STRING_ARCH_strcmp 1
910 #define strcmp(s1, s2) \
911 (__extension__ (__builtin_constant_p (s1) && __builtin_constant_p (s2) \
912 && (sizeof ((s1)[0]) != 1 || strlen (s1) >= 4) \
913 && (sizeof ((s2)[0]) != 1 || strlen (s2) >= 4) \
914 ? memcmp ((__const char *) s1, (__const char *) s2, \
915 (strlen (s1) < strlen (s2) \
916 ? strlen (s1) : strlen (s2)) + 1) \
917 : (__builtin_constant_p (s1) && sizeof ((s1)[0]) == 1 \
918 && sizeof ((s2)[0]) == 1 && strlen (s1) < 4 \
919 ? (__builtin_constant_p (s2) && sizeof ((s2)[0]) == 1 \
920 ? __strcmp_cc (s1, s2, strlen (s1)) \
921 : __strcmp_cg (s1, s2, strlen (s1))) \
922 : (__builtin_constant_p (s2) && sizeof ((s1)[0]) == 1 \
923 && sizeof ((s2)[0]) == 1 && strlen (s2) < 4 \
924 ? (__builtin_constant_p (s1) \
925 ? __strcmp_cc (s1, s2, strlen (s2)) \
926 : __strcmp_gc (s1, s2, strlen (s2))) \
927 : __strcmp_gg (s1, s2)))))
929 #define __strcmp_cc(s1, s2, l) \
930 (__extension__ ({ register int __result = ((unsigned char) (s1)[0] \
931 - (unsigned char) (s2)[0]); \
932 if (l > 0 && __result == 0) \
934 __result = ((unsigned char) (s1)[1] \
935 - (unsigned char) (s2)[1]); \
936 if (l > 1 && __result == 0) \
938 __result = ((unsigned char) (s1)[2] \
939 - (unsigned char) (s2)[2]); \
940 if (l > 2 && __result == 0) \
941 __result = ((unsigned char) (s1)[3] \
942 - (unsigned char) (s2)[3]); \
945 __result; }))
947 #define __strcmp_cg(s1, s2, l1) \
948 (__extension__ ({ __const unsigned char *__s2 = (unsigned char *) (s2); \
949 register int __result = (unsigned char) (s1)[0] - __s2[0];\
950 if (l1 > 0 && __result == 0) \
952 __result = (unsigned char) (s1)[1] - __s2[1]; \
953 if (l1 > 1 && __result == 0) \
955 __result = (unsigned char) (s1)[2] - __s2[2]; \
956 if (l1 > 2 && __result == 0) \
957 __result = (unsigned char) (s1)[3] - __s2[3]; \
960 __result; }))
962 #define __strcmp_gc(s1, s2, l2) \
963 (__extension__ ({ __const unsigned char *__s1 = (unsigned char *) (s1); \
964 register int __result = __s1[0] - (unsigned char) (s2)[0];\
965 if (l2 > 0 && __result == 0) \
967 __result = __s1[1] - (unsigned char) (s2)[1]; \
968 if (l2 > 1 && __result == 0) \
970 __result = __s1[2] - (unsigned char) (s2)[2]; \
971 if (l2 > 2 && __result == 0) \
972 __result = __s1[3] - (unsigned char) (s2)[3]; \
975 __result; }))
977 __STRING_INLINE int __strcmp_gg (__const char *__s1, __const char *__s2);
979 __STRING_INLINE int
980 __strcmp_gg (__const char *__s1, __const char *__s2)
982 register int __res;
983 __asm__ __volatile__
984 ("1:\n\t"
985 "movb (%1),%b0\n\t"
986 "leal 1(%1),%1\n\t"
987 "cmpb %b0,(%2)\n\t"
988 "jne 2f\n\t"
989 "leal 1(%2),%2\n\t"
990 "testb %b0,%b0\n\t"
991 "jne 1b\n\t"
992 "xorl %0,%0\n\t"
993 "jmp 3f\n"
994 "2:\n\t"
995 "movl $1,%0\n\t"
996 "jb 3f\n\t"
997 "negl %0\n"
998 "3:"
999 : "=q" (__res), "=&r" (__s1), "=&r" (__s2)
1000 : "1" (__s1), "2" (__s2)
1001 : "cc");
1002 return __res;
1006 /* Compare N characters of S1 and S2. */
1007 #define _HAVE_STRING_ARCH_strncmp 1
1008 #define strncmp(s1, s2, n) \
1009 (__extension__ (__builtin_constant_p (s1) && strlen (s1) < ((size_t) (n)) \
1010 ? strcmp (s1, s2) \
1011 : (__builtin_constant_p (s2) && strlen (s2) < ((size_t) (n))\
1012 ? strcmp (s1, s2) \
1013 : __strncmp_g (s1, s2, n))))
1015 __STRING_INLINE int __strncmp_g (__const char *__s1, __const char *__s2,
1016 size_t __n);
1018 __STRING_INLINE int
1019 __strncmp_g (__const char *__s1, __const char *__s2, size_t __n)
1021 register int __res;
1022 __asm__ __volatile__
1023 ("1:\n\t"
1024 "decl %3\n\t"
1025 "js 2f\n\t"
1026 "movb (%1),%b0\n\t"
1027 "incl %1\n\t"
1028 "cmpb %b0,(%2)\n\t"
1029 "jne 3f\n\t"
1030 "incl %2\n\t"
1031 "testb %b0,%b0\n\t"
1032 "jne 1b\n"
1033 "2:\n\t"
1034 "xorl %0,%0\n\t"
1035 "jmp 4f\n"
1036 "3:\n\t"
1037 "movl $1,%0\n\t"
1038 "jb 4f\n\t"
1039 "negl %0\n"
1040 "4:"
1041 : "=q" (__res), "=&r" (__s1), "=&r" (__s2), "=&r" (__n)
1042 : "1" (__s1), "2" (__s2), "3" (__n)
1043 : "cc");
1044 return __res;
1048 /* Find the first occurrence of C in S. */
1049 #define _HAVE_STRING_ARCH_strchr 1
1050 #define strchr(s, c) \
1051 (__extension__ (__builtin_constant_p (c) \
1052 ? __strchr_c (s, ((c) & 0xff) << 8) \
1053 : __strchr_g (s, c)))
1055 __STRING_INLINE char *__strchr_c (__const char *__s, int __c);
1057 __STRING_INLINE char *
1058 __strchr_c (__const char *__s, int __c)
1060 register unsigned long int __d0;
1061 register char *__res;
1062 __asm__ __volatile__
1063 ("1:\n\t"
1064 "movb (%0),%%al\n\t"
1065 "cmpb %%ah,%%al\n\t"
1066 "je 2f\n\t"
1067 "leal 1(%0),%0\n\t"
1068 "testb %%al,%%al\n\t"
1069 "jne 1b\n\t"
1070 "xorl %0,%0\n"
1071 "2:"
1072 : "=r" (__res), "=&a" (__d0)
1073 : "0" (__s), "1" (__c)
1074 : "cc");
1075 return __res;
1078 __STRING_INLINE char *__strchr_g (__const char *__s, int __c);
1080 __STRING_INLINE char *
1081 __strchr_g (__const char *__s, int __c)
1083 register unsigned long int __d0;
1084 register char *__res;
1085 __asm__ __volatile__
1086 ("movb %%al,%%ah\n"
1087 "1:\n\t"
1088 "movb (%0),%%al\n\t"
1089 "cmpb %%ah,%%al\n\t"
1090 "je 2f\n\t"
1091 "leal 1(%0),%0\n\t"
1092 "testb %%al,%%al\n\t"
1093 "jne 1b\n\t"
1094 "xorl %0,%0\n"
1095 "2:"
1096 : "=r" (__res), "=&a" (__d0)
1097 : "0" (__s), "1" (__c)
1098 : "cc");
1099 return __res;
1103 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1104 /* Find the first occurrence of C in S. This is the BSD name. */
1105 # define _HAVE_STRING_ARCH_index 1
1106 # define index(s, c) \
1107 (__extension__ (__builtin_constant_p (c) \
1108 ? __strchr_c (s, ((c) & 0xff) << 8) \
1109 : __strchr_g (s, c)))
1110 #endif
1113 /* Find the last occurrence of C in S. */
1114 #define _HAVE_STRING_ARCH_strrchr 1
1115 #define strrchr(s, c) \
1116 (__extension__ (__builtin_constant_p (c) \
1117 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1118 : __strrchr_g (s, c)))
1120 #ifdef __i686__
1121 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1123 __STRING_INLINE char *
1124 __strrchr_c (__const char *__s, int __c)
1126 register unsigned long int __d0, __d1;
1127 register char *__res;
1128 __asm__ __volatile__
1129 ("cld\n"
1130 "1:\n\t"
1131 "lodsb\n\t"
1132 "cmpb %h2,%b2\n\t"
1133 "cmove %1,%0\n\t"
1134 "testb %b2,%b2\n\t"
1135 "jne 1b"
1136 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1137 : "0" (1), "1" (__s), "2" (__c)
1138 : "cc");
1139 return __res - 1;
1142 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1144 __STRING_INLINE char *
1145 __strrchr_g (__const char *__s, int __c)
1147 register unsigned long int __d0, __d1;
1148 register char *__res;
1149 __asm__ __volatile__
1150 ("movb %b2,%h2\n"
1151 "cld\n\t"
1152 "1:\n\t"
1153 "lodsb\n\t"
1154 "cmpb %h2,%b2\n\t"
1155 "cmove %1,%0\n\t"
1156 "testb %b2,%b2\n\t"
1157 "jne 1b"
1158 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1159 : "0" (1), "1" (__s), "2" (__c)
1160 : "cc");
1161 return __res - 1;
1163 #else
1164 __STRING_INLINE char *__strrchr_c (__const char *__s, int __c);
1166 __STRING_INLINE char *
1167 __strrchr_c (__const char *__s, int __c)
1169 register unsigned long int __d0, __d1;
1170 register char *__res;
1171 __asm__ __volatile__
1172 ("cld\n"
1173 "1:\n\t"
1174 "lodsb\n\t"
1175 "cmpb %%ah,%%al\n\t"
1176 "jne 2f\n\t"
1177 "leal -1(%%esi),%0\n"
1178 "2:\n\t"
1179 "testb %%al,%%al\n\t"
1180 "jne 1b"
1181 : "=d" (__res), "=&S" (__d0), "=&a" (__d1)
1182 : "0" (0), "1" (__s), "2" (__c)
1183 : "cc");
1184 return __res;
1187 __STRING_INLINE char *__strrchr_g (__const char *__s, int __c);
1189 __STRING_INLINE char *
1190 __strrchr_g (__const char *__s, int __c)
1192 register unsigned long int __d0, __d1;
1193 register char *__res;
1194 __asm__ __volatile__
1195 ("movb %%al,%%ah\n"
1196 "cld\n\t"
1197 "1:\n\t"
1198 "lodsb\n\t"
1199 "cmpb %%ah,%%al\n\t"
1200 "jne 2f\n\t"
1201 "leal -1(%%esi),%0\n"
1202 "2:\n\t"
1203 "testb %%al,%%al\n\t"
1204 "jne 1b"
1205 : "=r" (__res), "=&S" (__d0), "=&a" (__d1)
1206 : "0" (0), "1" (__s), "2" (__c)
1207 : "cc");
1208 return __res;
1210 #endif
1213 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1214 /* Find the last occurrence of C in S. This is the BSD name. */
1215 # define _HAVE_STRING_ARCH_rindex 1
1216 # define rindex(s, c) \
1217 (__extension__ (__builtin_constant_p (c) \
1218 ? __strrchr_c (s, ((c) & 0xff) << 8) \
1219 : __strrchr_g (s, c)))
1220 #endif
1223 /* Return the length of the initial segment of S which
1224 consists entirely of characters not in REJECT. */
1225 #define _HAVE_STRING_ARCH_strcspn 1
1226 #define strcspn(s, reject) \
1227 (__extension__ (__builtin_constant_p (reject) && sizeof ((reject)[0]) == 1 \
1228 ? ((reject)[0] == '\0' \
1229 ? strlen (s) \
1230 : ((reject)[1] == '\0' \
1231 ? __strcspn_c1 (s, (((reject)[0] << 8) & 0xff00)) \
1232 : __strcspn_cg (s, reject, strlen (reject)))) \
1233 : __strcspn_g (s, reject)))
1235 __STRING_INLINE size_t __strcspn_c1 (__const char *__s, int __reject);
1237 __STRING_INLINE size_t
1238 __strcspn_c1 (__const char *__s, int __reject)
1240 register unsigned long int __d0;
1241 register char *__res;
1242 __asm__ __volatile__
1243 ("1:\n\t"
1244 "movb (%0),%%al\n\t"
1245 "leal 1(%0),%0\n\t"
1246 "cmpb %%ah,%%al\n\t"
1247 "je 2f\n\t"
1248 "testb %%al,%%al\n\t"
1249 "jne 1b\n"
1250 "2:"
1251 : "=r" (__res), "=&a" (__d0)
1252 : "0" (__s), "1" (__reject)
1253 : "cc");
1254 return (__res - 1) - __s;
1257 __STRING_INLINE size_t __strcspn_cg (__const char *__s, __const char __reject[],
1258 size_t __reject_len);
1260 __STRING_INLINE size_t
1261 __strcspn_cg (__const char *__s, __const char __reject[], size_t __reject_len)
1263 register unsigned long int __d0, __d1, __d2;
1264 register __const char *__res;
1265 __asm__ __volatile__
1266 ("cld\n"
1267 "1:\n\t"
1268 "lodsb\n\t"
1269 "testb %%al,%%al\n\t"
1270 "je 2f\n\t"
1271 "movl %5,%%edi\n\t"
1272 "movl %6,%%ecx\n\t"
1273 "repne; scasb\n\t"
1274 "jne 1b\n"
1275 "2:"
1276 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1277 : "0" (__s), "d" (__reject), "g" (__reject_len)
1278 : "cc");
1279 return (__res - 1) - __s;
1282 __STRING_INLINE size_t __strcspn_g (__const char *__s, __const char *__reject);
1283 #ifdef __PIC__
1285 __STRING_INLINE size_t
1286 __strcspn_g (__const char *__s, __const char *__reject)
1288 register unsigned long int __d0, __d1, __d2;
1289 register __const char *__res;
1290 __asm__ __volatile__
1291 ("pushl %%ebx\n\t"
1292 "movl %4,%%edi\n\t"
1293 "cld\n\t"
1294 "repne; scasb\n\t"
1295 "notl %%ecx\n\t"
1296 "leal -1(%%ecx),%%ebx\n"
1297 "1:\n\t"
1298 "lodsb\n\t"
1299 "testb %%al,%%al\n\t"
1300 "je 2f\n\t"
1301 "movl %4,%%edi\n\t"
1302 "movl %%ebx,%%ecx\n\t"
1303 "repne; scasb\n\t"
1304 "jne 1b\n"
1305 "2:\n\t"
1306 "popl %%ebx"
1307 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1308 : "r" (__reject), "0" (__s), "1" (0), "2" (0xffffffff)
1309 : "cc");
1310 return (__res - 1) - __s;
1312 #else
1313 __STRING_INLINE size_t
1314 __strcspn_g (__const char *__s, __const char *__reject)
1316 register unsigned long int __d0, __d1, __d2, __d3;
1317 register __const char *__res;
1318 __asm__ __volatile__
1319 ("cld\n\t"
1320 "repne; scasb\n\t"
1321 "notl %%ecx\n\t"
1322 "leal -1(%%ecx),%%edx\n"
1323 "1:\n\t"
1324 "lodsb\n\t"
1325 "testb %%al,%%al\n\t"
1326 "je 2f\n\t"
1327 "movl %%ebx,%%edi\n\t"
1328 "movl %%edx,%%ecx\n\t"
1329 "repne; scasb\n\t"
1330 "jne 1b\n"
1331 "2:"
1332 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1333 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__reject), "b" (__reject)
1334 : "cc");
1335 return (__res - 1) - __s;
1337 #endif
1340 /* Return the length of the initial segment of S which
1341 consists entirely of characters in ACCEPT. */
1342 #define _HAVE_STRING_ARCH_strspn 1
1343 #define strspn(s, accept) \
1344 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1345 ? ((accept)[0] == '\0' \
1346 ? 0 \
1347 : ((accept)[1] == '\0' \
1348 ? __strspn_c1 (s, (((accept)[0] << 8 ) & 0xff00)) \
1349 : __strspn_cg (s, accept, strlen (accept)))) \
1350 : __strspn_g (s, accept)))
1352 __STRING_INLINE size_t __strspn_c1 (__const char *__s, int __accept);
1354 __STRING_INLINE size_t
1355 __strspn_c1 (__const char *__s, int __accept)
1357 register unsigned long int __d0;
1358 register char *__res;
1359 /* Please note that __accept never can be '\0'. */
1360 __asm__ __volatile__
1361 ("1:\n\t"
1362 "movb (%0),%b1\n\t"
1363 "leal 1(%0),%0\n\t"
1364 "cmpb %h1,%b1\n\t"
1365 "je 1b"
1366 : "=r" (__res), "=&q" (__d0)
1367 : "0" (__s), "1" (__accept)
1368 : "cc");
1369 return (__res - 1) - __s;
1372 __STRING_INLINE size_t __strspn_cg (__const char *__s, __const char __accept[],
1373 size_t __accept_len);
1375 __STRING_INLINE size_t
1376 __strspn_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1378 register unsigned long int __d0, __d1, __d2;
1379 register __const char *__res;
1380 __asm__ __volatile__
1381 ("cld\n"
1382 "1:\n\t"
1383 "lodsb\n\t"
1384 "testb %%al,%%al\n\t"
1385 "je 2f\n\t"
1386 "movl %1,%%edi\n\t"
1387 "movl %6,%%ecx\n\t"
1388 "repne; scasb\n\t"
1389 "je 1b\n"
1390 "2:"
1391 : "=S" (__res), "=&d" (__d0), "=&c" (__d1), "=&D" (__d2)
1392 : "0" (__s), "1" (__accept), "g" (__accept_len)
1393 : "cc");
1394 return (__res - 1) - __s;
1397 __STRING_INLINE size_t __strspn_g (__const char *__s, __const char *__accept);
1398 #ifdef __PIC__
1400 __STRING_INLINE size_t
1401 __strspn_g (__const char *__s, __const char *__accept)
1403 register unsigned long int __d0, __d1, __d2;
1404 register __const char *__res;
1405 __asm__ __volatile__
1406 ("pushl %%ebx\n\t"
1407 "cld\n\t"
1408 "repne; scasb\n\t"
1409 "notl %%ecx\n\t"
1410 "leal -1(%%ecx),%%ebx\n"
1411 "1:\n\t"
1412 "lodsb\n\t"
1413 "testb %%al,%%al\n\t"
1414 "je 2f\n\t"
1415 "movl %%edx,%%edi\n\t"
1416 "movl %%ebx,%%ecx\n\t"
1417 "repne; scasb\n\t"
1418 "je 1b\n"
1419 "2:\n\t"
1420 "popl %%ebx"
1421 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1422 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept)
1423 : "cc");
1424 return (__res - 1) - __s;
1426 #else
1427 __STRING_INLINE size_t
1428 __strspn_g (__const char *__s, __const char *__accept)
1430 register unsigned long int __d0, __d1, __d2, __d3;
1431 register __const char *__res;
1432 __asm__ __volatile__
1433 ("cld\n\t"
1434 "repne; scasb\n\t"
1435 "notl %%ecx\n\t"
1436 "leal -1(%%ecx),%%edx\n"
1437 "1:\n\t"
1438 "lodsb\n\t"
1439 "testb %%al,%%al\n\t"
1440 "je 2f\n\t"
1441 "movl %%ebx,%%edi\n\t"
1442 "movl %%edx,%%ecx\n\t"
1443 "repne; scasb\n\t"
1444 "je 1b\n"
1445 "2:"
1446 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&d" (__d3)
1447 : "0" (__s), "1" (0), "2" (0xffffffff), "3" (__accept), "b" (__accept)
1448 : "cc");
1449 return (__res - 1) - __s;
1451 #endif
1454 /* Find the first occurrence in S of any character in ACCEPT. */
1455 #define _HAVE_STRING_ARCH_strpbrk 1
1456 #define strpbrk(s, accept) \
1457 (__extension__ (__builtin_constant_p (accept) && sizeof ((accept)[0]) == 1 \
1458 ? ((accept)[0] == '\0' \
1459 ? NULL \
1460 : ((accept)[1] == '\0' \
1461 ? strchr (s, (accept)[0]) \
1462 : __strpbrk_cg (s, accept, strlen (accept)))) \
1463 : __strpbrk_g (s, accept)))
1465 __STRING_INLINE char *__strpbrk_cg (__const char *__s, __const char __accept[],
1466 size_t __accept_len);
1468 __STRING_INLINE char *
1469 __strpbrk_cg (__const char *__s, __const char __accept[], size_t __accept_len)
1471 register unsigned long int __d0, __d1, __d2;
1472 register char *__res;
1473 __asm__ __volatile__
1474 ("cld\n"
1475 "1:\n\t"
1476 "lodsb\n\t"
1477 "testb %%al,%%al\n\t"
1478 "je 2f\n\t"
1479 "movl %5,%%edi\n\t"
1480 "movl %6,%%ecx\n\t"
1481 "repne; scasb\n\t"
1482 "jne 1b\n\t"
1483 "decl %0\n\t"
1484 "jmp 3f\n"
1485 "2:\n\t"
1486 "xorl %0,%0\n"
1487 "3:"
1488 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1489 : "0" (__s), "d" (__accept), "g" (__accept_len)
1490 : "cc");
1491 return __res;
1494 __STRING_INLINE char *__strpbrk_g (__const char *__s, __const char *__accept);
1495 #ifdef __PIC__
1497 __STRING_INLINE char *
1498 __strpbrk_g (__const char *__s, __const char *__accept)
1500 register unsigned long int __d0, __d1, __d2;
1501 register char *__res;
1502 __asm__ __volatile__
1503 ("pushl %%ebx\n\t"
1504 "movl %%edx,%%edi\n\t"
1505 "cld\n\t"
1506 "repne; scasb\n\t"
1507 "notl %%ecx\n\t"
1508 "leal -1(%%ecx),%%ebx\n"
1509 "1:\n\t"
1510 "lodsb\n\t"
1511 "testb %%al,%%al\n\t"
1512 "je 2f\n\t"
1513 "movl %%edx,%%edi\n\t"
1514 "movl %%ebx,%%ecx\n\t"
1515 "repne; scasb\n\t"
1516 "jne 1b\n\t"
1517 "decl %0\n\t"
1518 "jmp 3f\n"
1519 "2:\n\t"
1520 "xorl %0,%0\n"
1521 "3:\n\t"
1522 "popl %%ebx"
1523 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
1524 : "d" (__accept), "0" (__s), "1" (0), "2" (0xffffffff)
1525 : "cc");
1526 return __res;
1528 #else
1529 __STRING_INLINE char *
1530 __strpbrk_g (__const char *__s, __const char *__accept)
1532 register unsigned long int __d0, __d1, __d2, __d3;
1533 register char *__res;
1534 __asm__ __volatile__
1535 ("movl %%ebx,%%edi\n\t"
1536 "cld\n\t"
1537 "repne; scasb\n\t"
1538 "notl %%ecx\n\t"
1539 "leal -1(%%ecx),%%edx\n"
1540 "1:\n\t"
1541 "lodsb\n\t"
1542 "testb %%al,%%al\n\t"
1543 "je 2f\n\t"
1544 "movl %%ebx,%%edi\n\t"
1545 "movl %%edx,%%ecx\n\t"
1546 "repne; scasb\n\t"
1547 "jne 1b\n\t"
1548 "decl %0\n\t"
1549 "jmp 3f\n"
1550 "2:\n\t"
1551 "xorl %0,%0\n"
1552 "3:"
1553 : "=S" (__res), "=&a" (__d0), "=&c" (__d1), "=&d" (__d2), "=&D" (__d3)
1554 : "0" (__s), "1" (0), "2" (0xffffffff), "b" (__accept)
1555 : "cc");
1556 return __res;
1558 #endif
1561 /* Find the first occurrence of NEEDLE in HAYSTACK. */
1562 #define _HAVE_STRING_ARCH_strstr 1
1563 #define strstr(haystack, needle) \
1564 (__extension__ (__builtin_constant_p (needle) && sizeof ((needle)[0]) == 1 \
1565 ? ((needle)[0] == '\0' \
1566 ? haystack \
1567 : ((needle)[1] == '\0' \
1568 ? strchr (haystack, (needle)[0]) \
1569 : __strstr_cg (haystack, needle, strlen (needle)))) \
1570 : __strstr_g (haystack, needle)))
1572 /* Please note that this function need not handle NEEDLEs with a
1573 length shorter than two. */
1574 __STRING_INLINE char *__strstr_cg (__const char *__haystack, __const char __needle[],
1575 size_t __needle_len);
1577 __STRING_INLINE char *
1578 __strstr_cg (__const char *__haystack, __const char __needle[],
1579 size_t __needle_len)
1581 register unsigned long int __d0, __d1, __d2;
1582 register char *__res;
1583 __asm__ __volatile__
1584 ("cld\n" \
1585 "1:\n\t"
1586 "movl %6,%%edi\n\t"
1587 "movl %5,%%eax\n\t"
1588 "movl %4,%%ecx\n\t"
1589 "repe; cmpsb\n\t"
1590 "je 2f\n\t"
1591 "cmpb $0,-1(%%esi)\n\t"
1592 "leal 1(%%eax),%5\n\t"
1593 "jne 1b\n\t"
1594 "xorl %%eax,%%eax\n"
1595 "2:"
1596 : "=a" (__res), "=&S" (__d0), "=&D" (__d1), "=&c" (__d2)
1597 : "g" (__needle_len), "1" (__haystack), "d" (__needle)
1598 : "cc");
1599 return __res;
1602 __STRING_INLINE char *__strstr_g (__const char *__haystack, __const char *__needle);
1603 #ifdef __PIC__
1605 __STRING_INLINE char *
1606 __strstr_g (__const char *__haystack, __const char *__needle)
1608 register unsigned long int __d0, __d1, __d2;
1609 register char *__res;
1610 __asm__ __volatile__
1611 ("cld\n\t"
1612 "repne; scasb\n\t"
1613 "notl %%ecx\n\t"
1614 "pushl %%ebx\n\t"
1615 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1616 "movl %%ecx,%%ebx\n"
1617 "1:\n\t"
1618 "movl %%edx,%%edi\n\t"
1619 "movl %%esi,%%eax\n\t"
1620 "movl %%ebx,%%ecx\n\t"
1621 "repe; cmpsb\n\t"
1622 "je 2f\n\t" /* also works for empty string, see above */
1623 "cmpb $0,-1(%%esi)\n\t"
1624 "leal 1(%%eax),%%esi\n\t"
1625 "jne 1b\n\t"
1626 "xorl %%eax,%%eax\n"
1627 "2:\n\t"
1628 "popl %%ebx"
1629 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
1630 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1631 "d" (__needle)
1632 : "cc");
1633 return __res;
1635 #else
1636 __STRING_INLINE char *
1637 __strstr_g (__const char *__haystack, __const char *__needle)
1639 register unsigned long int __d0, __d1, __d2, __d3;
1640 register char *__res;
1641 __asm__ __volatile__
1642 ("cld\n\t"
1643 "repne; scasb\n\t"
1644 "notl %%ecx\n\t"
1645 "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */
1646 "movl %%ecx,%%edx\n"
1647 "1:\n\t"
1648 "movl %%ebx,%%edi\n\t"
1649 "movl %%esi,%%eax\n\t"
1650 "movl %%edx,%%ecx\n\t"
1651 "repe; cmpsb\n\t"
1652 "je 2f\n\t" /* also works for empty string, see above */
1653 "cmpb $0,-1(%%esi)\n\t"
1654 "leal 1(%%eax),%%esi\n\t"
1655 "jne 1b\n\t"
1656 "xorl %%eax,%%eax\n"
1657 "2:"
1658 : "=a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&d" (__d3)
1659 : "0" (0), "1" (0xffffffff), "2" (__haystack), "3" (__needle),
1660 "b" (__needle)
1661 : "cc");
1662 return __res;
1664 #endif
1667 /* Bit find functions. We define only the i686 version since for the other
1668 processors gcc generates good code. */
1669 #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED
1670 # ifdef __i686__
1671 # define _HAVE_STRING_ARCH_ffs 1
1672 # define ffs(word) (__builtin_constant_p (word) \
1673 ? __builtin_ffs (word) \
1674 : ({ int __cnt, __tmp; \
1675 __asm__ __volatile__ \
1676 ("bsfl %2,%0\n\t" \
1677 "cmovel %1,%0" \
1678 : "=&r" (__cnt), "=r" (__tmp) \
1679 : "rm" (word), "1" (-1)); \
1680 __cnt + 1; }))
1682 # ifndef ffsl
1683 # define ffsl(word) ffs(word)
1684 # endif
1685 # endif /* i686 */
1686 #endif /* BSD || X/Open */
1688 #undef __STRING_INLINE
1690 #endif /* use string inlines && GNU CC */