home *** CD-ROM | disk | FTP | other *** search
/ Serving the Web / ServingTheWeb1995.disc1of1.iso / linux / slacksrce / d / libc / libc-4.6 / libc-4 / libc-linux / sysdeps / i386 / strlen.c.new < prev    next >
Encoding:
Text File  |  1994-12-13  |  3.7 KB  |  140 lines

  1. /* strlen(str) -- determine the length of the string STR.
  2.    For Intel 80x86, x>=3.
  3.    Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc.
  4.    i386 version: Contributed by Torbjorn Granlund (tege@sics.se).
  5.    i[45]86 version: Contributed by Ulrich Drepper <drepper@ira.uka.de>.
  6.  
  7. The GNU C Library is free software; you can redistribute it and/or
  8. modify it under the terms of the GNU Library General Public License as
  9. published by the Free Software Foundation; either version 2 of the
  10. License, or (at your option) any later version.
  11.  
  12. The GNU C Library is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15. Library General Public License for more details.
  16.  
  17. You should have received a copy of the GNU Library General Public
  18. License along with the GNU C Library; see the file COPYING.LIB.  If
  19. not, write to the Free Software Foundation, Inc., 675 Mass Ave,
  20. Cambridge, MA 02139, USA.  */
  21.  
  22. #include <ansidecl.h>
  23. #include <string.h>
  24.  
  25. #include "asm-ops.h"
  26.  
  27. size_t
  28. strlen(const char *str)
  29. {
  30. register size_t __res;
  31.  
  32. __asm__(
  33. #if !defined(__i486__) && !defined(__i586__)
  34. /*
  35.  * We have to use two different versions, one for i386 and for the rest
  36.  * because the difference is so big.  Be aware when the name of the i586
  37.  * (aka Pentium) in the gcc changes (I assume __i586__) or the next
  38.  * generation (i686) is available.
  39.  */
  40.         "cld\n\t"
  41.     "repne\n\t"
  42.     "scasb\n\t"
  43.     "notl %3\n\t"
  44.     "leal -1(%3),%0"
  45.     :"=a" (__res):"D" (str),"0" (0),"c" (0xffffffff):"cx","di");
  46. #else
  47.         /* test the first bytes seperately until aligned */
  48.     "movl %1,%%ecx\n\t"
  49.     "andl $3,%%ecx\n\t"
  50.     "jz " LF(1) "\n\t"
  51.     "testb $0xff,(%1)\n\t"
  52.     "jz " LF(2) "\n\t"
  53.     "incl %0\n\t"
  54.     "decl %%ecx\n\t"
  55.     "jz " LF(1) "\n\t"
  56.     "testb $0xff,(%1,%0)\n\t"
  57.     "jz " LF(2) "\n\t"
  58.     "incl %0\n\t"
  59.     "decl %%ecx\n\t"
  60.     "jz " LF(1) "\n\t"
  61.     "testb $0xff,(%1,%0)\n\t"
  62.     "jz " LF(2) "\n\t"
  63.     "incl %0\n"
  64.  
  65.     /* If you cannot guess what this is for look through the resulting
  66.      * code.  The dumb version has an .align at the end of the conditional
  67.      * region.  This is quite long.  If we could make the jump to the
  68.      * label '1' behind the NOPs we could save the time in 75% of the
  69.      * cases without any costs.  Exactly this is done here. if anything
  70.      * in the prepending code changes the number of NOPs may have to
  71.      * change, too.  */
  72.  
  73. #if defined(I_DONT_KNOW_WHAT_THIS_MEANS)
  74. LL(1)    "\tsubl $16,%0\n\t"
  75.  
  76.     ALIGN "\n"
  77. #else
  78.     "\tnop; nop; nop; nop; nop\n\t"
  79.     "nop; nop; nop; nop\n"
  80. LL(1)   "\tsubl $16,%0\n"
  81. #endif
  82.  
  83. LL(4)    "\taddl $16,%0\n\t"
  84.  
  85.     "movl (%1,%0),%%ecx\n\t"
  86.     "movl %%ecx,%%edi\n\t"
  87.     "addl $0xfefefeff,%%edi\n\t"
  88.     "jnc " LF(3) "\n\t"
  89.     "xorl %%ecx,%%edi\n\t"
  90.     "notl %%edi\n\t"
  91.     "andl $0x01010100,%%edi\n\t"
  92.     "jnz " LF(3) "\n\t"
  93.     
  94.     "movl 4(%1,%0),%%ecx\n\t"
  95.     "movl %%ecx,%%edi\n\t"
  96.     "addl $0xfefefeff,%%edi\n\t"
  97.     "jnc " LF(5) "\n\t"
  98.     "xorl %%ecx,%%edi\n\t"
  99.     "notl %%edi\n\t"
  100.     "andl $0x01010100,%%edi\n\t"
  101.     "jnz " LF(5) "\n\t"
  102.     
  103.     "movl 8(%1,%0),%%ecx\n\t"
  104.     "movl %%ecx,%%edi\n\t"
  105.     "addl $0xfefefeff,%%edi\n\t"
  106.     "jnc " LF(6) "\n\t"
  107.     "xorl %%ecx,%%edi\n\t"
  108.     "notl %%edi\n\t"
  109.     "andl $0x01010100,%%edi\n\t"
  110.     "jnz " LF(6) "\n\t"
  111.     
  112.     "movl 12(%1,%0),%%ecx\n\t"
  113.     "movl %%ecx,%%edi\n\t"
  114.     "addl $0xfefefeff,%%edi\n\t"
  115.     "jnc " LF(7) "\n\t"
  116.     "xorl %%ecx,%%edi\n\t"
  117.     "notl %%edi\n\t"
  118.     "andl $0x01010100,%%edi\n\t"
  119.     "jz " LB(4) "\n"
  120.  
  121. LL(7)    "\taddl $4,%0\n"
  122. LL(6)    "\taddl $4,%0\n"
  123. LL(5)    "\taddl $4,%0\n"
  124.  
  125. LL(3)    "\ttestb $0xff,%%cl\n\t"
  126.     "jz " LF(2) "\n\t"
  127.     "incl %0\n\t"
  128.     "testb $0xff,%%ch\n\t"
  129.     "jz " LF(2) "\n\t"
  130.     "incl %0\n\t"
  131.     "testl $0xff0000,%%ecx\n\t"
  132.     "jz " LF(2) "\n\t"
  133.     "incl %0\n"
  134. LL(2)    
  135.     :"=a" (__res):"d" (str),"0" (0):"cx","dx","di");
  136. #endif
  137.  
  138. return __res;
  139. }
  140.