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

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

unix.superglobalmegacorp.com

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