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: {
                     29: __asm__("cld\n"
                     30:        "1:\tlodsb\n\t"
                     31:        "stosb\n\t"
                     32:        "testb %%al,%%al\n\t"
                     33:        "jne 1b"
                     34:        ::"S" (src),"D" (dest):"si","di","ax");
                     35: return dest;
                     36: }
                     37: 
1.1.1.2 ! root       38: extern inline char * strncpy(char * dest,const char *src,size_t count)
1.1       root       39: {
                     40: __asm__("cld\n"
                     41:        "1:\tdecl %2\n\t"
                     42:        "js 2f\n\t"
                     43:        "lodsb\n\t"
                     44:        "stosb\n\t"
                     45:        "testb %%al,%%al\n\t"
                     46:        "jne 1b\n\t"
                     47:        "rep\n\t"
                     48:        "stosb\n"
                     49:        "2:"
                     50:        ::"S" (src),"D" (dest),"c" (count):"si","di","ax","cx");
                     51: return dest;
                     52: }
                     53: 
                     54: extern inline char * strcat(char * dest,const char * src)
                     55: {
                     56: __asm__("cld\n\t"
                     57:        "repne\n\t"
                     58:        "scasb\n\t"
                     59:        "decl %1\n"
                     60:        "1:\tlodsb\n\t"
                     61:        "stosb\n\t"
                     62:        "testb %%al,%%al\n\t"
                     63:        "jne 1b"
                     64:        ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
                     65: return dest;
                     66: }
                     67: 
1.1.1.2 ! root       68: extern inline char * strncat(char * dest,const char * src,size_t count)
1.1       root       69: {
                     70: __asm__("cld\n\t"
                     71:        "repne\n\t"
                     72:        "scasb\n\t"
                     73:        "decl %1\n\t"
                     74:        "movl %4,%3\n"
                     75:        "1:\tdecl %3\n\t"
                     76:        "js 2f\n\t"
                     77:        "lodsb\n\t"
                     78:        "stosb\n\t"
                     79:        "testb %%al,%%al\n\t"
                     80:        "jne 1b\n"
                     81:        "2:\txorl %2,%2\n\t"
                     82:        "stosb"
                     83:        ::"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
                     84:        :"si","di","ax","cx");
                     85: return dest;
                     86: }
                     87: 
                     88: extern inline int strcmp(const char * cs,const char * ct)
                     89: {
                     90: register int __res __asm__("ax");
                     91: __asm__("cld\n"
                     92:        "1:\tlodsb\n\t"
                     93:        "scasb\n\t"
                     94:        "jne 2f\n\t"
                     95:        "testb %%al,%%al\n\t"
                     96:        "jne 1b\n\t"
                     97:        "xorl %%eax,%%eax\n\t"
                     98:        "jmp 3f\n"
                     99:        "2:\tmovl $1,%%eax\n\t"
                    100:        "jl 3f\n\t"
                    101:        "negl %%eax\n"
                    102:        "3:"
                    103:        :"=a" (__res):"D" (cs),"S" (ct):"si","di");
                    104: return __res;
                    105: }
                    106: 
1.1.1.2 ! root      107: extern inline int strncmp(const char * cs,const char * ct,size_t count)
1.1       root      108: {
                    109: register int __res __asm__("ax");
                    110: __asm__("cld\n"
                    111:        "1:\tdecl %3\n\t"
                    112:        "js 2f\n\t"
                    113:        "lodsb\n\t"
                    114:        "scasb\n\t"
                    115:        "jne 3f\n\t"
                    116:        "testb %%al,%%al\n\t"
                    117:        "jne 1b\n"
                    118:        "2:\txorl %%eax,%%eax\n\t"
                    119:        "jmp 4f\n"
                    120:        "3:\tmovl $1,%%eax\n\t"
                    121:        "jl 4f\n\t"
                    122:        "negl %%eax\n"
                    123:        "4:"
                    124:        :"=a" (__res):"D" (cs),"S" (ct),"c" (count):"si","di","cx");
                    125: return __res;
                    126: }
                    127: 
                    128: extern inline char * strchr(const char * s,char c)
                    129: {
                    130: register char * __res __asm__("ax");
                    131: __asm__("cld\n\t"
                    132:        "movb %%al,%%ah\n"
                    133:        "1:\tlodsb\n\t"
                    134:        "cmpb %%ah,%%al\n\t"
                    135:        "je 2f\n\t"
                    136:        "testb %%al,%%al\n\t"
                    137:        "jne 1b\n\t"
                    138:        "movl $1,%1\n"
                    139:        "2:\tmovl %1,%0\n\t"
                    140:        "decl %0"
                    141:        :"=a" (__res):"S" (s),"0" (c):"si");
                    142: return __res;
                    143: }
                    144: 
                    145: extern inline char * strrchr(const char * s,char c)
                    146: {
                    147: register char * __res __asm__("dx");
                    148: __asm__("cld\n\t"
                    149:        "movb %%al,%%ah\n"
                    150:        "1:\tlodsb\n\t"
                    151:        "cmpb %%ah,%%al\n\t"
                    152:        "jne 2f\n\t"
                    153:        "movl %%esi,%0\n\t"
                    154:        "decl %0\n"
                    155:        "2:\ttestb %%al,%%al\n\t"
                    156:        "jne 1b"
                    157:        :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
                    158: return __res;
                    159: }
                    160: 
1.1.1.2 ! root      161: extern inline size_t strspn(const char * cs, const char * ct)
1.1       root      162: {
                    163: register char * __res __asm__("si");
                    164: __asm__("cld\n\t"
                    165:        "movl %4,%%edi\n\t"
                    166:        "repne\n\t"
                    167:        "scasb\n\t"
                    168:        "notl %%ecx\n\t"
                    169:        "decl %%ecx\n\t"
                    170:        "movl %%ecx,%%edx\n"
                    171:        "1:\tlodsb\n\t"
                    172:        "testb %%al,%%al\n\t"
                    173:        "je 2f\n\t"
                    174:        "movl %4,%%edi\n\t"
                    175:        "movl %%edx,%%ecx\n\t"
                    176:        "repne\n\t"
                    177:        "scasb\n\t"
                    178:        "je 1b\n"
                    179:        "2:\tdecl %0"
                    180:        :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
                    181:        :"ax","cx","dx","di");
                    182: return __res-cs;
                    183: }
                    184: 
1.1.1.2 ! root      185: extern inline size_t strcspn(const char * cs, const char * ct)
1.1       root      186: {
                    187: register char * __res __asm__("si");
                    188: __asm__("cld\n\t"
                    189:        "movl %4,%%edi\n\t"
                    190:        "repne\n\t"
                    191:        "scasb\n\t"
                    192:        "notl %%ecx\n\t"
                    193:        "decl %%ecx\n\t"
                    194:        "movl %%ecx,%%edx\n"
                    195:        "1:\tlodsb\n\t"
                    196:        "testb %%al,%%al\n\t"
                    197:        "je 2f\n\t"
                    198:        "movl %4,%%edi\n\t"
                    199:        "movl %%edx,%%ecx\n\t"
                    200:        "repne\n\t"
                    201:        "scasb\n\t"
                    202:        "jne 1b\n"
                    203:        "2:\tdecl %0"
                    204:        :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
                    205:        :"ax","cx","dx","di");
                    206: return __res-cs;
                    207: }
                    208: 
                    209: extern inline char * strpbrk(const char * cs,const char * ct)
                    210: {
                    211: register char * __res __asm__("si");
                    212: __asm__("cld\n\t"
                    213:        "movl %4,%%edi\n\t"
                    214:        "repne\n\t"
                    215:        "scasb\n\t"
                    216:        "notl %%ecx\n\t"
                    217:        "decl %%ecx\n\t"
                    218:        "movl %%ecx,%%edx\n"
                    219:        "1:\tlodsb\n\t"
                    220:        "testb %%al,%%al\n\t"
                    221:        "je 2f\n\t"
                    222:        "movl %4,%%edi\n\t"
                    223:        "movl %%edx,%%ecx\n\t"
                    224:        "repne\n\t"
                    225:        "scasb\n\t"
                    226:        "jne 1b\n\t"
                    227:        "decl %0\n\t"
                    228:        "jmp 3f\n"
                    229:        "2:\txorl %0,%0\n"
                    230:        "3:"
                    231:        :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
                    232:        :"ax","cx","dx","di");
                    233: return __res;
                    234: }
                    235: 
                    236: extern inline char * strstr(const char * cs,const char * ct)
                    237: {
                    238: register char * __res __asm__("ax");
                    239: __asm__("cld\n\t" \
                    240:        "movl %4,%%edi\n\t"
                    241:        "repne\n\t"
                    242:        "scasb\n\t"
                    243:        "notl %%ecx\n\t"
                    244:        "decl %%ecx\n\t"        /* NOTE! This also sets Z if searchstring='' */
                    245:        "movl %%ecx,%%edx\n"
                    246:        "1:\tmovl %4,%%edi\n\t"
                    247:        "movl %%esi,%%eax\n\t"
                    248:        "movl %%edx,%%ecx\n\t"
                    249:        "repe\n\t"
                    250:        "cmpsb\n\t"
                    251:        "je 2f\n\t"             /* also works for empty string, see above */
                    252:        "xchgl %%eax,%%esi\n\t"
                    253:        "incl %%esi\n\t"
                    254:        "cmpb $0,-1(%%eax)\n\t"
                    255:        "jne 1b\n\t"
                    256:        "xorl %%eax,%%eax\n\t"
                    257:        "2:"
                    258:        :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
                    259:        :"cx","dx","di","si");
                    260: return __res;
                    261: }
                    262: 
1.1.1.2 ! root      263: extern inline size_t strlen(const char * s)
1.1       root      264: {
                    265: register int __res __asm__("cx");
                    266: __asm__("cld\n\t"
                    267:        "repne\n\t"
                    268:        "scasb\n\t"
                    269:        "notl %0\n\t"
                    270:        "decl %0"
                    271:        :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
                    272: return __res;
                    273: }
                    274: 
                    275: extern char * ___strtok;
                    276: 
                    277: extern inline char * strtok(char * s,const char * ct)
                    278: {
                    279: register char * __res __asm__("si");
                    280: __asm__("testl %1,%1\n\t"
                    281:        "jne 1f\n\t"
                    282:        "testl %0,%0\n\t"
                    283:        "je 8f\n\t"
                    284:        "movl %0,%1\n"
                    285:        "1:\txorl %0,%0\n\t"
                    286:        "movl $-1,%%ecx\n\t"
                    287:        "xorl %%eax,%%eax\n\t"
                    288:        "cld\n\t"
                    289:        "movl %4,%%edi\n\t"
                    290:        "repne\n\t"
                    291:        "scasb\n\t"
                    292:        "notl %%ecx\n\t"
                    293:        "decl %%ecx\n\t"
                    294:        "je 7f\n\t"                     /* empty delimeter-string */
                    295:        "movl %%ecx,%%edx\n"
                    296:        "2:\tlodsb\n\t"
                    297:        "testb %%al,%%al\n\t"
                    298:        "je 7f\n\t"
                    299:        "movl %4,%%edi\n\t"
                    300:        "movl %%edx,%%ecx\n\t"
                    301:        "repne\n\t"
                    302:        "scasb\n\t"
                    303:        "je 2b\n\t"
                    304:        "decl %1\n\t"
                    305:        "cmpb $0,(%1)\n\t"
                    306:        "je 7f\n\t"
                    307:        "movl %1,%0\n"
                    308:        "3:\tlodsb\n\t"
                    309:        "testb %%al,%%al\n\t"
                    310:        "je 5f\n\t"
                    311:        "movl %4,%%edi\n\t"
                    312:        "movl %%edx,%%ecx\n\t"
                    313:        "repne\n\t"
                    314:        "scasb\n\t"
                    315:        "jne 3b\n\t"
                    316:        "decl %1\n\t"
                    317:        "cmpb $0,(%1)\n\t"
                    318:        "je 5f\n\t"
                    319:        "movb $0,(%1)\n\t"
                    320:        "incl %1\n\t"
                    321:        "jmp 6f\n"
                    322:        "5:\txorl %1,%1\n"
                    323:        "6:\tcmpb $0,(%0)\n\t"
                    324:        "jne 7f\n\t"
                    325:        "xorl %0,%0\n"
                    326:        "7:\ttestl %0,%0\n\t"
                    327:        "jne 8f\n\t"
                    328:        "movl %0,%1\n"
                    329:        "8:"
1.1.1.2 ! root      330: #if __GNUC__ == 2
        !           331:        :"=r" (__res)
        !           332: #else
        !           333:        :"=b" (__res)
        !           334: #endif
        !           335:        ,"=S" (___strtok)
1.1       root      336:        :"0" (___strtok),"1" (s),"g" (ct)
                    337:        :"ax","cx","dx","di");
                    338: return __res;
                    339: }
                    340: 
1.1.1.2 ! root      341: extern inline void * memcpy(void * dest,const void * src, size_t n)
1.1       root      342: {
                    343: __asm__("cld\n\t"
                    344:        "rep\n\t"
                    345:        "movsb"
                    346:        ::"c" (n),"S" (src),"D" (dest)
                    347:        :"cx","si","di");
                    348: return dest;
                    349: }
                    350: 
1.1.1.2 ! root      351: extern inline void * memmove(void * dest,const void * src, size_t n)
1.1       root      352: {
                    353: if (dest<src)
                    354: __asm__("cld\n\t"
                    355:        "rep\n\t"
                    356:        "movsb"
                    357:        ::"c" (n),"S" (src),"D" (dest)
                    358:        :"cx","si","di");
                    359: else
                    360: __asm__("std\n\t"
                    361:        "rep\n\t"
1.1.1.2 ! root      362:        "movsb\n\t"
        !           363:        "cld"
1.1       root      364:        ::"c" (n),"S" (src+n-1),"D" (dest+n-1)
                    365:        :"cx","si","di");
                    366: return dest;
                    367: }
                    368: 
1.1.1.2 ! root      369: extern inline int memcmp(const void * cs,const void * ct,size_t count)
1.1       root      370: {
                    371: register int __res __asm__("ax");
                    372: __asm__("cld\n\t"
                    373:        "repe\n\t"
                    374:        "cmpsb\n\t"
                    375:        "je 1f\n\t"
                    376:        "movl $1,%%eax\n\t"
                    377:        "jl 1f\n\t"
                    378:        "negl %%eax\n"
                    379:        "1:"
                    380:        :"=a" (__res):"0" (0),"D" (cs),"S" (ct),"c" (count)
                    381:        :"si","di","cx");
                    382: return __res;
                    383: }
                    384: 
1.1.1.2 ! root      385: extern inline void * memchr(const void * cs,char c,size_t count)
1.1       root      386: {
                    387: register void * __res __asm__("di");
                    388: if (!count)
                    389:        return NULL;
                    390: __asm__("cld\n\t"
                    391:        "repne\n\t"
                    392:        "scasb\n\t"
                    393:        "je 1f\n\t"
                    394:        "movl $1,%0\n"
                    395:        "1:\tdecl %0"
                    396:        :"=D" (__res):"a" (c),"D" (cs),"c" (count)
                    397:        :"cx");
                    398: return __res;
                    399: }
                    400: 
1.1.1.2 ! root      401: extern inline void * memset(void * s,char c,size_t count)
1.1       root      402: {
                    403: __asm__("cld\n\t"
                    404:        "rep\n\t"
                    405:        "stosb"
                    406:        ::"a" (c),"D" (s),"c" (count)
                    407:        :"cx","di");
                    408: return s;
                    409: }
                    410: 
                    411: #endif

unix.superglobalmegacorp.com

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