root/include/linux/string.h

/* [previous][next][first][last][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. strcpy
  2. strncpy
  3. strcat
  4. strncat
  5. strcmp
  6. strncmp
  7. strchr
  8. strrchr
  9. strspn
  10. strcspn
  11. strpbrk
  12. strstr
  13. strlen
  14. strtok
  15. memcpy
  16. memmove
  17. memcmp
  18. memchr
  19. memset

   1 #ifndef _LINUX_STRING_H_
   2 #define _LINUX_STRING_H_
   3 
   4 #include <linux/types.h>        /* for size_t */
   5 
   6 #ifndef NULL
   7 #define NULL ((void *) 0)
   8 #endif
   9 
  10 #ifdef __cplusplus
  11 extern "C" {
  12 #endif
  13 
  14 /*
  15  * This string-include defines all string functions as inline
  16  * functions. Use gcc. It also assumes ds=es=data space, this should be
  17  * normal. Most of the string-functions are rather heavily hand-optimized,
  18  * see especially strtok,strstr,str[c]spn. They should work, but are not
  19  * very easy to understand. Everything is done entirely within the register
  20  * set, making the functions fast and clean. String instructions have been
  21  * used through-out, making for "slightly" unclear code :-)
  22  *
  23  *              Copyright (C) 1991, 1992 Linus Torvalds
  24  */
  25  
  26 extern inline char * strcpy(char * dest,const char *src)
     /* [previous][next][first][last][top][bottom][index][help] */
  27 {
  28 __asm__("cld\n"
  29         "1:\tlodsb\n\t"
  30         "stosb\n\t"
  31         "testb %%al,%%al\n\t"
  32         "jne 1b"
  33         : /* no output */
  34         :"S" (src),"D" (dest):"si","di","ax","memory");
  35 return dest;
  36 }
  37 
  38 extern inline char * strncpy(char * dest,const char *src,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
  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         : /* no output */
  51         :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
  52 return dest;
  53 }
  54 
  55 extern inline char * strcat(char * dest,const char * src)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57 __asm__("cld\n\t"
  58         "repne\n\t"
  59         "scasb\n\t"
  60         "decl %1\n"
  61         "1:\tlodsb\n\t"
  62         "stosb\n\t"
  63         "testb %%al,%%al\n\t"
  64         "jne 1b"
  65         : /* no output */
  66         :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
  67 return dest;
  68 }
  69 
  70 extern inline char * strncat(char * dest,const char * src,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
  71 {
  72 __asm__("cld\n\t"
  73         "repne\n\t"
  74         "scasb\n\t"
  75         "decl %1\n\t"
  76         "movl %4,%3\n"
  77         "1:\tdecl %3\n\t"
  78         "js 2f\n\t"
  79         "lodsb\n\t"
  80         "stosb\n\t"
  81         "testb %%al,%%al\n\t"
  82         "jne 1b\n"
  83         "2:\txorl %2,%2\n\t"
  84         "stosb"
  85         : /* no output */
  86         :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
  87         :"si","di","ax","cx","memory");
  88 return dest;
  89 }
  90 
  91 extern inline int strcmp(const char * cs,const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
  92 {
  93 register int __res __asm__("ax");
  94 __asm__("cld\n"
  95         "1:\tlodsb\n\t"
  96         "scasb\n\t"
  97         "jne 2f\n\t"
  98         "testb %%al,%%al\n\t"
  99         "jne 1b\n\t"
 100         "xorl %%eax,%%eax\n\t"
 101         "jmp 3f\n"
 102         "2:\tsbbl %%eax,%%eax\n\t"
 103         "orb $1,%%eax\n"
 104         "3:"
 105         :"=a" (__res):"S" (cs),"D" (ct):"si","di");
 106 return __res;
 107 }
 108 
 109 extern inline int strncmp(const char * cs,const char * ct,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111 register int __res __asm__("ax");
 112 __asm__("cld\n"
 113         "1:\tdecl %3\n\t"
 114         "js 2f\n\t"
 115         "lodsb\n\t"
 116         "scasb\n\t"
 117         "jne 3f\n\t"
 118         "testb %%al,%%al\n\t"
 119         "jne 1b\n"
 120         "2:\txorl %%eax,%%eax\n\t"
 121         "jmp 4f\n"
 122         "3:\tsbbl %%eax,%%eax\n\t"
 123         "orb $1,%%al\n"
 124         "4:"
 125         :"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
 126 return __res;
 127 }
 128 
 129 extern inline char * strchr(const char * s,char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131 register char * __res __asm__("ax");
 132 __asm__("cld\n\t"
 133         "movb %%al,%%ah\n"
 134         "1:\tlodsb\n\t"
 135         "cmpb %%ah,%%al\n\t"
 136         "je 2f\n\t"
 137         "testb %%al,%%al\n\t"
 138         "jne 1b\n\t"
 139         "movl $1,%1\n"
 140         "2:\tmovl %1,%0\n\t"
 141         "decl %0"
 142         :"=a" (__res):"S" (s),"0" (c):"si");
 143 return __res;
 144 }
 145 
 146 extern inline char * strrchr(const char * s,char c)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148 register char * __res __asm__("dx");
 149 __asm__("cld\n\t"
 150         "movb %%al,%%ah\n"
 151         "1:\tlodsb\n\t"
 152         "cmpb %%ah,%%al\n\t"
 153         "jne 2f\n\t"
 154         "leal -1(%%esi),%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 
 161 extern inline size_t strspn(const char * cs, const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 185 extern inline size_t strcspn(const char * cs, const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 
 263 extern inline size_t strlen(const char * s)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 278 {
 279 register char * __res;
 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:"
 330         :"=b" (__res),"=S" (___strtok)
 331         :"0" (___strtok),"1" (s),"g" (ct)
 332         :"ax","cx","dx","di","memory");
 333 return __res;
 334 }
 335 
 336 extern inline void * memcpy(void * to, const void * from, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 337 {
 338 __asm__("cld\n\t"
 339         "movl %%edx, %%ecx\n\t"
 340         "shrl $2,%%ecx\n\t"
 341         "rep ; movsl\n\t"
 342         "testb $1,%%dl\n\t"
 343         "je 1f\n\t"
 344         "movsb\n"
 345         "1:\ttestb $2,%%dl\n\t"
 346         "je 2f\n\t"
 347         "movsw\n"
 348         "2:\n"
 349         : /* no output */
 350         :"d" (n),"D" ((long) to),"S" ((long) from)
 351         : "cx","di","si","memory");
 352 return (to);
 353 }
 354 
 355 extern inline void * memmove(void * dest,const void * src, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 356 {
 357 if (dest<src)
 358 __asm__("cld\n\t"
 359         "rep\n\t"
 360         "movsb"
 361         : /* no output */
 362         :"c" (n),"S" (src),"D" (dest)
 363         :"cx","si","di");
 364 else
 365 __asm__("std\n\t"
 366         "rep\n\t"
 367         "movsb\n\t"
 368         "cld"
 369         : /* no output */
 370         :"c" (n),
 371          "S" (n-1+(const char *)src),
 372          "D" (n-1+(char *)dest)
 373         :"cx","si","di","memory");
 374 return dest;
 375 }
 376 
 377 extern inline int memcmp(const void * cs,const void * ct,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 378 {
 379 register int __res __asm__("ax");
 380 __asm__("cld\n\t"
 381         "repe\n\t"
 382         "cmpsb\n\t"
 383         "je 1f\n\t"
 384         "sbbl %%eax,%%eax\n\t"
 385         "orb $1,%%al\n"
 386         "1:"
 387         :"=a" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
 388         :"si","di","cx");
 389 return __res;
 390 }
 391 
 392 extern inline void * memchr(const void * cs,char c,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 393 {
 394 register void * __res __asm__("di");
 395 if (!count)
 396         return NULL;
 397 __asm__("cld\n\t"
 398         "repne\n\t"
 399         "scasb\n\t"
 400         "je 1f\n\t"
 401         "movl $1,%0\n"
 402         "1:\tdecl %0"
 403         :"=D" (__res):"a" (c),"D" (cs),"c" (count)
 404         :"cx");
 405 return __res;
 406 }
 407 
 408 extern inline void * memset(void * s,char c,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 409 {
 410 __asm__("cld\n\t"
 411         "rep\n\t"
 412         "stosb"
 413         : /* no output */
 414         :"a" (c),"D" (s),"c" (count)
 415         :"cx","di","memory");
 416 return s;
 417 }
 418 
 419 #ifdef __cplusplus
 420 }
 421 #endif
 422 
 423 #endif

/* [previous][next][first][last][top][bottom][index][help] */