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 / __stpncpy.c.new < prev    next >
Encoding:
Text File  |  1994-12-13  |  3.4 KB  |  129 lines

  1. /* stpncpy -- copy no more then N bytes from SRC to DEST, returning the
  2.           address of the terminating '\0' in DEST.
  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. /* This function is defined neither in ANSI nor POSIX standards but is
  23.    also not invented here.  */
  24.  
  25. #include <string.h>
  26. #include "asm-ops.h"
  27.  
  28. char *
  29. __stpncpy(char * dest, const char * src, size_t n)
  30. {
  31. register char * __res;
  32. __asm__("subl %0,%1\n\t"
  33.     "addl $4,%3\n\t"
  34.     "subl $4,%0\n"        /* prepare loop */
  35.  
  36.     /* Four time unfolded loop with two loop counters.  We get the
  37.      * the third value (the source address) by using the index+base
  38.      * adressing mode.
  39.      */
  40. LL(1)    "\taddl $4,%0\n\t"    /* increment loop counter */
  41.  
  42.     "subl $4,%3\n\t"    /* decrement length counter */
  43.     "testl $0xfffffffc,%3\n\t"
  44.     "je " LF(4) "\n\t"    /* less than 3 chars left, than branch */
  45.  
  46.     "movb (%0,%1),%%dl\n\t"
  47.     "movb %%dl,(%0)\n\t"
  48.     "testb %%dl,%%dl\n\t"    /* if last character */
  49.     "je " LF(3) "\n\t"    /* than exit */
  50.  
  51.     "movb 1(%0,%1),%%dl\n\t"
  52.     "movb %%dl,1(%0)\n\t"
  53.     "testb %%dl,%%dl\n\t"
  54.     "je " LF(6) "\n\t"
  55.  
  56.     "movb 2(%0,%1),%%dl\n\t"
  57.     "movb %%dl,2(%0)\n\t"
  58.     "testb %%dl,%%dl\n\t"
  59.     "je " LF(5) "\n\t"
  60.  
  61.     "movb 3(%0,%1),%%dl\n\t"
  62.     "movb %%dl,3(%0)\n\t"
  63.     "testb %%dl,%%dl\n\t"
  64.     "jne " LB(1) "\n\t"
  65.  
  66.     "decl %3\n\t"        /* correct counters */
  67.     "incl %0\n"
  68. LL(5)    "\tdecl %3\n\t"
  69.     "incl %0\n"
  70. LL(6)    "\tdecl %3\n\t"
  71.     "incl %0\n\t"
  72.     "jmp " LF(3) "\n"
  73.  
  74.     /* Process rest of string byte by byte.  */
  75. LL(4)    "testb %3,%3\n\t"
  76.     "je " LF(2) "\n\t"
  77.     "movb (%0,%1),%%dl\n\t"
  78.     "movb %%dl,(%0)\n\t"
  79.     "incl %0\n\t"
  80.     "testb %%dl,%%dl\n\t"
  81.     "je " LF(32) "\n\t"
  82.     "decl %3\n\t"
  83.     "je " LF(2) "\n\t"
  84.  
  85.     "movb (%0,%1),%%dl\n\t"
  86.     "movb %%dl,(%0)\n\t"
  87.     "incl %0\n\t"
  88.     "testb %%dl,%%dl\n\t"
  89.     "je " LF(32) "\n\t"
  90.     "decl %3\n\t"
  91.     "je " LF(2) "\n\t"
  92.  
  93.     "movb (%0,%1),%%dl\n\t"
  94.     "movb %%dl,(%0)\n\t"
  95.     "incl %0\n\t"
  96.     "testb %%dl,%%dl\n\t"
  97.     "je " LF(32) "\n\t"
  98.     "decl %3\n\t"
  99.     "je " LF(2) "\n\t"
  100.  
  101. /* fill with zero.  Here is a difference between how I understand the
  102.    function and how it is implemented in the GNU libc (1.09).  In glibc
  103.    the pointer returned is to the LAST '\0' written.  But I think is more
  104.    useful to point to the '\0' terminating the string.
  105.  
  106.    Roland McGrath agreed with me on this.  Hopefully in one of the next GNU
  107.    libc releases it will be changed.  */
  108.  
  109. #ifdef GLIBC_COMPAT
  110. LL(3)    "\tmovb $0,(%0)\n\t"
  111.     "incl %0\n"
  112. LL(32)    "\tdecl %3\n\t"
  113. #else
  114. LL(3)    "\tmovb $0,(%3,%0)\n"
  115. LL(32)    "decl %3\n\t"
  116. #endif
  117.     "jne " LB(3) "\n"
  118. LL(2)    "movb $0,(%0)\n\t"
  119.     :"=a" (__res):"S" (src),"0" (dest),"c" (n):"si","cx","dx");
  120. return __res;
  121. }
  122.  
  123. #include <gnu-stabs.h>
  124. #ifdef weak_alias
  125. weak_alias (__stpncpy, stpncpy);
  126. #endif
  127.  
  128.  
  129.