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