Back to index

glibc  2.9
memcopy.h
Go to the documentation of this file.
00001 /* memcopy.h -- definitions for memory copy functions.  Generic C version.
00002    Copyright (C) 1991, 1992, 1993, 1997, 2004, 2006 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Torbjorn Granlund (tege@sics.se).
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 /* The strategy of the memory functions is:
00022 
00023      1. Copy bytes until the destination pointer is aligned.
00024 
00025      2. Copy words in unrolled loops.  If the source and destination
00026      are not aligned in the same way, use word memory operations,
00027      but shift and merge two read words before writing.
00028 
00029      3. Copy the few remaining bytes.
00030 
00031    This is fast on processors that have at least 10 registers for
00032    allocation by GCC, and that can access memory at reg+const in one
00033    instruction.
00034 
00035    I made an "exhaustive" test of this memmove when I wrote it,
00036    exhaustive in the sense that I tried all alignment and length
00037    combinations, with and without overlap.  */
00038 
00039 #include <sysdeps/generic/memcopy.h>
00040 
00041 /* The macros defined in this file are:
00042 
00043    BYTE_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_to_copy)
00044 
00045    BYTE_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_to_copy)
00046 
00047    WORD_COPY_FWD(dst_beg_ptr, src_beg_ptr, nbytes_remaining, nbytes_to_copy)
00048 
00049    WORD_COPY_BWD(dst_end_ptr, src_end_ptr, nbytes_remaining, nbytes_to_copy)
00050 
00051    MERGE(old_word, sh_1, new_word, sh_2)
00052      [I fail to understand.  I feel stupid.  --roland]
00053 */
00054 
00055 
00056 /* Threshold value for when to enter the unrolled loops.  */
00057 #undef OP_T_THRES
00058 #define OP_T_THRES 16
00059 
00060 /* Copy exactly NBYTES bytes from SRC_BP to DST_BP,
00061    without any assumptions about alignment of the pointers.  */
00062 #undef BYTE_COPY_FWD
00063 #define BYTE_COPY_FWD(dst_bp, src_bp, nbytes)                               \
00064   do                                                                 \
00065     {                                                                \
00066       size_t __nbytes = (nbytes);                                    \
00067       if (__nbytes & 1)                                                     \
00068         {                                                            \
00069          ((byte *) dst_bp)[0] =  ((byte *) src_bp)[0];                      \
00070          src_bp += 1;                                                       \
00071          dst_bp += 1;                                                       \
00072          __nbytes -= 1;                                              \
00073         }                                                            \
00074       while (__nbytes > 0)                                           \
00075        {                                                             \
00076          byte __x = ((byte *) src_bp)[0];                            \
00077          byte __y = ((byte *) src_bp)[1];                            \
00078          src_bp += 2;                                                       \
00079          __nbytes -= 2;                                              \
00080          ((byte *) dst_bp)[0] = __x;                                        \
00081          ((byte *) dst_bp)[1] = __y;                                        \
00082          dst_bp += 2;                                                       \
00083        }                                                             \
00084     } while (0)
00085 
00086 /* Copy exactly NBYTES_TO_COPY bytes from SRC_END_PTR to DST_END_PTR,
00087    beginning at the bytes right before the pointers and continuing towards
00088    smaller addresses.  Don't assume anything about alignment of the
00089    pointers.  */
00090 #undef BYTE_COPY_BWD
00091 #define BYTE_COPY_BWD(dst_ep, src_ep, nbytes)                               \
00092   do                                                                 \
00093     {                                                                \
00094       size_t __nbytes = (nbytes);                                    \
00095       if (__nbytes & 1)                                                     \
00096         {                                                            \
00097          src_ep -= 1;                                                       \
00098          dst_ep -= 1;                                                       \
00099          ((byte *) dst_ep)[0] =  ((byte *) src_ep)[0];                      \
00100          __nbytes -= 1;                                              \
00101         }                                                            \
00102       while (__nbytes > 0)                                           \
00103        {                                                             \
00104          byte __x, __y;                                              \
00105          src_ep -= 2;                                                       \
00106          __y = ((byte *) src_ep)[1];                                        \
00107          __x = ((byte *) src_ep)[0];                                        \
00108          dst_ep -= 2;                                                       \
00109          __nbytes -= 2;                                              \
00110          ((byte *) dst_ep)[1] = __y;                                        \
00111          ((byte *) dst_ep)[0] = __x;                                        \
00112        }                                                             \
00113     } while (0)