Annotation of Gnu-Mach/linux/src/include/asm-i386/string-486.h, revision 1.1.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.