Annotation of linux/include/string.h, revision 1.1.1.2

1.1       root        1: #ifndef _STRING_H_
                      2: #define _STRING_H_
                      3: 
                      4: #ifndef NULL
                      5: #define NULL ((void *) 0)
                      6: #endif
                      7: 
                      8: #ifndef _SIZE_T
                      9: #define _SIZE_T
                     10: typedef unsigned int size_t;
                     11: #endif
                     12: 
                     13: extern char * strerror(int errno);
                     14: 
                     15: /*
                     16:  * This string-include defines all string functions as inline
                     17:  * functions. Use gcc. It also assumes ds=es=data space, this should be
                     18:  * normal. Most of the string-functions are rather heavily hand-optimized,
                     19:  * see especially strtok,strstr,str[c]spn. They should work, but are not
                     20:  * very easy to understand. Everything is done entirely within the register
                     21:  * set, making the functions fast and clean. String instructions have been
                     22:  * used through-out, making for "slightly" unclear code :-)
                     23:  *
                     24:  *             (C) 1991 Linus Torvalds
                     25:  */
                     26:  
                     27: extern inline char * strcpy(char * dest,const char *src)
                     28: {
1.1.1.2 ! root       29: int d0, d1, d2;
        !            30: __asm__ __volatile__("cld\n\t"
1.1       root       31:        "1:\tlodsb\n\t"
                     32:        "stosb\n\t"
                     33:        "testb %%al,%%al\n\t"
                     34:        "jne 1b"
1.1.1.2 ! root       35:        : "=&S" (d0), "=&D" (d1), "=&a" (d2)
        !            36:        :"0" (src),"1" (dest) : "memory");
1.1       root       37: return dest;
                     38: }
                     39: 
                     40: extern inline char * strncpy(char * dest,const char *src,int count)
                     41: {
1.1.1.2 ! root       42: int d0, d1, d2, d3;
        !            43: __asm__ __volatile__("cld\n\t"
1.1       root       44:        "1:\tdecl %2\n\t"
                     45:        "js 2f\n\t"
                     46:        "lodsb\n\t"
                     47:        "stosb\n\t"
                     48:        "testb %%al,%%al\n\t"
                     49:        "jne 1b\n\t"
                     50:        "rep\n\t"
                     51:        "stosb\n"
                     52:        "2:"
1.1.1.2 ! root       53:        : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3)
        !            54:        :"0" (src),"1" (dest),"2" (count) : "memory");
1.1       root       55: return dest;
                     56: }
                     57: 
                     58: extern inline char * strcat(char * dest,const char * src)
                     59: {
1.1.1.2 ! root       60: int d0, d1, d2, d3;
        !            61: __asm__ __volatile__("cld\n\t"
1.1       root       62:        "repne\n\t"
                     63:        "scasb\n\t"
                     64:        "decl %1\n"
                     65:        "1:\tlodsb\n\t"
                     66:        "stosb\n\t"
                     67:        "testb %%al,%%al\n\t"
                     68:        "jne 1b"
1.1.1.2 ! root       69:        : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
        !            70:        : "0" (src), "1" (dest), "2" (0), "3" (0xffffffffu):"memory");
1.1       root       71: return dest;
                     72: }
                     73: 
                     74: extern inline char * strncat(char * dest,const char * src,int count)
                     75: {
1.1.1.2 ! root       76: int d0, d1, d2, d3;
        !            77: __asm__ __volatile__("cld\n\t"
1.1       root       78:        "repne\n\t"
                     79:        "scasb\n\t"
                     80:        "decl %1\n\t"
1.1.1.2 ! root       81:        "movl %8,%3\n"
1.1       root       82:        "1:\tdecl %3\n\t"
                     83:        "js 2f\n\t"
                     84:        "lodsb\n\t"
                     85:        "stosb\n\t"
                     86:        "testb %%al,%%al\n\t"
                     87:        "jne 1b\n"
                     88:        "2:\txorl %2,%2\n\t"
                     89:        "stosb"
1.1.1.2 ! root       90:        : "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
        !            91:        : "0" (src),"1" (dest),"2" (0),"3" (0xffffffffu), "g" (count)
        !            92:        : "memory");
1.1       root       93: return dest;
                     94: }
                     95: 
                     96: extern inline int strcmp(const char * cs,const char * ct)
                     97: {
1.1.1.2 ! root       98: int d0, d1;
        !            99: register int __res;
        !           100: __asm__ __volatile__("cld\n\t"
1.1       root      101:        "1:\tlodsb\n\t"
                    102:        "scasb\n\t"
                    103:        "jne 2f\n\t"
                    104:        "testb %%al,%%al\n\t"
                    105:        "jne 1b\n\t"
                    106:        "xorl %%eax,%%eax\n\t"
                    107:        "jmp 3f\n"
1.1.1.2 ! root      108:        "2:\tsbbl %%eax,%%eax\n\t"
        !           109:        "orb $1,%%al\n"
1.1       root      110:        "3:"
1.1.1.2 ! root      111:        :"=a" (__res), "=&S" (d0), "=&D" (d1)
        !           112:        :"1" (cs),"2" (ct)
        !           113:        :"memory");
1.1       root      114: return __res;
                    115: }
                    116: 
                    117: extern inline int strncmp(const char * cs,const char * ct,int count)
                    118: {
1.1.1.2 ! root      119: register int __res;
        !           120: int d0, d1, d2;
        !           121: __asm__ __volatile__("cld\n\t"
1.1       root      122:        "1:\tdecl %3\n\t"
                    123:        "js 2f\n\t"
                    124:        "lodsb\n\t"
                    125:        "scasb\n\t"
                    126:        "jne 3f\n\t"
                    127:        "testb %%al,%%al\n\t"
                    128:        "jne 1b\n"
                    129:        "2:\txorl %%eax,%%eax\n\t"
                    130:        "jmp 4f\n"
1.1.1.2 ! root      131:        "3:\tsbbl %%eax,%%eax\n\t"
        !           132:        "orb $1,%%al\n"
1.1       root      133:        "4:"
1.1.1.2 ! root      134:        :"=a" (__res), "=&S" (d0), "=&D" (d1), "=&c" (d2)
        !           135:        :"1" (cs),"2" (ct),"3" (count)
        !           136:        :"memory");
1.1       root      137: return __res;
                    138: }
                    139: 
1.1.1.2 ! root      140: extern inline char * strchr(const char * s,int c)
1.1       root      141: {
1.1.1.2 ! root      142: int d0;
        !           143: register char * __res;
        !           144: __asm__ __volatile__(
1.1       root      145:        "movb %%al,%%ah\n"
                    146:        "1:\tlodsb\n\t"
                    147:        "cmpb %%ah,%%al\n\t"
                    148:        "je 2f\n\t"
                    149:        "testb %%al,%%al\n\t"
                    150:        "jne 1b\n\t"
                    151:        "movl $1,%1\n"
                    152:        "2:\tmovl %1,%0\n\t"
                    153:        "decl %0"
1.1.1.2 ! root      154:        :"=a" (__res), "=&S" (d0)
        !           155:        :"1" (s),"0" (c)
        !           156:        :"memory");
1.1       root      157: return __res;
                    158: }
                    159: 
1.1.1.2 ! root      160: extern inline char * strrchr(const char * s,int c)
1.1       root      161: {
1.1.1.2 ! root      162: int d0, d1;
        !           163: register char * __res;
        !           164: __asm__ __volatile__("cld\n\t"
1.1       root      165:        "movb %%al,%%ah\n"
                    166:        "1:\tlodsb\n\t"
                    167:        "cmpb %%ah,%%al\n\t"
                    168:        "jne 2f\n\t"
1.1.1.2 ! root      169:        "leal -1(%%esi),%0\n"
1.1       root      170:        "2:\ttestb %%al,%%al\n\t"
                    171:        "jne 1b"
1.1.1.2 ! root      172:        :"=g" (__res), "=&S" (d0), "=&a" (d1)
        !           173:        :"0" (0),"1" (s),"2" (c)
        !           174:        :"memory");
1.1       root      175: return __res;
                    176: }
                    177: 
                    178: extern inline int strspn(const char * cs, const char * ct)
                    179: {
1.1.1.2 ! root      180: register char * __res;// __asm__("si");
1.1       root      181: __asm__("cld\n\t"
                    182:        "movl %4,%%edi\n\t"
                    183:        "repne\n\t"
                    184:        "scasb\n\t"
                    185:        "notl %%ecx\n\t"
                    186:        "decl %%ecx\n\t"
                    187:        "movl %%ecx,%%edx\n"
                    188:        "1:\tlodsb\n\t"
                    189:        "testb %%al,%%al\n\t"
                    190:        "je 2f\n\t"
                    191:        "movl %4,%%edi\n\t"
                    192:        "movl %%edx,%%ecx\n\t"
                    193:        "repne\n\t"
                    194:        "scasb\n\t"
                    195:        "je 1b\n"
                    196:        "2:\tdecl %0"
                    197:        :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
1.1.1.2 ! root      198:        :/*"ax","cx",*/"dx","di"); /* TODO : constraint may be wrong*/
1.1       root      199: return __res-cs;
                    200: }
                    201: 
                    202: extern inline int strcspn(const char * cs, const char * ct)
                    203: {
1.1.1.2 ! root      204: register char * __res;// __asm__("si");
1.1       root      205: __asm__("cld\n\t"
                    206:        "movl %4,%%edi\n\t"
                    207:        "repne\n\t"
                    208:        "scasb\n\t"
                    209:        "notl %%ecx\n\t"
                    210:        "decl %%ecx\n\t"
                    211:        "movl %%ecx,%%edx\n"
                    212:        "1:\tlodsb\n\t"
                    213:        "testb %%al,%%al\n\t"
                    214:        "je 2f\n\t"
                    215:        "movl %4,%%edi\n\t"
                    216:        "movl %%edx,%%ecx\n\t"
                    217:        "repne\n\t"
                    218:        "scasb\n\t"
                    219:        "jne 1b\n"
                    220:        "2:\tdecl %0"
                    221:        :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
1.1.1.2 ! root      222:        :/*"ax","cx",*/"dx","di"); /* TODO : constraint may be wrong*/
1.1       root      223: return __res-cs;
                    224: }
                    225: 
                    226: extern inline char * strpbrk(const char * cs,const char * ct)
                    227: {
1.1.1.2 ! root      228: register char * __res;// __asm__("si");
1.1       root      229: __asm__("cld\n\t"
                    230:        "movl %4,%%edi\n\t"
                    231:        "repne\n\t"
                    232:        "scasb\n\t"
                    233:        "notl %%ecx\n\t"
                    234:        "decl %%ecx\n\t"
                    235:        "movl %%ecx,%%edx\n"
                    236:        "1:\tlodsb\n\t"
                    237:        "testb %%al,%%al\n\t"
                    238:        "je 2f\n\t"
                    239:        "movl %4,%%edi\n\t"
                    240:        "movl %%edx,%%ecx\n\t"
                    241:        "repne\n\t"
                    242:        "scasb\n\t"
                    243:        "jne 1b\n\t"
                    244:        "decl %0\n\t"
                    245:        "jmp 3f\n"
                    246:        "2:\txorl %0,%0\n"
                    247:        "3:"
                    248:        :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
1.1.1.2 ! root      249:        :/*"ax","cx",*/"dx","di");/* TODO : constraint may be wrong*/
1.1       root      250: return __res;
                    251: }
                    252: 
                    253: extern inline char * strstr(const char * cs,const char * ct)
                    254: {
1.1.1.2 ! root      255: register char * __res;// __asm__("ax");
1.1       root      256: __asm__("cld\n\t" \
                    257:        "movl %4,%%edi\n\t"
                    258:        "repne\n\t"
                    259:        "scasb\n\t"
                    260:        "notl %%ecx\n\t"
                    261:        "decl %%ecx\n\t"        /* NOTE! This also sets Z if searchstring='' */
                    262:        "movl %%ecx,%%edx\n"
                    263:        "1:\tmovl %4,%%edi\n\t"
                    264:        "movl %%esi,%%eax\n\t"
                    265:        "movl %%edx,%%ecx\n\t"
                    266:        "repe\n\t"
                    267:        "cmpsb\n\t"
                    268:        "je 2f\n\t"             /* also works for empty string, see above */
                    269:        "xchgl %%eax,%%esi\n\t"
                    270:        "incl %%esi\n\t"
                    271:        "cmpb $0,-1(%%eax)\n\t"
                    272:        "jne 1b\n\t"
                    273:        "xorl %%eax,%%eax\n\t"
                    274:        "2:"
                    275:        :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
1.1.1.2 ! root      276:        :/*"cx",*/"dx","di"/*,"si"*/); /* TODO : constraint may be wrong*/
1.1       root      277: return __res;
                    278: }
                    279: 
                    280: extern inline int strlen(const char * s)
                    281: {
1.1.1.2 ! root      282: int d0;
        !           283: register int __res;
        !           284: __asm__ __volatile__("cld\n\t"
1.1       root      285:        "repne\n\t"
                    286:        "scasb\n\t"
                    287:        "notl %0\n\t"
                    288:        "decl %0"
1.1.1.2 ! root      289:        :"=c" (__res), "=&D" (d0)
        !           290:        :"1" (s),"a" (0), "0" (0xffffffffu)
        !           291:        :"memory");
1.1       root      292: return __res;
                    293: }
                    294: 
                    295: extern char * ___strtok;
                    296: 
                    297: extern inline char * strtok(char * s,const char * ct)
                    298: {
1.1.1.2 ! root      299: register char * __res;// __asm__("si");
1.1       root      300: __asm__("testl %1,%1\n\t"
                    301:        "jne 1f\n\t"
                    302:        "testl %0,%0\n\t"
                    303:        "je 8f\n\t"
                    304:        "movl %0,%1\n"
                    305:        "1:\txorl %0,%0\n\t"
                    306:        "movl $-1,%%ecx\n\t"
                    307:        "xorl %%eax,%%eax\n\t"
                    308:        "cld\n\t"
                    309:        "movl %4,%%edi\n\t"
                    310:        "repne\n\t"
                    311:        "scasb\n\t"
                    312:        "notl %%ecx\n\t"
                    313:        "decl %%ecx\n\t"
                    314:        "je 7f\n\t"                     /* empty delimeter-string */
                    315:        "movl %%ecx,%%edx\n"
                    316:        "2:\tlodsb\n\t"
                    317:        "testb %%al,%%al\n\t"
                    318:        "je 7f\n\t"
                    319:        "movl %4,%%edi\n\t"
                    320:        "movl %%edx,%%ecx\n\t"
                    321:        "repne\n\t"
                    322:        "scasb\n\t"
                    323:        "je 2b\n\t"
                    324:        "decl %1\n\t"
                    325:        "cmpb $0,(%1)\n\t"
                    326:        "je 7f\n\t"
                    327:        "movl %1,%0\n"
                    328:        "3:\tlodsb\n\t"
                    329:        "testb %%al,%%al\n\t"
                    330:        "je 5f\n\t"
                    331:        "movl %4,%%edi\n\t"
                    332:        "movl %%edx,%%ecx\n\t"
                    333:        "repne\n\t"
                    334:        "scasb\n\t"
                    335:        "jne 3b\n\t"
                    336:        "decl %1\n\t"
                    337:        "cmpb $0,(%1)\n\t"
                    338:        "je 5f\n\t"
                    339:        "movb $0,(%1)\n\t"
                    340:        "incl %1\n\t"
                    341:        "jmp 6f\n"
                    342:        "5:\txorl %1,%1\n"
                    343:        "6:\tcmpb $0,(%0)\n\t"
                    344:        "jne 7f\n\t"
                    345:        "xorl %0,%0\n"
                    346:        "7:\ttestl %0,%0\n\t"
                    347:        "jne 8f\n\t"
                    348:        "movl %0,%1\n"
                    349:        "8:"
                    350:        :"=b" (__res),"=S" (___strtok)
                    351:        :"0" (___strtok),"1" (s),"g" (ct)
1.1.1.2 ! root      352:        :"ax","cx","dx","di"); /* TODO : constraint may be wrong*/
1.1       root      353: return __res;
                    354: }
                    355: 
                    356: extern inline void * memcpy(void * dest,const void * src, int n)
                    357: {
1.1.1.2 ! root      358: int d0,d1,d2;
        !           359: __asm__ __volatile("cld\n\t"
1.1       root      360:        "rep\n\t"
                    361:        "movsb"
1.1.1.2 ! root      362:        :"=&c" (d0), "=&S" (d1), "=&D" (d2)
        !           363:        :"0" (n),"1" (src),"2" (dest)
        !           364:        :"memory");
1.1       root      365: return dest;
                    366: }
                    367: 
                    368: extern inline void * memmove(void * dest,const void * src, int n)
                    369: {
1.1.1.2 ! root      370:        int d0, d1, d2;
        !           371: 
        !           372:        if (dest < src) {
        !           373:                memcpy(dest,src,n);
        !           374:        } else {
        !           375:                __asm__ __volatile__(
        !           376:                        "std\n\t"
        !           377:                        "rep\n\t"
        !           378:                        "movsb\n\t"
        !           379:                        "cld"
        !           380:                        : "=&c" (d0), "=&S" (d1), "=&D" (d2)
        !           381:                        :"0" (n),
        !           382:                         "1" (n-1+(const char *)src),
        !           383:                         "2" (n-1+(char *)dest)
        !           384:                        :"memory");
        !           385:        }
        !           386:        return dest;
1.1       root      387: }
                    388: 
                    389: extern inline int memcmp(const void * cs,const void * ct,int count)
                    390: {
1.1.1.2 ! root      391: register int __res;// __asm__("ax");
1.1       root      392: __asm__("cld\n\t"
                    393:        "repe\n\t"
                    394:        "cmpsb\n\t"
                    395:        "je 1f\n\t"
                    396:        "movl $1,%%eax\n\t"
                    397:        "jl 1f\n\t"
                    398:        "negl %%eax\n"
                    399:        "1:"
                    400:        :"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
1.1.1.2 ! root      401:        /*:"si","di","cx"*/); /* TODO : constraint may be wrong*/
1.1       root      402: return __res;
                    403: }
                    404: 
                    405: extern inline void * memchr(const void * cs,char c,int count)
                    406: {
1.1.1.2 ! root      407: int d0;
        !           408: register void * __res;
1.1       root      409: if (!count)
                    410:        return NULL;
1.1.1.2 ! root      411: __asm__ __volatile__("cld\n\t"
1.1       root      412:        "repne\n\t"
                    413:        "scasb\n\t"
                    414:        "je 1f\n\t"
                    415:        "movl $1,%0\n"
                    416:        "1:\tdecl %0"
1.1.1.2 ! root      417:        :"=D" (__res), "=&c" (d0)
        !           418:        :"a" (c),"0" (cs),"1" (count)
        !           419:        :"memory");
1.1       root      420: return __res;
                    421: }
                    422: 
1.1.1.2 ! root      423: extern inline void * memset(void * s,int c,int count)
1.1       root      424: {
1.1.1.2 ! root      425: int d0, d1;
        !           426: __asm__ __volatile__("cld\n\t"
1.1       root      427:        "rep\n\t"
                    428:        "stosb"
1.1.1.2 ! root      429:        : "=&c" (d0), "=&D" (d1)
        !           430:        :"a" (c),"1" (s),"0" (count)
        !           431:        :"memory");
1.1       root      432: return s;
                    433: }
                    434: 
                    435: #endif

unix.superglobalmegacorp.com

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