Annotation of Gnu-Mach/linux/src/include/asm-i386/string-486.h, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.