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 / strspn.c.new < prev    next >
Encoding:
Text File  |  1994-12-13  |  6.2 KB  |  202 lines

  1. /* strspn (str, ss) -- Return the length of the initial segement of STR
  2.                which contains only characters from SS.
  3.    For Intel 80x86, x>=3.
  4.    Copyright (C) 1994 Free Software Foundation, Inc.
  5.    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 <string.h>
  23.  
  24. #include "asm-ops.h"
  25.  
  26. size_t
  27. strspn(const char *str, const char *skipset)
  28. {
  29. register size_t __res;
  30. __asm__(
  31.     /*
  32.      * First we create a table with flags for all possible characters.
  33.      * For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
  34.      * supported by the C string functions we have 256 characters.
  35.      * Before inserting marks for the stop characters we clear the whole
  36.      * table.  The unrolled form is much faster than a loop.
  37.      */
  38.     "xorl %%ecx,%%ecx\n\t"        /* Put 0 in a register because the */
  39.     "movl %%ecx,-4(%%esp)\n\t"    /* resulting code for all the moves */
  40.     "movl %%ecx,-8(%%esp)\n\t"    /* is a lot shorter.  */
  41.     "movl %%ecx,-12(%%esp)\n\t"
  42.     "movl %%ecx,-16(%%esp)\n\t"
  43.     "movl %%ecx,-20(%%esp)\n\t"
  44.     "movl %%ecx,-24(%%esp)\n\t"
  45.     "movl %%ecx,-28(%%esp)\n\t"
  46.     "movl %%ecx,-32(%%esp)\n\t"
  47.     "movl %%ecx,-36(%%esp)\n\t"
  48.     "movl %%ecx,-40(%%esp)\n\t"
  49.     "movl %%ecx,-44(%%esp)\n\t"
  50.     "movl %%ecx,-48(%%esp)\n\t"
  51.     "movl %%ecx,-52(%%esp)\n\t"
  52.     "movl %%ecx,-56(%%esp)\n\t"
  53.     "movl %%ecx,-60(%%esp)\n\t"
  54.     "movl %%ecx,-64(%%esp)\n\t"
  55.     "movl %%ecx,-68(%%esp)\n\t"
  56.     "movl %%ecx,-72(%%esp)\n\t"
  57.     "movl %%ecx,-76(%%esp)\n\t"
  58.     "movl %%ecx,-80(%%esp)\n\t"
  59.     "movl %%ecx,-84(%%esp)\n\t"
  60.     "movl %%ecx,-88(%%esp)\n\t"
  61.     "movl %%ecx,-92(%%esp)\n\t"
  62.     "movl %%ecx,-96(%%esp)\n\t"
  63.     "movl %%ecx,-100(%%esp)\n\t"
  64.     "movl %%ecx,-104(%%esp)\n\t"
  65.     "movl %%ecx,-108(%%esp)\n\t"
  66.     "movl %%ecx,-112(%%esp)\n\t"
  67.     "movl %%ecx,-116(%%esp)\n\t"
  68.     "movl %%ecx,-120(%%esp)\n\t"
  69.     "movl %%ecx,-124(%%esp)\n\t"
  70.     "movl %%ecx,-128(%%esp)\n\t"
  71.     "movl %%ecx,-132(%%esp)\n\t"
  72.     "movl %%ecx,-136(%%esp)\n\t"
  73.     "movl %%ecx,-140(%%esp)\n\t"
  74.     "movl %%ecx,-144(%%esp)\n\t"
  75.     "movl %%ecx,-148(%%esp)\n\t"
  76.     "movl %%ecx,-152(%%esp)\n\t"
  77.     "movl %%ecx,-156(%%esp)\n\t"
  78.     "movl %%ecx,-160(%%esp)\n\t"
  79.     "movl %%ecx,-164(%%esp)\n\t"
  80.     "movl %%ecx,-168(%%esp)\n\t"
  81.     "movl %%ecx,-172(%%esp)\n\t"
  82.     "movl %%ecx,-176(%%esp)\n\t"
  83.     "movl %%ecx,-180(%%esp)\n\t"
  84.     "movl %%ecx,-184(%%esp)\n\t"
  85.     "movl %%ecx,-188(%%esp)\n\t"
  86.     "movl %%ecx,-192(%%esp)\n\t"
  87.     "movl %%ecx,-196(%%esp)\n\t"
  88.     "movl %%ecx,-200(%%esp)\n\t"
  89.     "movl %%ecx,-204(%%esp)\n\t"
  90.     "movl %%ecx,-208(%%esp)\n\t"
  91.     "movl %%ecx,-212(%%esp)\n\t"
  92.     "movl %%ecx,-216(%%esp)\n\t"
  93.     "movl %%ecx,-220(%%esp)\n\t"
  94.     "movl %%ecx,-224(%%esp)\n\t"
  95.     "movl %%ecx,-228(%%esp)\n\t"
  96.     "movl %%ecx,-232(%%esp)\n\t"
  97.     "movl %%ecx,-236(%%esp)\n\t"
  98.     "movl %%ecx,-240(%%esp)\n\t"
  99.     "movl %%ecx,-244(%%esp)\n\t"
  100.     "movl %%ecx,-248(%%esp)\n\t"
  101.     "movl %%ecx,-252(%%esp)\n\t"
  102.     "movl %%ecx,-256(%%esp)\n\t"
  103.  
  104.     "movl $-4,%%eax\n\t"        /* This is a trick.  For i486 alignment
  105.                      * here would be a big NOP hole.  We
  106.                      * can use this hole for setting some
  107.                      * registers for the following code.
  108.                      * Eax is not used in this asm stat.
  109.                      * but in the following (see below).
  110.                      */
  111.     ALIGN "\n"
  112.  
  113. LL(2)    "\tmovb (%0),%%cl\n\t"        /* get char from stopset */
  114.     "movb %%cl,-256(%%esp,%%ecx)\n\t" /* mark as stop character in table */
  115.     "testl %%ecx,%%ecx\n\t"        /* was NULL char */
  116.     "jz " LF(1) "\n\t"        /* yes, than stop */
  117.  
  118.     "movb 1(%0),%%cl\n\t"
  119.     "movb %%cl,-256(%%esp,%%ecx)\n\t"
  120.     "test %%ecx,%%ecx\n\t"
  121.     "jz " LF(1) "\n\t"
  122.  
  123.     "movb 2(%0),%%cl\n\t"
  124.     "movb %%cl,-256(%%esp,%%ecx)\n\t"
  125.     "test %%ecx,%%ecx\n\t"
  126.     "jz " LF(1) "\n\t"
  127.  
  128.     "movb 3(%0),%%cl\n\t"
  129.     "addl $4,%0\n\t"        /* add loop increment */
  130.     "movb %%cl,-256(%%esp,%%ecx)\n\t"
  131.     "test %%ecx,%%ecx\n\t"
  132.     "jnz " LB(2) "\n"
  133.  
  134.     /* At this point all characters not in the skipset are not marked
  135.      * in the table.  Especially the NULL character is not marked
  136.      * altough The last move before the end of the loop wrote a NULL
  137.      * in the table.  But this NULL is the stop character.
  138.      */
  139.  
  140.     /* We use two asm statements because we don't want to do the
  141.      * argument in the asm code.  In the first part we need the stopset
  142.      * and in the second the string.  By this splitting we don't need
  143.      * another register.
  144.      */
  145.  
  146.     /* If you cannot guess what this is for look through the resulting
  147.      * code.  The dumb version has an .align at the beginning of the
  148.      * following asm statement.  This is quite long.  If we could
  149.      * make the jump to the label '1' behind the NOPs we would save
  150.      * the time in 75% of the cases.  Exactly this is done here.
  151.      * If anything in the prepending code changes the number of NOPs
  152.      * may have to change, too.
  153.      */
  154.  
  155. #if (!defined(__i486__) && !defined(__i586__)) || \
  156.     defined(I_DONT_KNOW_WHAT_THIS_MEANS)
  157. LL(1)
  158.     : :"d" (skipset):"ax");
  159.  
  160. __asm__(ALIGN "\n"
  161. #else
  162.     "\tnop; nop\n"
  163. LL(1)
  164.     : :"d" (skipset):"ax");
  165.  
  166. __asm__(
  167. #endif
  168.     /* At this point of the execution %eax contains the value -4
  169.      * (see above).
  170.      */
  171.  
  172.     /* We use the base+index adressing mode because by this mean we only
  173.      * have to increment one counter in the loop which can also serve
  174.      * as the string length counter which is the result.
  175.      */
  176.  
  177. LL(3)    "\taddl $4,%0\n\t"        /* add loop increment */
  178.  
  179.     "movb (%1,%0),%%cl\n\t"    /* get current string character */
  180.     "testb $0xff,-256(%%esp,%%ecx)\n\t" /* is char set in table ? */
  181.     "jz " LF(4) "\n\t"        /* no, than exit */
  182.  
  183.     "movb 1(%1,%0),%%cl\n\t"
  184.     "testb $0xff,-256(%%esp,%%ecx)\n\t"
  185.     "jz " LF(5) "\n\t"
  186.  
  187.     "movb 2(%1,%0),%%cl\n\t"
  188.     "testb $0xff,-256(%%esp,%%ecx)\n\t"
  189.     "jz " LF(6) "\n\t"
  190.  
  191.     "movb 3(%1,%0),%%cl\n\t"
  192.     "testb $0xff,-256(%%esp,%%ecx)\n\t"
  193.     "jnz " LB(3) "\n\t"
  194.  
  195.     "incl %0\n"            /* correct result length counter */
  196. LL(6)    "\tincl %0\n"
  197. LL(5)    "\tincl %0\n"
  198. LL(4)
  199.     :"=a" (__res):"d" (str):"cx");
  200. return __res;
  201. }
  202.