|
|
1.1 ! root 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 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) ! 550: :"c" (s),"d" (count) ! 551: :"dx"); ! 552: return __res; ! 553: } ! 554: /* end of additional stuff */ ! 555: ! 556: /* ! 557: * This looks horribly ugly, but the compiler can optimize it totally, ! 558: * as we by now know that both pattern and count is constant.. ! 559: */ ! 560: extern inline void * __constant_c_and_count_memset(void * s, unsigned long pattern, size_t count) ! 561: { ! 562: switch (count) { ! 563: case 0: ! 564: return s; ! 565: case 1: ! 566: *(unsigned char *)s = pattern; ! 567: return s; ! 568: case 2: ! 569: *(unsigned short *)s = pattern; ! 570: return s; ! 571: case 3: ! 572: *(unsigned short *)s = pattern; ! 573: *(2+(unsigned char *)s) = pattern; ! 574: return s; ! 575: case 4: ! 576: *(unsigned long *)s = pattern; ! 577: return s; ! 578: } ! 579: #define COMMON(x) \ ! 580: __asm__("cld\n\t" \ ! 581: "rep ; stosl" \ ! 582: x \ ! 583: : /* no outputs */ \ ! 584: : "a" (pattern),"c" (count/4),"D" ((long) s) \ ! 585: : "cx","di","memory") ! 586: ! 587: switch (count % 4) { ! 588: case 0: COMMON(""); return s; ! 589: case 1: COMMON("\n\tstosb"); return s; ! 590: case 2: COMMON("\n\tstosw"); return s; ! 591: case 3: COMMON("\n\tstosw\n\tstosb"); return s; ! 592: } ! 593: #undef COMMON ! 594: } ! 595: ! 596: #define __constant_c_x_memset(s, c, count) \ ! 597: (__builtin_constant_p(count) ? \ ! 598: __constant_c_and_count_memset((s),(c),(count)) : \ ! 599: __constant_c_memset((s),(c),(count))) ! 600: ! 601: #define __memset(s, c, count) \ ! 602: (__builtin_constant_p(count) ? \ ! 603: __constant_count_memset((s),(c),(count)) : \ ! 604: __memset_generic((s),(c),(count))) ! 605: ! 606: #define __HAVE_ARCH_MEMSET ! 607: #define memset(s, c, count) \ ! 608: (__builtin_constant_p(c) ? \ ! 609: __constant_c_x_memset((s),(0x01010101UL*(unsigned char)c),(count)) : \ ! 610: __memset((s),(c),(count))) ! 611: ! 612: /* ! 613: * find the first occurrence of byte 'c', or 1 past the area if none ! 614: */ ! 615: #define __HAVE_ARCH_MEMSCAN ! 616: extern inline void * memscan(void * addr, int c, size_t size) ! 617: { ! 618: if (!size) ! 619: return addr; ! 620: __asm__("cld ! 621: repnz; scasb ! 622: jnz 1f ! 623: dec %%edi ! 624: 1: " ! 625: : "=D" (addr), "=c" (size) ! 626: : "0" (addr), "1" (size), "a" (c)); ! 627: return addr; ! 628: } ! 629: ! 630: #endif ! 631: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.