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 / strpbrk.c.new < prev    next >
Encoding:
Text File  |  1994-12-13  |  6.0 KB  |  199 lines

  1. /* strpbrk (str, ss) -- Find the first occurence in STR of any character
  2.             in 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. char *
  27. strpbrk(const char *str, const char *stopset)
  28. {
  29. register char * __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.     ALIGN "\n"
  105.  
  106. LL(2)    "\tmovb (%0),%%cl\n\t"        /* get char from stopset */
  107.     "movb %%cl,-256(%%esp,%%ecx)\n\t" /* mark as stop character in table */
  108.     "testl %%ecx,%%ecx\n\t"        /* was NULL char */
  109.     "jz " LF(1) "\n\t"        /* yes, than stop */
  110.  
  111.     "movb 1(%0),%%cl\n\t"
  112.     "movb %%cl,-256(%%esp,%%ecx)\n\t"
  113.     "test %%ecx,%%ecx\n\t"
  114.     "jz " LF(1) "\n\t"
  115.  
  116.     "movb 2(%0),%%cl\n\t"
  117.     "movb %%cl,-256(%%esp,%%ecx)\n\t"
  118.     "test %%ecx,%%ecx\n\t"
  119.     "jz " LF(1) "\n\t"
  120.  
  121.     "movb 3(%0),%%cl\n\t"
  122.     "addl $4,%0\n\t"        /* add loop increment */
  123.     "movb %%cl,-256(%%esp,%%ecx)\n\t"
  124.     "test %%ecx,%%ecx\n\t"
  125.     "jnz " LB(2) "\n"
  126.  
  127.     /* We use two asm statements because we don't want to do the
  128.      * argument in the asm code.  In the first part we need the stopset
  129.      * and in the second the string.  By this splitting we don't need
  130.      * another register.
  131.      */
  132.  
  133.     /* If you cannot guess what this is for look through the resulting
  134.      * code.  The dumb version has an .align at the beginning of the
  135.      * following asm statement.  This is quite long.  If we could
  136.      * make the jump to the label '1' behind the NOPs we could save
  137.      * the time in 75% of the cases.  Exactly this is done here.
  138.      * If anything in the prepending code changes the number of NOPs
  139.      * may have to change, too.  */
  140.  
  141. #if (!defined(__i486__) && !defined(__i586__)) || \
  142.     defined(I_DONT_KNOW_WHAT_THIS_MEANS)
  143. LL(1)    "incl -256(%%esp)\n\t"        /* This is another trick.  We mark the
  144.                      * NULL character as a stop char.
  145.                      */
  146.     : :"d" (stopset):"cx","ax");
  147.  
  148. __asm__("subl $4,%0\n\t"
  149.     ALIGN "\n"
  150. #else
  151.     "\tnop; nop; nop; nop; nop; nop; nop; nop\n"
  152. LL(1)    "\tincl -256(%%esp)\n\t"    /* This is another trick.  We mark the
  153.                      * NULL character as a stop char.
  154.                      */
  155.     : :"d" (stopset):"ax");
  156.  
  157. __asm__("subl $4,%0\n"
  158. #endif
  159.  
  160.     /* At this point of the execution %eax contains the value -4
  161.      * (see above).
  162.      */
  163.  
  164.     /* We use the base+index adressing mode because by this mean we only
  165.      * have to increment one counter in the loop which can also serve
  166.      * as the string length counter which is the result.
  167.      */
  168.  
  169. LL(3)    "\taddl $4,%0\n\t"
  170.  
  171.     "movb (%0),%%cl\n\t"    /* get current string character */
  172.     "testb $0xff,-256(%%esp,%%ecx)\n\t" /* is char set in table ? */
  173.     "jnz " LF(4) "\n\t"        /* yes, than exit */
  174.  
  175.     "movb 1(%0),%%cl\n\t"
  176.     "testb $0xff,-256(%%esp,%%ecx)\n\t"
  177.     "jnz " LF(5) "\n\t"
  178.  
  179.     "movb 2(%0),%%cl\n\t"
  180.     "testb $0xff,-256(%%esp,%%ecx)\n\t"
  181.     "jnz " LF(6) "\n\t"
  182.  
  183.     "movb 3(%0),%%cl\n\t"
  184.     "testb $0xff,-256(%%esp,%%ecx)\n\t"
  185.     "jz " LB(3) "\n\t"
  186.  
  187.     "incl %0\n"            /* correct result length counter */
  188. LL(6)    "\tincl %0\n"
  189. LL(5)    "\tincl %0\n"
  190.  
  191. LL(4)    "\torb %%cl,%%cl\n\t"        /* If the loop ended because of the */
  192.     "jnz " LF(7) "\n\t"        /* end of the string */
  193.     "xorl %0,%0\n"            /* return NULL */
  194.  
  195. LL(7)
  196.     :"=a" (__res):"0" (str):"cx");
  197. return __res;
  198. }
  199.