root/include/asm-i386/string-486.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. strnlen
  15. strtok
  16. __memcpy_by4
  17. __memcpy_by2
  18. __memcpy_g
  19. memmove
  20. memcmp
  21. memchr
  22. __memset_cc_by4
  23. __memset_cc_by2
  24. __memset_gc_by4
  25. __memset_gc_by2
  26. __memset_cg
  27. __memset_gg
  28. memscan

   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)
     /* [previous][next][first][last][top][bottom][index][help] */
  21 {
  22 register char *tmp= (char *)dest;
  23 register char dummy;
  24 __asm__ __volatile__(
  25         "\n1:\t"
  26         "movb (%0),%2\n\t"
  27         "incl %0\n\t"
  28         "movb %2,(%1)\n\t"
  29         "incl %1\n\t"
  30         "testb %2,%2\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)
     /* [previous][next][first][last][top][bottom][index][help] */
  40 {
  41 register char *tmp= (char *)dest;
  42 register char dummy;
  43 if (count) {
  44 __asm__ __volatile__(
  45         "\n1:\t"
  46         "movb (%0),%2\n\t"
  47         "incl %0\n\t"
  48         "movb %2,(%1)\n\t"
  49         "incl %1\n\t"
  50         "decl %3\n\t"
  51         "je 3f\n\t"
  52         "testb %2,%2\n\t"
  53         "jne 1b\n\t"
  54         "2:\tmovb %2,(%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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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)
     /* [previous][next][first][last][top][bottom][index][help] */
  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:\txorl %0,%0\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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 %0,%0\n\t"
 125         "jmp 3f\n"
 126         "2:\tmovl $1,%0\n\t"
 127         "jb 3f\n\t"
 128         "negl %0\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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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 %0,%0\n\t"
 151         "jmp 4f\n"
 152         "3:\tmovl $1,%0\n\t"
 153         "jb 4f\n\t"
 154         "negl %0\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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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)
     /* [previous][next][first][last][top][bottom][index][help] */
 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):"c" (s),"d" (count));
 343 return __res;
 344 }
 345 /* end of additional stuff */
 346 
 347 #define __HAVE_ARCH_STRTOK
 348 extern inline char * strtok(char * s,const char * ct)
     /* [previous][next][first][last][top][bottom][index][help] */
 349 {
 350 register char * __res;
 351 __asm__ __volatile__(
 352         "testl %1,%1\n\t"
 353         "jne 1f\n\t"
 354         "testl %0,%0\n\t"
 355         "je 8f\n\t"
 356         "movl %0,%1\n"
 357         "1:\txorl %0,%0\n\t"
 358         "movl $-1,%%ecx\n\t"
 359         "xorl %%eax,%%eax\n\t"
 360         "cld\n\t"
 361         "movl %4,%%edi\n\t"
 362         "repne\n\t"
 363         "scasb\n\t"
 364         "notl %%ecx\n\t"
 365         "decl %%ecx\n\t"
 366         "je 7f\n\t"                     /* empty delimiter-string */
 367         "movl %%ecx,%%edx\n"
 368         "2:\tlodsb\n\t"
 369         "testb %%al,%%al\n\t"
 370         "je 7f\n\t"
 371         "movl %4,%%edi\n\t"
 372         "movl %%edx,%%ecx\n\t"
 373         "repne\n\t"
 374         "scasb\n\t"
 375         "je 2b\n\t"
 376         "decl %1\n\t"
 377         "cmpb $0,(%1)\n\t"
 378         "je 7f\n\t"
 379         "movl %1,%0\n"
 380         "3:\tlodsb\n\t"
 381         "testb %%al,%%al\n\t"
 382         "je 5f\n\t"
 383         "movl %4,%%edi\n\t"
 384         "movl %%edx,%%ecx\n\t"
 385         "repne\n\t"
 386         "scasb\n\t"
 387         "jne 3b\n\t"
 388         "decl %1\n\t"
 389         "cmpb $0,(%1)\n\t"
 390         "je 5f\n\t"
 391         "movb $0,(%1)\n\t"
 392         "incl %1\n\t"
 393         "jmp 6f\n"
 394         "5:\txorl %1,%1\n"
 395         "6:\tcmpb $0,(%0)\n\t"
 396         "jne 7f\n\t"
 397         "xorl %0,%0\n"
 398         "7:\ttestl %0,%0\n\t"
 399         "jne 8f\n\t"
 400         "movl %0,%1\n"
 401         "8:"
 402         :"=b" (__res),"=S" (___strtok)
 403         :"0" (___strtok),"1" (s),"g" (ct)
 404         :"ax","cx","dx","di","memory");
 405 return __res;
 406 }
 407 
 408 #define __memcpy_c(d,s,count) \
 409 ((count%4==0) ? \
 410  __memcpy_by4((d),(s),(count)) : \
 411  ((count%2==0) ? \
 412   __memcpy_by2((d),(s),(count)) : \
 413   __memcpy_g((d),(s),(count))))
 414 
 415 #define __HAVE_ARCH_MEMCPY
 416 #define memcpy(d,s,count) \
 417 (__builtin_constant_p(count) ? \
 418  __memcpy_c((d),(s),(count)) : \
 419  __memcpy_g((d),(s),(count)))
 420 
 421 /*
 422  *      These ought to get tweaked to do some cache priming.
 423  */
 424  
 425 extern inline void * __memcpy_by4(void * to, const void * from, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 426 {
 427 register void *tmp = (void *)to;
 428 register int dummy1,dummy2;
 429 __asm__ __volatile__ (
 430         "\n1:\tmovl (%2),%0\n\t"
 431         "addl $4,%2\n\t"
 432         "movl %0,(%1)\n\t"
 433         "addl $4,%1\n\t"
 434         "decl %3\n\t"
 435         "jnz 1b"
 436         :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) 
 437         :"1" (tmp), "2" (from), "3" (n/4)
 438         :"memory");
 439 return (to);
 440 }
 441 
 442 extern inline void * __memcpy_by2(void * to, const void * from, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 443 {
 444 register void *tmp = (void *)to;
 445 register int dummy1,dummy2;
 446 __asm__ __volatile__ (
 447         "shrl $1,%3\n\t"
 448         "jz 2f\n"                 /* only a word */
 449         "1:\tmovl (%2),%0\n\t"
 450         "addl $4,%2\n\t"
 451         "movl %0,(%1)\n\t"
 452         "addl $4,%1\n\t"
 453         "decl %3\n\t"
 454         "jnz 1b\n"
 455         "2:\tmovw (%2),%w0\n\t"
 456         "movw %w0,(%1)"
 457         :"=r" (dummy1), "=r" (tmp), "=r" (from), "=r" (dummy2) 
 458         :"1" (tmp), "2" (from), "3" (n/2)
 459         :"memory");
 460 return (to);
 461 }
 462 
 463 extern inline void * __memcpy_g(void * to, const void * from, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 464 {
 465 register void *tmp = (void *)to;
 466 __asm__ __volatile__ (
 467         "cld\n\t"
 468         "shrl $1,%%ecx\n\t"
 469         "jnc 1f\n\t"
 470         "movsb\n"
 471         "1:\tshrl $1,%%ecx\n\t"
 472         "jnc 2f\n\t"
 473         "movsw\n"
 474         "2:\trep\n\t"
 475         "movsl"
 476         : /* no output */
 477         :"c" (n),"D" ((long) tmp),"S" ((long) from)
 478         :"cx","di","si","memory");
 479 return (to);
 480 }
 481 
 482 
 483 #define __HAVE_ARCH_MEMMOVE
 484 extern inline void * memmove(void * dest,const void * src, size_t n)
     /* [previous][next][first][last][top][bottom][index][help] */
 485 {
 486 register void *tmp = (void *)dest;
 487 if (dest<src)
 488 __asm__ __volatile__ (
 489         "cld\n\t"
 490         "rep\n\t"
 491         "movsb"
 492         : /* no output */
 493         :"c" (n),"S" (src),"D" (tmp)
 494         :"cx","si","di");
 495 else
 496 __asm__ __volatile__ (
 497         "std\n\t"
 498         "rep\n\t"
 499         "movsb\n\t"
 500         : /* no output */
 501         :"c" (n), "S" (n-1+(const char *)src), "D" (n-1+(char *)tmp)
 502         :"cx","si","di","memory");
 503 return dest;
 504 }
 505 
 506 extern inline int memcmp(const void * cs,const void * ct,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 507 {
 508 register int __res;
 509 __asm__ __volatile__(
 510         "cld\n\t"
 511         "repe\n\t"
 512         "cmpsb\n\t"
 513         "je 1f\n\t"
 514         "sbbl %0,%0\n\t"
 515         "orb $1,%b0\n"
 516         "1:"
 517         :"=abd" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
 518         :"si","di","cx");
 519 return __res;
 520 }
 521 
 522 #define __HAVE_ARCH_MEMCHR
 523 extern inline void * memchr(const void * cs,int c,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 524 {
 525 register void * __res;
 526 if (!count)
 527         return NULL;
 528 __asm__ __volatile__(
 529         "cld\n\t"
 530         "repne\n\t"
 531         "scasb\n\t"
 532         "je 1f\n\t"
 533         "movl $1,%0\n"
 534         "1:\tdecl %0"
 535         :"=D" (__res):"a" (c),"D" (cs),"c" (count)
 536         :"cx");
 537 return __res;
 538 }
 539 
 540 #define __memset_cc(s,c,count) \
 541 ((count%4==0) ? \
 542  __memset_cc_by4((s),(c),(count)) : \
 543  ((count%2==0) ? \
 544   __memset_cc_by2((s),(c),(count)) : \
 545   __memset_cg((s),(c),(count))))
 546 
 547 #define __memset_gc(s,c,count) \
 548 ((count%4==0) ? \
 549  __memset_gc_by4((s),(c),(count)) : \
 550  ((count%2==0) ? \
 551   __memset_gc_by2((s),(c),(count)) : \
 552   __memset_gg((s),(c),(count))))
 553 
 554 #define __HAVE_ARCH_MEMSET
 555 #define memset(s,c,count) \
 556 (__builtin_constant_p(c) ? \
 557  (__builtin_constant_p(count) ? \
 558   __memset_cc((s),(c),(count)) : \
 559   __memset_cg((s),(c),(count))) : \
 560  (__builtin_constant_p(count) ? \
 561   __memset_gc((s),(c),(count)) : \
 562   __memset_gg((s),(c),(count))))
 563 
 564 extern inline void * __memset_cc_by4(void * s, char c, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 565 {
 566 /*
 567  * register char *tmp = s;
 568  */
 569 register char *tmp = (char *)s;
 570 register int  dummy;
 571 __asm__ __volatile__ (
 572         "\n1:\tmovl %2,(%0)\n\t"
 573         "addl $4,%0\n\t"
 574         "decl %1\n\t"
 575         "jnz 1b"
 576         :"=r" (tmp), "=r" (dummy)
 577         :"q" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/4)
 578         :"memory");
 579 return s;
 580 }
 581 
 582 extern inline void * __memset_cc_by2(void * s, char c, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 583 {
 584 register void *tmp = (void *)s;
 585 register int  dummy;
 586 __asm__ __volatile__ (
 587         "shrl $1,%1\n\t"          /* may be divisible also by 4 */
 588         "jz 2f\n"
 589         "\n1:\tmovl %2,(%0)\n\t"
 590         "addl $4,%0\n\t"
 591         "decl %1\n\t"
 592         "jnz 1b\n"
 593         "2:\tmovw %w2,(%0)"
 594         :"=r" (tmp), "=r" (dummy)
 595         :"q" (0x01010101UL * (unsigned char) c), "0" (tmp), "1" (count/2)
 596         :"memory");
 597 return s;
 598 }
 599 
 600 extern inline void * __memset_gc_by4(void * s, char c, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 601 {
 602 register void *tmp = (void *)s;
 603 register int dummy;
 604 __asm__ __volatile__ (
 605         "movb %b0,%h0\n"
 606         "pushw %w0\n\t"
 607         "shll $16,%0\n\t"
 608         "popw %w0\n"
 609         "1:\tmovl %0,(%1)\n\t"
 610         "addl $4,%1\n\t"
 611         "decl %2\n\t"
 612         "jnz 1b\n"
 613         :"=q" (c), "=r" (tmp), "=r" (dummy)
 614         :"0" ((unsigned) c),  "1"  (tmp), "2" (count/4)
 615         :"memory");
 616 return s;
 617 }
 618 
 619 extern inline void * __memset_gc_by2(void * s, char c, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 620 {
 621 register void *tmp = (void *)s;
 622 register int dummy1,dummy2;
 623 __asm__ __volatile__ (
 624         "movb %b0,%h0\n\t"
 625         "shrl $1,%2\n\t"          /* may be divisible also by 4 */
 626         "jz 2f\n\t"
 627         "pushw %w0\n\t"
 628         "shll $16,%0\n\t"
 629         "popw %w0\n"
 630         "1:\tmovl %0,(%1)\n\t"
 631         "addl $4,%1\n\t"
 632         "decl %2\n\t"
 633         "jnz 1b\n"
 634         "2:\tmovw %w0,(%1)"
 635         :"=q" (dummy1), "=r" (tmp), "=r" (dummy2)
 636         :"0" ((unsigned) c),  "1"  (tmp), "2" (count/2)
 637         :"memory");
 638 return s;
 639 }
 640 
 641 extern inline void * __memset_cg(void * s, char c, size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 642 {
 643 register void *tmp = (void *)s;
 644 __asm__ __volatile__ (
 645         "shrl $1,%%ecx\n\t"
 646         "rep\n\t"
 647         "stosw\n\t"
 648         "jnc 1f\n\t"
 649         "movb %%al,(%%edi)\n"
 650         "1:"
 651         : /* no output */
 652         :"c" (count),"D" (tmp), "a" (0x0101U * (unsigned char) c)
 653         :"cx","di","memory");
 654 return s;
 655 }
 656 
 657 extern inline void * __memset_gg(void * s,char c,size_t count)
     /* [previous][next][first][last][top][bottom][index][help] */
 658 {
 659 register void *tmp = (void *)s;
 660 __asm__ __volatile__ (
 661         "movb %%al,%%ah\n\t"
 662         "shrl $1,%%ecx\n\t"
 663         "rep\n\t"
 664         "stosw\n\t"
 665         "jnc 1f\n\t"
 666         "movb %%al,(%%edi)\n"
 667         "1:"
 668         : /* no output */
 669         :"c" (count),"D" (tmp), "a" (c)
 670         :"cx","di","memory");
 671 return s;
 672 }
 673 
 674 
 675 /*
 676  * find the first occurrence of byte 'c', or 1 past the area if none
 677  */
 678 #define __HAVE_ARCH_MEMSCAN
 679 extern inline void * memscan(void * addr, int c, size_t size)
     /* [previous][next][first][last][top][bottom][index][help] */
 680 {
 681         if (!size)
 682                 return addr;
 683         __asm__("cld
 684                 repnz; scasb
 685                 jnz 1f
 686                 dec %%edi
 687 1:              "
 688                 : "=D" (addr), "=c" (size)
 689                 : "0" (addr), "1" (size), "a" (c));
 690         return addr;
 691 }
 692 
 693 #endif

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