Back to index

glibc  2.9
memmove.c
Go to the documentation of this file.
00001 /* Copy memory to memory until the specified number of bytes
00002    has been copied.  Overlap is handled correctly.
00003    Copyright (C) 1991, 1995, 1996, 1997, 2003 Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005    Contributed by Torbjorn Granlund (tege@sics.se).
00006 
00007    The GNU C Library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public
00009    License as published by the Free Software Foundation; either
00010    version 2.1 of the License, or (at your option) any later version.
00011 
00012    The GNU C Library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License along with the GNU C Library; if not, write to the Free
00019    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00020    02111-1307 USA.  */
00021 
00022 #include <string.h>
00023 #include <memcopy.h>
00024 #include <pagecopy.h>
00025 
00026 /* All this is so that bcopy.c can #include
00027    this file after defining some things.  */
00028 #ifndef       a1
00029 #define       a1     dest   /* First arg is DEST.  */
00030 #define       a1const
00031 #define       a2     src    /* Second arg is SRC.  */
00032 #define       a2const       const
00033 #undef memmove
00034 #endif
00035 #if    !defined(RETURN) || !defined(rettype)
00036 #define       RETURN(s)     return (s)    /* Return DEST.  */
00037 #define       rettype              void *
00038 #endif
00039 
00040 
00041 rettype
00042 memmove (a1, a2, len)
00043      a1const void *a1;
00044      a2const void *a2;
00045      size_t len;
00046 {
00047   unsigned long int dstp = (long int) dest;
00048   unsigned long int srcp = (long int) src;
00049 
00050   /* This test makes the forward copying code be used whenever possible.
00051      Reduces the working set.  */
00052   if (dstp - srcp >= len)   /* *Unsigned* compare!  */
00053     {
00054       /* Copy from the beginning to the end.  */
00055 
00056       /* If there not too few bytes to copy, use word copy.  */
00057       if (len >= OP_T_THRES)
00058        {
00059          /* Copy just a few bytes to make DSTP aligned.  */
00060          len -= (-dstp) % OPSIZ;
00061          BYTE_COPY_FWD (dstp, srcp, (-dstp) % OPSIZ);
00062 
00063          /* Copy whole pages from SRCP to DSTP by virtual address
00064             manipulation, as much as possible.  */
00065 
00066          PAGE_COPY_FWD_MAYBE (dstp, srcp, len, len);
00067 
00068          /* Copy from SRCP to DSTP taking advantage of the known
00069             alignment of DSTP.  Number of bytes remaining is put
00070             in the third argument, i.e. in LEN.  This number may
00071             vary from machine to machine.  */
00072 
00073          WORD_COPY_FWD (dstp, srcp, len, len);
00074 
00075          /* Fall out and copy the tail.  */
00076        }
00077 
00078       /* There are just a few bytes to copy.  Use byte memory operations.  */
00079       BYTE_COPY_FWD (dstp, srcp, len);
00080     }
00081   else
00082     {
00083       /* Copy from the end to the beginning.  */
00084       srcp += len;
00085       dstp += len;
00086 
00087       /* If there not too few bytes to copy, use word copy.  */
00088       if (len >= OP_T_THRES)
00089        {
00090          /* Copy just a few bytes to make DSTP aligned.  */
00091          len -= dstp % OPSIZ;
00092          BYTE_COPY_BWD (dstp, srcp, dstp % OPSIZ);
00093 
00094          /* Copy from SRCP to DSTP taking advantage of the known
00095             alignment of DSTP.  Number of bytes remaining is put
00096             in the third argument, i.e. in LEN.  This number may
00097             vary from machine to machine.  */
00098 
00099          WORD_COPY_BWD (dstp, srcp, len, len);
00100 
00101          /* Fall out and copy the tail.  */
00102        }
00103 
00104       /* There are just a few bytes to copy.  Use byte memory operations.  */
00105       BYTE_COPY_BWD (dstp, srcp, len);
00106     }
00107 
00108   RETURN (dest);
00109 }
00110 #ifndef memmove
00111 libc_hidden_builtin_def (memmove)
00112 #endif