Back to index

glibc  2.9
wordcopy.c
Go to the documentation of this file.
00001 /* _memcopy.c -- subroutines for memory copy functions.
00002    Copyright (C) 1991, 1996 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 /* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
00022 
00023 #include <stddef.h>
00024 #include <memcopy.h>
00025 
00026 /* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
00027    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
00028    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
00029 
00030 void
00031 _wordcopy_fwd_aligned (dstp, srcp, len)
00032      long int dstp;
00033      long int srcp;
00034      size_t len;
00035 {
00036   op_t a0, a1;
00037 
00038   if (len & 1)
00039   {
00040     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
00041     
00042     if (len == 1)
00043       return;
00044     srcp += OPSIZ;
00045     dstp += OPSIZ;
00046     len -= 1;
00047   }
00048 
00049   do
00050     {
00051       a0 = ((op_t *) srcp)[0];
00052       a1 = ((op_t *) srcp)[1];
00053       ((op_t *) dstp)[0] = a0;
00054       ((op_t *) dstp)[1] = a1;
00055 
00056       srcp += 2 * OPSIZ;
00057       dstp += 2 * OPSIZ;
00058       len -= 2;
00059     }
00060   while (len != 0);
00061 }
00062 
00063 /* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
00064    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
00065    DSTP should be aligned for memory operations on `op_t's, but SRCP must
00066    *not* be aligned.  */
00067 
00068 void
00069 _wordcopy_fwd_dest_aligned (dstp, srcp, len)
00070      long int dstp;
00071      long int srcp;
00072      size_t len;
00073 {
00074   op_t a0, a1, a2;
00075   int sh_1, sh_2;
00076 
00077   /* Calculate how to shift a word read at the memory operation
00078      aligned srcp to make it aligned for copy.  */
00079 
00080   sh_1 = 8 * (srcp % OPSIZ);
00081   sh_2 = 8 * OPSIZ - sh_1;
00082 
00083   /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
00084      it points in the middle of.  */
00085   srcp &= -OPSIZ;
00086   a0 = ((op_t *) srcp)[0];
00087 
00088   if (len & 1)
00089   {
00090     a1 = ((op_t *) srcp)[1];
00091     ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
00092     
00093     if (len == 1)
00094       return;
00095     
00096     a0 = a1;
00097     srcp += OPSIZ;
00098     dstp += OPSIZ;
00099     len -= 1;
00100   }
00101 
00102   do
00103     {
00104       a1 = ((op_t *) srcp)[1];
00105       a2 = ((op_t *) srcp)[2];
00106       ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
00107       ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
00108       a0 = a2;
00109 
00110       srcp += 2 * OPSIZ;
00111       dstp += 2 * OPSIZ;
00112       len -= 2;
00113     }
00114   while (len != 0);
00115 }
00116 
00117 /* _wordcopy_bwd_aligned -- Copy block finishing right before
00118    SRCP to block finishing right before DSTP with LEN `op_t' words
00119    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
00120    operations on `op_t's.  */
00121 
00122 void
00123 _wordcopy_bwd_aligned (dstp, srcp, len)
00124      long int dstp;
00125      long int srcp;
00126      size_t len;
00127 {
00128   op_t a0, a1;
00129 
00130   if (len & 1)
00131   {
00132     srcp -= OPSIZ;
00133     dstp -= OPSIZ;
00134     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
00135     
00136     if (len == 1)
00137       return;
00138     len -= 1;
00139   }
00140 
00141   do
00142     {
00143       srcp -= 2 * OPSIZ;
00144       dstp -= 2 * OPSIZ;
00145 
00146       a1 = ((op_t *) srcp)[1];
00147       a0 = ((op_t *) srcp)[0];
00148       ((op_t *) dstp)[1] = a1;
00149       ((op_t *) dstp)[0] = a0;
00150 
00151       len -= 2;
00152     }
00153   while (len != 0);
00154 }
00155 
00156 /* _wordcopy_bwd_dest_aligned -- Copy block finishing right
00157    before SRCP to block finishing right before DSTP with LEN `op_t'
00158    words (not LEN bytes!).  DSTP should be aligned for memory
00159    operations on `op_t', but SRCP must *not* be aligned.  */
00160 
00161 void
00162 _wordcopy_bwd_dest_aligned (dstp, srcp, len)
00163      long int dstp;
00164      long int srcp;
00165      size_t len;
00166 {
00167   op_t a0, a1, a2;
00168   int sh_1, sh_2;
00169 
00170   /* Calculate how to shift a word read at the memory operation
00171      aligned srcp to make it aligned for copy.  */
00172 
00173   sh_1 = 8 * (srcp % OPSIZ);
00174   sh_2 = 8 * OPSIZ - sh_1;
00175 
00176   /* Make srcp aligned by rounding it down to the beginning of the op_t
00177      it points in the middle of.  */
00178   srcp &= -OPSIZ;
00179   a2 = ((op_t *) srcp)[0];
00180 
00181   if (len & 1)
00182   {
00183     srcp -= OPSIZ;
00184     dstp -= OPSIZ;
00185     a1 = ((op_t *) srcp)[0];
00186     ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
00187 
00188     if (len == 1)
00189       return;
00190 
00191     a2 = a1;
00192     len -= 1;
00193   }
00194 
00195   do
00196     {
00197       srcp -= 2 * OPSIZ;
00198       dstp -= 2 * OPSIZ;
00199 
00200       a1 = ((op_t *) srcp)[1];
00201       a0 = ((op_t *) srcp)[0];
00202       ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
00203       ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
00204       a2 = a0;
00205 
00206       len -= 2;
00207     }
00208   while (len != 0);
00209 }