|
|
1.1 ! root 1: #ifndef _I386_STRING_I486_H_ ! 2: #define _I386_STRING_I486_H_ ! 3: ! 4: /* ! 5: * This string-include defines all string functions as inline ! 6: * functions. Use gcc. It also assumes ds=es=data space, this should be ! 7: * normal. Most of the string-functions are rather heavily hand-optimized, ! 8: * see especially strtok,strstr,str[c]spn. They should work, but are not ! 9: * very easy to understand. Everything is done entirely within the register ! 10: * set, making the functions fast and clean. ! 11: * ! 12: * Copyright (C) 1991, 1992 Linus Torvalds ! 13: * Revised and optimized for i486/pentium ! 14: * 1994/03/15 by Alberto Vignani/Davide Parodi @crf.it ! 15: * ! 16: * Split into 2 CPU specific files by Alan Cox to keep #ifdef noise down. ! 17: */ ! 18: ! 19: #define __HAVE_ARCH_STRCPY ! 20: extern inline char * strcpy(char * dest,const char *src) ! 21: { ! 22: register char *tmp= (char *)dest; ! 23: register char dummy; ! 24: __asm__ __volatile__( ! 25: "\n1:\t" ! 26: "movb (%0),%b2\n\t" ! 27: "incl %0\n\t" ! 28: "movb %b2,(%1)\n\t" ! 29: "incl %1\n\t" ! 30: "testb %b2,%b2\n\t" ! 31: "jne 1b" ! 32: :"=r" (src), "=r" (tmp), "=q" (dummy) ! 33: :"0" (src), "1" (tmp) ! 34: :"memory"); ! 35: return dest; ! 36: } ! 37: ! 38: #define __HAVE_ARCH_STRNCPY ! 39: extern inline char * strncpy(char * dest,const char *src,size_t count) ! 40: { ! 41: register char *tmp= (char *)dest; ! 42: register char dummy; ! 43: if (count) { ! 44: __asm__ __volatile__( ! 45: "\n1:\t" ! 46: "movb (%0),%b2\n\t" ! 47: "incl %0\n\t" ! 48: "movb %b2,(%1)\n\t" ! 49: "incl %1\n\t" ! 50: "decl %3\n\t" ! 51: "je 3f\n\t" ! 52: "testb %b2,%b2\n\t" ! 53: "jne 1b\n\t" ! 54: "2:\tmovb %b2,(%1)\n\t" ! 55: "incl %1\n\t" ! 56: "decl %3\n\t" ! 57: "jne 2b\n\t" ! 58: "3:" ! 59: :"=r" (src), "=r" (tmp), "=q" (dummy), "=r" (count) ! 60: :"0" (src), "1" (tmp), "3" (count) ! 61: :"memory"); ! 62: } /* if (count) */ ! 63: return dest; ! 64: } ! 65: ! 66: #define __HAVE_ARCH_STRCAT ! 67: extern inline char * strcat(char * dest,const char * src) ! 68: { ! 69: register char *tmp = (char *)(dest-1); ! 70: register char dummy; ! 71: __asm__ __volatile__( ! 72: "\n1:\tincl %1\n\t" ! 73: "cmpb $0,(%1)\n\t" ! 74: "jne 1b\n" ! 75: "2:\tmovb (%2),%b0\n\t" ! 76: "incl %2\n\t" ! 77: "movb %b0,(%1)\n\t" ! 78: "incl %1\n\t" ! 79: "testb %b0,%b0\n\t" ! 80: "jne 2b\n" ! 81: :"=q" (dummy), "=r" (tmp), "=r" (src) ! 82: :"1" (tmp), "2" (src) ! 83: :"memory"); ! 84: return dest; ! 85: } ! 86: ! 87: #define __HAVE_ARCH_STRNCAT ! 88: extern inline char * strncat(char * dest,const char * src,size_t count) ! 89: { ! 90: register char *tmp = (char *)(dest-1); ! 91: register char dummy; ! 92: __asm__ __volatile__( ! 93: "\n1:\tincl %1\n\t" ! 94: "cmpb $0,(%1)\n\t" ! 95: "jne 1b\n" ! 96: "2:\tdecl %3\n\t" ! 97: "js 3f\n\t" ! 98: "movb (%2),%b0\n\t" ! 99: "incl %2\n\t" ! 100: "movb %b0,(%1)\n\t" ! 101: "incl %1\n\t" ! 102: "testb %b0,%b0\n\t" ! 103: "jne 2b\n" ! 104: "3:\txorb %b0,%b0\n\t" ! 105: "movb %b0,(%1)\n\t" ! 106: :"=q" (dummy), "=r" (tmp), "=r" (src), "=r" (count) ! 107: :"1" (tmp), "2" (src), "3" (count) ! 108: :"memory"); ! 109: return dest; ! 110: } ! 111: ! 112: #define __HAVE_ARCH_STRCMP ! 113: extern inline int strcmp(const char * cs,const char * ct) ! 114: { ! 115: register int __res; ! 116: __asm__ __volatile__( ! 117: "\n1:\tmovb (%1),%b0\n\t" ! 118: "incl %1\n\t" ! 119: "cmpb %b0,(%2)\n\t" ! 120: "jne 2f\n\t" ! 121: "incl %2\n\t" ! 122: "testb %b0,%b0\n\t" ! 123: "jne 1b\n\t" ! 124: "xorl %k0,%k0\n\t" ! 125: "jmp 3f\n" ! 126: "2:\tmovl $1,%k0\n\t" ! 127: "jb 3f\n\t" ! 128: "negl %k0\n" ! 129: "3:" ! 130: :"=q" (__res), "=r" (cs), "=r" (ct) ! 131: :"1" (cs), "2" (ct) ! 132: : "memory" ); ! 133: return __res; ! 134: } ! 135: ! 136: #define __HAVE_ARCH_STRNCMP ! 137: extern inline int strncmp(const char * cs,const char * ct,size_t count) ! 138: { ! 139: register int __res; ! 140: __asm__ __volatile__( ! 141: "\n1:\tdecl %3\n\t" ! 142: "js 2f\n\t" ! 143: "movb (%1),%b0\n\t" ! 144: "incl %1\n\t" ! 145: "cmpb %b0,(%2)\n\t" ! 146: "jne 3f\n\t" ! 147: "incl %2\n\t" ! 148: "testb %b0,%b0\n\t" ! 149: "jne 1b\n" ! 150: "2:\txorl %k0,%k0\n\t" ! 151: "jmp 4f\n" ! 152: "3:\tmovl $1,%k0\n\t" ! 153: "jb 4f\n\t" ! 154: "negl %k0\n" ! 155: "4:" ! 156: :"=q" (__res), "=r" (cs), "=r" (ct), "=r" (count) ! 157: :"1" (cs), "2" (ct), "3" (count)); ! 158: return __res; ! 159: } ! 160: ! 161: #define __HAVE_ARCH_STRCHR ! 162: extern inline char * strchr(const char * s, int c) ! 163: { ! 164: register char * __res; ! 165: __asm__ __volatile__( ! 166: "movb %%al,%%ah\n" ! 167: "1:\tmovb (%1),%%al\n\t" ! 168: "cmpb %%ah,%%al\n\t" ! 169: "je 2f\n\t" ! 170: "incl %1\n\t" ! 171: "testb %%al,%%al\n\t" ! 172: "jne 1b\n\t" ! 173: "xorl %1,%1\n" ! 174: "2:\tmovl %1,%0\n\t" ! 175: :"=a" (__res), "=r" (s) ! 176: :"0" (c), "1" (s)); ! 177: return __res; ! 178: } ! 179: ! 180: #define __HAVE_ARCH_STRRCHR ! 181: extern inline char * strrchr(const char * s, int c) ! 182: { ! 183: register char * __res; ! 184: __asm__ __volatile__( ! 185: "cld\n\t" ! 186: "movb %%al,%%ah\n" ! 187: "1:\tlodsb\n\t" ! 188: "cmpb %%ah,%%al\n\t" ! 189: "jne 2f\n\t" ! 190: "leal -1(%%esi),%0\n" ! 191: "2:\ttestb %%al,%%al\n\t" ! 192: "jne 1b" ! 193: :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si"); ! 194: return __res; ! 195: } ! 196: ! 197: #define __HAVE_ARCH_STRSPN ! 198: extern inline size_t strspn(const char * cs, const char * ct) ! 199: { ! 200: register char * __res; ! 201: __asm__ __volatile__( ! 202: "cld\n\t" ! 203: "movl %4,%%edi\n\t" ! 204: "repne\n\t" ! 205: "scasb\n\t" ! 206: "notl %%ecx\n\t" ! 207: "decl %%ecx\n\t" ! 208: "movl %%ecx,%%edx\n" ! 209: "1:\tlodsb\n\t" ! 210: "testb %%al,%%al\n\t" ! 211: "je 2f\n\t" ! 212: "movl %4,%%edi\n\t" ! 213: "movl %%edx,%%ecx\n\t" ! 214: "repne\n\t" ! 215: "scasb\n\t" ! 216: "je 1b\n" ! 217: "2:\tdecl %0" ! 218: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) ! 219: :"ax","cx","dx","di"); ! 220: return __res-cs; ! 221: } ! 222: ! 223: #define __HAVE_ARCH_STRCSPN ! 224: extern inline size_t strcspn(const char * cs, const char * ct) ! 225: { ! 226: register char * __res; ! 227: __asm__ __volatile__( ! 228: "cld\n\t" ! 229: "movl %4,%%edi\n\t" ! 230: "repne\n\t" ! 231: "scasb\n\t" ! 232: "notl %%ecx\n\t" ! 233: "decl %%ecx\n\t" ! 234: "movl %%ecx,%%edx\n" ! 235: "1:\tlodsb\n\t" ! 236: "testb %%al,%%al\n\t" ! 237: "je 2f\n\t" ! 238: "movl %4,%%edi\n\t" ! 239: "movl %%edx,%%ecx\n\t" ! 240: "repne\n\t" ! 241: "scasb\n\t" ! 242: "jne 1b\n" ! 243: "2:\tdecl %0" ! 244: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) ! 245: :"ax","cx","dx","di"); ! 246: return __res-cs; ! 247: } ! 248: ! 249: #define __HAVE_ARCH_STRPBRK ! 250: extern inline char * strpbrk(const char * cs,const char * ct) ! 251: { ! 252: register char * __res; ! 253: __asm__ __volatile__( ! 254: "cld\n\t" ! 255: "movl %4,%%edi\n\t" ! 256: "repne\n\t" ! 257: "scasb\n\t" ! 258: "notl %%ecx\n\t" ! 259: "decl %%ecx\n\t" ! 260: "movl %%ecx,%%edx\n" ! 261: "1:\tlodsb\n\t" ! 262: "testb %%al,%%al\n\t" ! 263: "je 2f\n\t" ! 264: "movl %4,%%edi\n\t" ! 265: "movl %%edx,%%ecx\n\t" ! 266: "repne\n\t" ! 267: "scasb\n\t" ! 268: "jne 1b\n\t" ! 269: "decl %0\n\t" ! 270: "jmp 3f\n" ! 271: "2:\txorl %0,%0\n" ! 272: "3:" ! 273: :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) ! 274: :"ax","cx","dx","di"); ! 275: return __res; ! 276: } ! 277: ! 278: #define __HAVE_ARCH_STRSTR ! 279: extern inline char * strstr(const char * cs,const char * ct) ! 280: { ! 281: register char * __res; ! 282: __asm__ __volatile__( ! 283: "cld\n\t" \ ! 284: "movl %4,%%edi\n\t" ! 285: "repne\n\t" ! 286: "scasb\n\t" ! 287: "notl %%ecx\n\t" ! 288: "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ ! 289: "movl %%ecx,%%edx\n" ! 290: "1:\tmovl %4,%%edi\n\t" ! 291: "movl %%esi,%%eax\n\t" ! 292: "movl %%edx,%%ecx\n\t" ! 293: "repe\n\t" ! 294: "cmpsb\n\t" ! 295: "je 2f\n\t" /* also works for empty string, see above */ ! 296: "xchgl %%eax,%%esi\n\t" ! 297: "incl %%esi\n\t" ! 298: "cmpb $0,-1(%%eax)\n\t" ! 299: "jne 1b\n\t" ! 300: "xorl %%eax,%%eax\n\t" ! 301: "2:" ! 302: :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) ! 303: :"cx","dx","di","si"); ! 304: return __res; ! 305: } ! 306: ! 307: #define __HAVE_ARCH_STRLEN ! 308: extern inline size_t strlen(const char * s) ! 309: { ! 310: /* ! 311: * slightly slower on a 486, but with better chances of ! 312: * register allocation ! 313: */ ! 314: register char dummy, *tmp= (char *)s; ! 315: __asm__ __volatile__( ! 316: "\n1:\t" ! 317: "movb\t(%0),%1\n\t" ! 318: "incl\t%0\n\t" ! 319: "testb\t%1,%1\n\t" ! 320: "jne\t1b" ! 321: :"=r" (tmp),"=q" (dummy) ! 322: :"0" (s) ! 323: : "memory" ); ! 324: return (tmp-s-1); ! 325: } ! 326: ! 327: /* Added by Gertjan van Wingerde to make minix and sysv module work */ ! 328: #define __HAVE_ARCH_STRNLEN ! 329: extern inline size_t strnlen(const char * s, size_t count) ! 330: { ! 331: register int __res; ! 332: __asm__ __volatile__( ! 333: "movl %1,%0\n\t" ! 334: "jmp 2f\n" ! 335: "1:\tcmpb $0,(%0)\n\t" ! 336: "je 3f\n\t" ! 337: "incl %0\n" ! 338: "2:\tdecl %2\n\t" ! 339: "cmpl $-1,%2\n\t" ! 340: "jne 1b\n" ! 341: "3:\tsubl %1,%0" ! 342: :"=a" (__res) ! 343: :"c" (s),"d" (count) ! 344: :"dx"); ! 345: return __res; ! 346: } ! 347: /* end of additional stuff */ ! 348: ! 349: #define __HAVE_ARCH_STRTOK ! 350: extern inline char * strtok(char * s,const char * ct) ! 351: { ! 352: register char * __res; ! 353: __asm__ __volatile__( ! 354: "testl %1,%1\n\t" ! 355: "jne 1f\n\t" ! 356: "testl %0,%0\n\t" ! 357: "je 8f\n\t" ! 358: "movl %0,%1\n" ! 359: "1:\txorl %0,%0\n\t" ! 360: "movl $-1,%%ecx\n\t" ! 361: "xorl %%eax,%%eax\n\t" ! 362: "cld\n\t" ! 363: "movl %4,%%edi\n\t" ! 364: "repne\n\t" ! 365: "scasb\n\t" ! 366: "notl %%ecx\n\t" ! 367: "decl %%ecx\n\t" ! 368: "je 7f\n\t" /* empty delimiter-string */ ! 369: "movl %%ecx,%%edx\n" ! 370: "2:\tlodsb\n\t" ! 371: "testb %%al,%%al\n\t" ! 372: "je 7f\n\t" ! 373: "movl %4,%%edi\n\t" ! 374: "movl %%edx,%%ecx\n\t" ! 375: "repne\n\t" ! 376: "scasb\n\t" ! 377: "je 2b\n\t" ! 378: "decl %1\n\t" ! 379: "cmpb $0,(%1)\n\t" ! 380: "je 7f\n\t" ! 381: "movl %1,%0\n" ! 382: "3:\tlodsb\n\t" ! 383: "testb %%al,%%al\n\t" ! 384: "je 5f\n\t" ! 385: "movl %4,%%edi\n\t" ! 386: "movl %%edx,%%ecx\n\t" ! 387: "repne\n\t" ! 388: "scasb\n\t" ! 389: "jne 3b\n\t" ! 390: "decl %1\n\t" ! 391: "cmpb $0,(%1)\n\t" ! 392: "je 5f\n\t" ! 393: "movb $0,(%1)\n\t" ! 394: "incl %1\n\t" ! 395: "jmp 6f\n" ! 396: "5:\txorl %1,%1\n" ! 397: "6:\tcmpb $0,(%0)\n\t" ! 398: "jne 7f\n\t" ! 399: "xorl %0,%0\n" ! 400: "7:\ttestl %0,%0\n\t" ! 401: "jne 8f\n\t" ! 402: "movl %0,%1\n" ! 403: "8:" ! 404: :"=b" (__res),"=S" (___strtok) ! 405: :"0" (___strtok),"1" (s),"g" (ct) ! 406: :"ax","cx","dx","di","memory"); ! 407: return __res; ! 408: } ! 409: ! 410: #define __memcpy_c(d,s,count) \ ! 411: ((count%4==0) ? \ ! 412: __memcpy_by4((d),(s),(count)) : \ ! 413: ((count%2==0) ? \ ! 414: __memcpy_by2((d),(s),(count)) : \ ! 415: __memcpy_g((d),(s),(count)))) ! 416: ! 417: #define __HAVE_ARCH_MEMCPY ! 418: #define memcpy(d,s,count) \ ! 419: (count == 0 \ ! 420: ? d \ ! 421: : __builtin_constant_p(count) \ ! 422: ? __memcpy_c((d),(s),(count)) \ ! 423: : __memcpy_g((d),(s),(count))) ! 424: ! 425: /* ! 426: * These ought to get tweaked to do some cache priming. ! 427: */ ! 428: ! 429: extern inline void * __memcpy_by4(void * to, const void * from, size_t n) ! 430: { ! 431: register void *tmp = (void *)to; ! 432: register int dummy1,dummy2; ! 433: __asm__ __volatile__ ( ! 434: "\n1:\tmovl (%2),%0\n\t" ! 435: "addl $4,%2\n\t" ! 436: "movl %0,(%1)\n\t" ! 437: "addl $4,%1\n\t" ! 438: "decl %3\n\t" ! 439: "jnz 1b" ! 440: :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) ! 441: :"1" (tmp), "2" (from), "3" (n/4) ! 442: :"memory"); ! 443: return to; ! 444: } ! 445: ! 446: extern inline void * __memcpy_by2(void * to, const void * from, size_t n) ! 447: { ! 448: register void *tmp = (void *)to; ! 449: register int dummy1,dummy2; ! 450: __asm__ __volatile__ ( ! 451: "shrl $1,%3\n\t" ! 452: "jz 2f\n" /* only a word */ ! 453: "1:\tmovl (%2),%0\n\t" ! 454: "addl $4,%2\n\t" ! 455: "movl %0,(%1)\n\t" ! 456: "addl $4,%1\n\t" ! 457: "decl %3\n\t" ! 458: "jnz 1b\n" ! 459: "2:\tmovw (%2),%w0\n\t" ! 460: "movw %w0,(%1)" ! 461: :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) ! 462: :"1" (tmp), "2" (from), "3" (n/2) ! 463: :"memory"); ! 464: return to; ! 465: } ! 466: ! 467: extern inline void * __memcpy_g(void * to, const void * from, size_t n) ! 468: { ! 469: register void *tmp = (void *)to; ! 470: __asm__ __volatile__ ( ! 471: "cld\n\t" ! 472: "shrl $1,%%ecx\n\t" ! 473: "jnc 1f\n\t" ! 474: "movsb\n" ! 475: "1:\tshrl $1,%%ecx\n\t" ! 476: "jnc 2f\n\t" ! 477: "movsw\n" ! 478: "2:\trep\n\t" ! 479: "movsl" ! 480: : /* no output */ ! 481: :"c" (n),"D" ((long) tmp),"S" ((long) from) ! 482: :"cx","di","si","memory"); ! 483: return to; ! 484: } ! 485: ! 486: ! 487: #define __HAVE_ARCH_MEMMOVE ! 488: extern inline void * memmove(void * dest,const void * src, size_t n) ! 489: { ! 490: register void *tmp = (void *)dest; ! 491: if (dest<src) ! 492: __asm__ __volatile__ ( ! 493: "cld\n\t" ! 494: "rep\n\t" ! 495: "movsb" ! 496: : /* no output */ ! 497: :"c" (n),"S" (src),"D" (tmp) ! 498: :"cx","si","di"); ! 499: else ! 500: __asm__ __volatile__ ( ! 501: "std\n\t" ! 502: "rep\n\t" ! 503: "movsb\n\t" ! 504: "cld\n\t" ! 505: : /* no output */ ! 506: :"c" (n), "S" (n-1+(const char *)src), "D" (n-1+(char *)tmp) ! 507: :"cx","si","di","memory"); ! 508: return dest; ! 509: } ! 510: ! 511: extern inline int memcmp(const void * cs,const void * ct,size_t count) ! 512: { ! 513: register int __res; ! 514: __asm__ __volatile__( ! 515: "cld\n\t" ! 516: "repe\n\t" ! 517: "cmpsb\n\t" ! 518: "je 1f\n\t" ! 519: "sbbl %0,%0\n\t" ! 520: "orb $1,%b0\n" ! 521: "1:" ! 522: :"=abd" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count) ! 523: :"si","di","cx"); ! 524: return __res; ! 525: } ! 526: ! 527: #define __HAVE_ARCH_MEMCHR ! 528: extern inline void * memchr(const void * cs,int c,size_t count) ! 529: { ! 530: register void * __res; ! 531: if (!count) ! 532: return NULL; ! 533: __asm__ __volatile__( ! 534: "cld\n\t" ! 535: "repne\n\t" ! 536: "scasb\n\t" ! 537: "je 1f\n\t" ! 538: "movl $1,%0\n" ! 539: "1:\tdecl %0" ! 540: :"=D" (__res):"a" (c),"D" (cs),"c" (count) ! 541: :"cx"); ! 542: return __res; ! 543: } ! 544: ! 545: #define __memset_cc(s,c,count) \ ! 546: ((count%4==0) ? \ ! 547: __memset_cc_by4((s),(c),(count)) : \ ! 548: ((count%2==0) ? \ ! 549: __memset_cc_by2((s),(c),(count)) : \ ! 550: __memset_cg((s),(c),(count)))) ! 551: ! 552: #define __memset_gc(s,c,count) \ ! 553: ((count%4==0) ? \ ! 554: __memset_gc_by4((s),(c),(count)) : \ ! 555: ((count%2==0) ? \ ! 556: __memset_gc_by2((s),(c),(count)) : \ ! 557: __memset_gg((s),(c),(count)))) ! 558: ! 559: #define __HAVE_ARCH_MEMSET ! 560: #define memset(s,c,count) \ ! 561: (count == 0 \ ! 562: ? s \ ! 563: : __builtin_constant_p(c) \ ! 564: ? __builtin_constant_p(count) \ ! 565: ? __memset_cc((s),(c),(count)) \ ! 566: : __memset_cg((s),(c),(count)) \ ! 567: : __builtin_constant_p(count) \ ! 568: ? __memset_gc((s),(c),(count)) \ ! 569: : __memset_gg((s),(c),(count))) ! 570: ! 571: extern inline void * __memset_cc_by4(void * s, char c, size_t count) ! 572: { ! 573: /* ! 574: * register char *tmp = s; ! 575: */ ! 576: register char *tmp = (char *)s; ! 577: register int dummy; ! 578: __asm__ __volatile__ ( ! 579: "\n1:\tmovl %2,(%0)\n\t" ! 580: "addl $4,%0\n\t" ! 581: "decl %1\n\t" ! 582: "jnz 1b" ! 583: :"=r" (tmp), "=r" (dummy) ! 584: :"r" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/4) ! 585: :"memory"); ! 586: return s; ! 587: } ! 588: ! 589: extern inline void * __memset_cc_by2(void * s, char c, size_t count) ! 590: { ! 591: register void *tmp = (void *)s; ! 592: register int dummy; ! 593: __asm__ __volatile__ ( ! 594: "shrl $1,%1\n\t" /* may be divisible also by 4 */ ! 595: "jz 2f\n" ! 596: "\n1:\tmovl %2,(%0)\n\t" ! 597: "addl $4,%0\n\t" ! 598: "decl %1\n\t" ! 599: "jnz 1b\n" ! 600: "2:\tmovw %w2,(%0)" ! 601: :"=r" (tmp), "=r" (dummy) ! 602: :"r" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/2) ! 603: :"memory"); ! 604: return s; ! 605: } ! 606: ! 607: extern inline void * __memset_gc_by4(void * s, char c, size_t count) ! 608: { ! 609: register void *tmp = (void *)s; ! 610: register int dummy; ! 611: __asm__ __volatile__ ( ! 612: "movb %b0,%h0\n" ! 613: "pushw %w0\n\t" ! 614: "shll $16,%k0\n\t" ! 615: "popw %w0\n" ! 616: "1:\tmovl %k0,(%1)\n\t" ! 617: "addl $4,%1\n\t" ! 618: "decl %2\n\t" ! 619: "jnz 1b\n" ! 620: :"=q" (c), "=r" (tmp), "=r" (dummy) ! 621: :"0" ((unsigned) c), "1" (tmp), "2" (count/4) ! 622: :"memory"); ! 623: return s; ! 624: } ! 625: ! 626: extern inline void * __memset_gc_by2(void * s, char c, size_t count) ! 627: { ! 628: register void *tmp = (void *)s; ! 629: register int dummy1,dummy2; ! 630: __asm__ __volatile__ ( ! 631: "movb %b0,%h0\n\t" ! 632: "shrl $1,%2\n\t" /* may be divisible also by 4 */ ! 633: "jz 2f\n\t" ! 634: "pushw %w0\n\t" ! 635: "shll $16,%k0\n\t" ! 636: "popw %w0\n" ! 637: "1:\tmovl %k0,(%1)\n\t" ! 638: "addl $4,%1\n\t" ! 639: "decl %2\n\t" ! 640: "jnz 1b\n" ! 641: "2:\tmovw %w0,(%1)" ! 642: :"=q" (dummy1), "=r" (tmp), "=r" (dummy2) ! 643: :"0" ((unsigned) c), "1" (tmp), "2" (count/2) ! 644: :"memory"); ! 645: return s; ! 646: } ! 647: ! 648: extern inline void * __memset_cg(void * s, char c, size_t count) ! 649: { ! 650: register void *tmp = (void *)s; ! 651: __asm__ __volatile__ ( ! 652: "shrl $1,%%ecx\n\t" ! 653: "cld\n\t" ! 654: "rep\n\t" ! 655: "stosw\n\t" ! 656: "jnc 1f\n\t" ! 657: "movb %%al,(%%edi)\n" ! 658: "1:" ! 659: : /* no output */ ! 660: :"c" (count),"D" (tmp), "a" (0x0101U * (unsigned char) c) ! 661: :"cx","di","memory"); ! 662: return s; ! 663: } ! 664: ! 665: extern inline void * __memset_gg(void * s,char c,size_t count) ! 666: { ! 667: register void *tmp = (void *)s; ! 668: __asm__ __volatile__ ( ! 669: "movb %%al,%%ah\n\t" ! 670: "shrl $1,%%ecx\n\t" ! 671: "cld\n\t" ! 672: "rep\n\t" ! 673: "stosw\n\t" ! 674: "jnc 1f\n\t" ! 675: "movb %%al,(%%edi)\n" ! 676: "1:" ! 677: : /* no output */ ! 678: :"c" (count),"D" (tmp), "a" (c) ! 679: :"cx","di","memory"); ! 680: return s; ! 681: } ! 682: ! 683: ! 684: /* ! 685: * find the first occurrence of byte 'c', or 1 past the area if none ! 686: */ ! 687: #define __HAVE_ARCH_MEMSCAN ! 688: extern inline void * memscan(void * addr, int c, size_t size) ! 689: { ! 690: if (!size) ! 691: return addr; ! 692: __asm__("cld ! 693: repnz; scasb ! 694: jnz 1f ! 695: dec %%edi ! 696: 1: " ! 697: : "=D" (addr), "=c" (size) ! 698: : "0" (addr), "1" (size), "a" (c)); ! 699: return addr; ! 700: } ! 701: ! 702: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.