root/include/asm-i386/string.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. strcpy
  2. strncpy
  3. strcat
  4. strncat
  5. strcmp
  6. strncmp
  7. strchr
  8. strrchr
  9. strspn
  10. strcspn
  11. strpbrk
  12. strstr
  13. strlen
  14. strtok
  15. __memcpy
  16. __constant_memcpy
  17. memmove
  18. memchr
  19. __memset_generic
  20. __constant_c_memset
  21. strnlen
  22. __constant_c_and_count_memset
  23. memscan

   1 #ifndef _I386_STRING_H_
   2 #define _I386_STRING_H_
   3 
   4 /*
   5  * On a 486 or Pentium, we are better off not using the
   6  * byte string operations. But on a 386 or a PPro the
   7  * byte string ops are faster than doing it by hand
   8  * (MUCH faster on a Pentium).
   9  *
  10  * Also, the byte strings actually work correctly. Forget
  11  * the i486 routines for now as they may be broken..
  12  */
  13 #if FIXED_486_STRING && (CPU == 486 || CPU == 586)
  14 #include <asm/string-486.h>
  15 #else
  16 
  17 /*
  18  * This string-include defines all string functions as inline
  19  * functions. Use gcc. It also assumes ds=es=data space, this should be
  20  * normal. Most of the string-functions are rather heavily hand-optimized,
  21  * see especially strtok,strstr,str[c]spn. They should work, but are not
  22  * very easy to understand. Everything is done entirely within the register
  23  * set, making the functions fast and clean. String instructions have been
  24  * used through-out, making for "slightly" unclear code :-)
  25  *
  26  *              Copyright (C) 1991, 1992 Linus Torvalds
  27  */
  28 
  29 #define __HAVE_ARCH_STRCPY
  30 extern inline char * strcpy(char * dest,const char *src)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32 __asm__ __volatile__(
  33         "cld\n"
  34         "1:\tlodsb\n\t"
  35         "stosb\n\t"
  36         "testb %%al,%%al\n\t"
  37         "jne 1b"
  38         : /* no output */
  39         :"S" (src),"D" (dest):"si","di","ax","memory");
  40 return dest;
  41 }
  42 
  43 #define __HAVE_ARCH_STRNCPY
  44 extern inline char * strncpy(char * dest,const char *src,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46 __asm__ __volatile__(
  47         "cld\n"
  48         "1:\tdecl %2\n\t"
  49         "js 2f\n\t"
  50         "lodsb\n\t"
  51         "stosb\n\t"
  52         "testb %%al,%%al\n\t"
  53         "jne 1b\n\t"
  54         "rep\n\t"
  55         "stosb\n"
  56         "2:"
  57         : /* no output */
  58         :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
  59 return dest;
  60 }
  61 
  62 #define __HAVE_ARCH_STRCAT
  63 extern inline char * strcat(char * dest,const char * src)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65 __asm__ __volatile__(
  66         "cld\n\t"
  67         "repne\n\t"
  68         "scasb\n\t"
  69         "decl %1\n"
  70         "1:\tlodsb\n\t"
  71         "stosb\n\t"
  72         "testb %%al,%%al\n\t"
  73         "jne 1b"
  74         : /* no output */
  75         :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
  76 return dest;
  77 }
  78 
  79 #define __HAVE_ARCH_STRNCAT
  80 extern inline char * strncat(char * dest,const char * src,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
  81 {
  82 __asm__ __volatile__(
  83         "cld\n\t"
  84         "repne\n\t"
  85         "scasb\n\t"
  86         "decl %1\n\t"
  87         "movl %4,%3\n"
  88         "1:\tdecl %3\n\t"
  89         "js 2f\n\t"
  90         "lodsb\n\t"
  91         "stosb\n\t"
  92         "testb %%al,%%al\n\t"
  93         "jne 1b\n"
  94         "2:\txorl %2,%2\n\t"
  95         "stosb"
  96         : /* no output */
  97         :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
  98         :"si","di","ax","cx","memory");
  99 return dest;
 100 }
 101 
 102 #define __HAVE_ARCH_STRCMP
 103 extern inline int strcmp(const char * cs,const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 104 {
 105 register int __res;
 106 __asm__ __volatile__(
 107         "cld\n"
 108         "1:\tlodsb\n\t"
 109         "scasb\n\t"
 110         "jne 2f\n\t"
 111         "testb %%al,%%al\n\t"
 112         "jne 1b\n\t"
 113         "xorl %%eax,%%eax\n\t"
 114         "jmp 3f\n"
 115         "2:\tsbbl %%eax,%%eax\n\t"
 116         "orb $1,%%eax\n"
 117         "3:"
 118         :"=a" (__res):"S" (cs),"D" (ct):"si","di");
 119 return __res;
 120 }
 121 
 122 #define __HAVE_ARCH_STRNCMP
 123 extern inline int strncmp(const char * cs,const char * ct,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 124 {
 125 register int __res;
 126 __asm__ __volatile__(
 127         "cld\n"
 128         "1:\tdecl %3\n\t"
 129         "js 2f\n\t"
 130         "lodsb\n\t"
 131         "scasb\n\t"
 132         "jne 3f\n\t"
 133         "testb %%al,%%al\n\t"
 134         "jne 1b\n"
 135         "2:\txorl %%eax,%%eax\n\t"
 136         "jmp 4f\n"
 137         "3:\tsbbl %%eax,%%eax\n\t"
 138         "orb $1,%%al\n"
 139         "4:"
 140         :"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
 141 return __res;
 142 }
 143 
 144 #define __HAVE_ARCH_STRCHR
 145 extern inline char * strchr(const char * s, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 146 {
 147 register char * __res;
 148 __asm__ __volatile__(
 149         "cld\n\t"
 150         "movb %%al,%%ah\n"
 151         "1:\tlodsb\n\t"
 152         "cmpb %%ah,%%al\n\t"
 153         "je 2f\n\t"
 154         "testb %%al,%%al\n\t"
 155         "jne 1b\n\t"
 156         "movl $1,%1\n"
 157         "2:\tmovl %1,%0\n\t"
 158         "decl %0"
 159         :"=a" (__res):"S" (s),"0" (c):"si");
 160 return __res;
 161 }
 162 
 163 #define __HAVE_ARCH_STRRCHR
 164 extern inline char * strrchr(const char * s, int c)
     /* [previous][next][first][last][top][bottom][index][help] */
 165 {
 166 register char * __res;
 167 __asm__ __volatile__(
 168         "cld\n\t"
 169         "movb %%al,%%ah\n"
 170         "1:\tlodsb\n\t"
 171         "cmpb %%ah,%%al\n\t"
 172         "jne 2f\n\t"
 173         "leal -1(%%esi),%0\n"
 174         "2:\ttestb %%al,%%al\n\t"
 175         "jne 1b"
 176         :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
 177 return __res;
 178 }
 179 
 180 #define __HAVE_ARCH_STRSPN
 181 extern inline size_t strspn(const char * cs, const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 182 {
 183 register char * __res;
 184 __asm__ __volatile__(
 185         "cld\n\t"
 186         "movl %4,%%edi\n\t"
 187         "repne\n\t"
 188         "scasb\n\t"
 189         "notl %%ecx\n\t"
 190         "decl %%ecx\n\t"
 191         "movl %%ecx,%%edx\n"
 192         "1:\tlodsb\n\t"
 193         "testb %%al,%%al\n\t"
 194         "je 2f\n\t"
 195         "movl %4,%%edi\n\t"
 196         "movl %%edx,%%ecx\n\t"
 197         "repne\n\t"
 198         "scasb\n\t"
 199         "je 1b\n"
 200         "2:\tdecl %0"
 201         :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
 202         :"ax","cx","dx","di");
 203 return __res-cs;
 204 }
 205 
 206 #define __HAVE_ARCH_STRCSPN
 207 extern inline size_t strcspn(const char * cs, const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 208 {
 209 register char * __res;
 210 __asm__ __volatile__(
 211         "cld\n\t"
 212         "movl %4,%%edi\n\t"
 213         "repne\n\t"
 214         "scasb\n\t"
 215         "notl %%ecx\n\t"
 216         "decl %%ecx\n\t"
 217         "movl %%ecx,%%edx\n"
 218         "1:\tlodsb\n\t"
 219         "testb %%al,%%al\n\t"
 220         "je 2f\n\t"
 221         "movl %4,%%edi\n\t"
 222         "movl %%edx,%%ecx\n\t"
 223         "repne\n\t"
 224         "scasb\n\t"
 225         "jne 1b\n"
 226         "2:\tdecl %0"
 227         :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
 228         :"ax","cx","dx","di");
 229 return __res-cs;
 230 }
 231 
 232 #define __HAVE_ARCH_STRPBRK
 233 extern inline char * strpbrk(const char * cs,const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 234 {
 235 register char * __res;
 236 __asm__ __volatile__(
 237         "cld\n\t"
 238         "movl %4,%%edi\n\t"
 239         "repne\n\t"
 240         "scasb\n\t"
 241         "notl %%ecx\n\t"
 242         "decl %%ecx\n\t"
 243         "movl %%ecx,%%edx\n"
 244         "1:\tlodsb\n\t"
 245         "testb %%al,%%al\n\t"
 246         "je 2f\n\t"
 247         "movl %4,%%edi\n\t"
 248         "movl %%edx,%%ecx\n\t"
 249         "repne\n\t"
 250         "scasb\n\t"
 251         "jne 1b\n\t"
 252         "decl %0\n\t"
 253         "jmp 3f\n"
 254         "2:\txorl %0,%0\n"
 255         "3:"
 256         :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
 257         :"ax","cx","dx","di");
 258 return __res;
 259 }
 260 
 261 #define __HAVE_ARCH_STRSTR
 262 extern inline char * strstr(const char * cs,const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 263 {
 264 register char * __res;
 265 __asm__ __volatile__(
 266         "cld\n\t" \
 267         "movl %4,%%edi\n\t"
 268         "repne\n\t"
 269         "scasb\n\t"
 270         "notl %%ecx\n\t"
 271         "decl %%ecx\n\t"        /* NOTE! This also sets Z if searchstring='' */
 272         "movl %%ecx,%%edx\n"
 273         "1:\tmovl %4,%%edi\n\t"
 274         "movl %%esi,%%eax\n\t"
 275         "movl %%edx,%%ecx\n\t"
 276         "repe\n\t"
 277         "cmpsb\n\t"
 278         "je 2f\n\t"             /* also works for empty string, see above */
 279         "xchgl %%eax,%%esi\n\t"
 280         "incl %%esi\n\t"
 281         "cmpb $0,-1(%%eax)\n\t"
 282         "jne 1b\n\t"
 283         "xorl %%eax,%%eax\n\t"
 284         "2:"
 285         :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
 286         :"cx","dx","di","si");
 287 return __res;
 288 }
 289 
 290 #define __HAVE_ARCH_STRLEN
 291 extern inline size_t strlen(const char * s)
     /* [previous][next][first][last][top][bottom][index][help] */
 292 {
 293 register int __res;
 294 __asm__ __volatile__(
 295         "cld\n\t"
 296         "repne\n\t"
 297         "scasb\n\t"
 298         "notl %0\n\t"
 299         "decl %0"
 300         :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
 301 return __res;
 302 }
 303 
 304 #define __HAVE_ARCH_STRTOK
 305 extern inline char * strtok(char * s,const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 306 {
 307 register char * __res;
 308 __asm__ __volatile__(
 309         "testl %1,%1\n\t"
 310         "jne 1f\n\t"
 311         "testl %0,%0\n\t"
 312         "je 8f\n\t"
 313         "movl %0,%1\n"
 314         "1:\txorl %0,%0\n\t"
 315         "movl $-1,%%ecx\n\t"
 316         "xorl %%eax,%%eax\n\t"
 317         "cld\n\t"
 318         "movl %4,%%edi\n\t"
 319         "repne\n\t"
 320         "scasb\n\t"
 321         "notl %%ecx\n\t"
 322         "decl %%ecx\n\t"
 323         "je 7f\n\t"                     /* empty delimiter-string */
 324         "movl %%ecx,%%edx\n"
 325         "2:\tlodsb\n\t"
 326         "testb %%al,%%al\n\t"
 327         "je 7f\n\t"
 328         "movl %4,%%edi\n\t"
 329         "movl %%edx,%%ecx\n\t"
 330         "repne\n\t"
 331         "scasb\n\t"
 332         "je 2b\n\t"
 333         "decl %1\n\t"
 334         "cmpb $0,(%1)\n\t"
 335         "je 7f\n\t"
 336         "movl %1,%0\n"
 337         "3:\tlodsb\n\t"
 338         "testb %%al,%%al\n\t"
 339         "je 5f\n\t"
 340         "movl %4,%%edi\n\t"
 341         "movl %%edx,%%ecx\n\t"
 342         "repne\n\t"
 343         "scasb\n\t"
 344         "jne 3b\n\t"
 345         "decl %1\n\t"
 346         "cmpb $0,(%1)\n\t"
 347         "je 5f\n\t"
 348         "movb $0,(%1)\n\t"
 349         "incl %1\n\t"
 350         "jmp 6f\n"
 351         "5:\txorl %1,%1\n"
 352         "6:\tcmpb $0,(%0)\n\t"
 353         "jne 7f\n\t"
 354         "xorl %0,%0\n"
 355         "7:\ttestl %0,%0\n\t"
 356         "jne 8f\n\t"
 357         "movl %0,%1\n"
 358         "8:"
 359         :"=b" (__res),"=S" (___strtok)
 360         :"0" (___strtok),"1" (s),"g" (ct)
 361         :"ax","cx","dx","di","memory");
 362 return __res;
 363 }
 364 
 365 extern inline void * __memcpy(void * to, const void * from, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 366 {
 367 __asm__ __volatile__(
 368         "cld\n\t"
 369         "rep ; movsl\n\t"
 370         "testb $2,%b1\n\t"
 371         "je 1f\n\t"
 372         "movsw\n"
 373         "1:\ttestb $1,%b1\n\t"
 374         "je 2f\n\t"
 375         "movsb\n"
 376         "2:"
 377         : /* no output */
 378         :"c" (n/4), "q" (n),"D" ((long) to),"S" ((long) from)
 379         : "cx","di","si","memory");
 380 return (to);
 381 }
 382 
 383 /*
 384  * This looks horribly ugly, but the compiler can optimize it totally,
 385  * as the count is constant.
 386  */
 387 extern inline void * __constant_memcpy(void * to, const void * from, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 388 {
 389         switch (n) {
 390                 case 0:
 391                         return to;
 392                 case 1:
 393                         *(unsigned char *)to = *(const unsigned char *)from;
 394                         return to;
 395                 case 2:
 396                         *(unsigned short *)to = *(const unsigned short *)from;
 397                         return to;
 398                 case 3:
 399                         *(unsigned short *)to = *(const unsigned short *)from;
 400                         *(2+(unsigned char *)to) = *(2+(const unsigned char *)from);
 401                         return to;
 402                 case 4:
 403                         *(unsigned long *)to = *(const unsigned long *)from;
 404                         return to;
 405                 case 8:
 406                         *(unsigned long *)to = *(const unsigned long *)from;
 407                         *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
 408                         return to;
 409                 case 12:
 410                         *(unsigned long *)to = *(const unsigned long *)from;
 411                         *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
 412                         *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
 413                         return to;
 414                 case 16:
 415                         *(unsigned long *)to = *(const unsigned long *)from;
 416                         *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
 417                         *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
 418                         *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
 419                         return to;
 420                 case 20:
 421                         *(unsigned long *)to = *(const unsigned long *)from;
 422                         *(1+(unsigned long *)to) = *(1+(const unsigned long *)from);
 423                         *(2+(unsigned long *)to) = *(2+(const unsigned long *)from);
 424                         *(3+(unsigned long *)to) = *(3+(const unsigned long *)from);
 425                         *(4+(unsigned long *)to) = *(4+(const unsigned long *)from);
 426                         return to;
 427         }
 428 #define COMMON(x) \
 429 __asm__("cld\n\t" \
 430         "rep ; movsl" \
 431         x \
 432         : /* no outputs */ \
 433         : "c" (n/4),"D" ((long) to),"S" ((long) from) \
 434         : "cx","di","si","memory");
 435 
 436         switch (n % 4) {
 437                 case 0: COMMON(""); return to;
 438                 case 1: COMMON("\n\tmovsb"); return to;
 439                 case 2: COMMON("\n\tmovsw"); return to;
 440                 case 3: COMMON("\n\tmovsw\n\tmovsb"); return to;
 441         }
 442 #undef COMMON
 443 }
 444 
 445 #define __HAVE_ARCH_MEMCPY
 446 #define memcpy(t, f, n) \
 447 (__builtin_constant_p(n) ? \
 448  __constant_memcpy((t),(f),(n)) : \
 449  __memcpy((t),(f),(n)))
 450 
 451 #define __HAVE_ARCH_MEMMOVE
 452 extern inline void * memmove(void * dest,const void * src, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 453 {
 454 if (dest<src)
 455 __asm__ __volatile__(
 456         "cld\n\t"
 457         "rep\n\t"
 458         "movsb"
 459         : /* no output */
 460         :"c" (n),"S" (src),"D" (dest)
 461         :"cx","si","di");
 462 else
 463 __asm__ __volatile__(
 464         "std\n\t"
 465         "rep\n\t"
 466         "movsb\n\t"
 467         "cld"
 468         : /* no output */
 469         :"c" (n),
 470          "S" (n-1+(const char *)src),
 471          "D" (n-1+(char *)dest)
 472         :"cx","si","di","memory");
 473 return dest;
 474 }
 475 
 476 #define memcmp __builtin_memcmp
 477 
 478 #define __HAVE_ARCH_MEMCHR
 479 extern inline void * memchr(const void * cs,int c,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 480 {
 481 register void * __res;
 482 if (!count)
 483         return NULL;
 484 __asm__ __volatile__(
 485         "cld\n\t"
 486         "repne\n\t"
 487         "scasb\n\t"
 488         "je 1f\n\t"
 489         "movl $1,%0\n"
 490         "1:\tdecl %0"
 491         :"=D" (__res):"a" (c),"D" (cs),"c" (count)
 492         :"cx");
 493 return __res;
 494 }
 495 
 496 extern inline void * __memset_generic(void * s, char c,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 497 {
 498 __asm__ __volatile__(
 499         "cld\n\t"
 500         "rep\n\t"
 501         "stosb"
 502         : /* no output */
 503         :"a" (c),"D" (s),"c" (count)
 504         :"cx","di","memory");
 505 return s;
 506 }
 507 
 508 /* we might want to write optimized versions of these later */
 509 #define __constant_count_memset(s,c,count) __memset_generic((s),(c),(count))
 510 
 511 /*
 512  * memset(x,0,y) is a reasonably common thing to do, so we want to fill
 513  * things 32 bits at a time even when we don't know the size of the
 514  * area at compile-time..
 515  */
 516 extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 517 {
 518 __asm__ __volatile__(
 519         "cld\n\t"
 520         "rep ; stosl\n\t"
 521         "testb $2,%b1\n\t"
 522         "je 1f\n\t"
 523         "stosw\n"
 524         "1:\ttestb $1,%b1\n\t"
 525         "je 2f\n\t"
 526         "stosb\n"
 527         "2:"
 528         : /* no output */
 529         :"a" (c), "q" (count), "c" (count/4), "D" ((long) s)
 530         :"cx","di","memory");
 531 return (s);     
 532 }
 533 
 534 /* Added by Gertjan van Wingerde to make minix and sysv module work */
 535 #define __HAVE_ARCH_STRNLEN
 536 extern inline size_t strnlen(const char * s, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 537 {
 538 register int __res;
 539 __asm__ __volatile__(
 540         "movl %1,%0\n\t"
 541         "jmp 2f\n"
 542         "1:\tcmpb $0,(%0)\n\t"
 543         "je 3f\n\t"
 544         "incl %0\n"
 545         "2:\tdecl %2\n\t"
 546         "cmpl $-1,%2\n\t"
 547         "jne 1b\n"
 548         "3:\tsubl %1,%0"
 549         :"=a" (__res):"c" (s),"d" (count));
 550 return __res;
 551 }
 552 /* end of additional stuff */
 553 
 554 /*
 555  * This looks horribly ugly, but the compiler can optimize it totally,
 556  * as we by now know that both pattern and count is constant..
 557  */
 558 extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 559 {
 560         switch (count) {
 561                 case 0:
 562                         return s;
 563                 case 1:
 564                         *(unsigned char *)s = pattern;
 565                         return s;
 566                 case 2:
 567                         *(unsigned short *)s = pattern;
 568                         return s;
 569                 case 3:
 570                         *(unsigned short *)s = pattern;
 571                         *(2+(unsigned char *)s) = pattern;
 572                         return s;
 573                 case 4:
 574                         *(unsigned long *)s = pattern;
 575                         return s;
 576         }
 577 #define COMMON(x) \
 578 __asm__("cld\n\t" \
 579         "rep ; stosl" \
 580         x \
 581         : /* no outputs */ \
 582         : "a" (pattern),"c" (count/4),"D" ((long) s) \
 583         : "cx","di","memory")
 584 
 585         switch (count % 4) {
 586                 case 0: COMMON(""); return s;
 587                 case 1: COMMON("\n\tstosb"); return s;
 588                 case 2: COMMON("\n\tstosw"); return s;
 589                 case 3: COMMON("\n\tstosw\n\tstosb"); return s;
 590         }
 591 #undef COMMON
 592 }
 593 
 594 #define __constant_c_x_memset(s, c, count) \
 595 (__builtin_constant_p(count) ? \
 596  __constant_c_and_count_memset((s),(c),(count)) : \
 597  __constant_c_memset((s),(c),(count)))
 598 
 599 #define __memset(s, c, count) \
 600 (__builtin_constant_p(count) ? \
 601  __constant_count_memset((s),(c),(count)) : \
 602  __memset_generic((s),(c),(count)))
 603 
 604 #define __HAVE_ARCH_MEMSET
 605 #define memset(s, c, count) \
 606 (__builtin_constant_p(c) ? \
 607  __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \
 608  __memset((s),(c),(count)))
 609 
 610 /*
 611  * find the first occurrence of byte 'c', or 1 past the area if none
 612  */
 613 #define __HAVE_ARCH_MEMSCAN
 614 extern inline void * memscan(void * addr, int c, size_t size)
     /* [previous][next][first][last][top][bottom][index][help] */
 615 {
 616         if (!size)
 617                 return addr;
 618         __asm__("cld
 619                 repnz; scasb
 620                 jnz 1f
 621                 dec %%edi
 622 1:              "
 623                 : "=D" (addr), "=c" (size)
 624                 : "0" (addr), "1" (size), "a" (c));
 625         return addr;
 626 }
 627 
 628 #endif
 629 #endif

/* [previous][next][first][last][top][bottom][index][help] */