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   int align;
00077 
00078   /* Calculate how to shift a word read at the memory operation
00079      aligned srcp to make it aligned for copy.  */
00080 
00081   align = srcp % OPSIZ;
00082   sh_1 = 8 * (srcp % OPSIZ);
00083   sh_2 = 8 * OPSIZ - sh_1;
00084 
00085   /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
00086      it points in the middle of.  */
00087   srcp &= -OPSIZ;
00088   a0 = ((op_t *) srcp)[0];
00089 
00090   if (len & 1)
00091   {
00092     a1 = ((op_t *) srcp)[1];
00093     ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
00094     
00095     if (len == 1)
00096       return;
00097     
00098     a0 = a1;
00099     srcp += OPSIZ;
00100     dstp += OPSIZ;
00101     len -= 1;
00102   }
00103 
00104   switch (align)
00105     {
00106     case 1:
00107       do
00108         {
00109           a1 = ((op_t *) srcp)[1];
00110           a2 = ((op_t *) srcp)[2];
00111           ((op_t *) dstp)[0] = MERGE (a0, 8, a1, (64-8));
00112           ((op_t *) dstp)[1] = MERGE (a1, 8, a2, (64-8));
00113           a0 = a2;
00114     
00115           srcp += 2 * OPSIZ;
00116           dstp += 2 * OPSIZ;
00117           len -= 2;
00118         }
00119       while (len != 0);
00120       break;
00121     case 2:
00122       do
00123         {
00124           a1 = ((op_t *) srcp)[1];
00125           a2 = ((op_t *) srcp)[2];
00126           ((op_t *) dstp)[0] = MERGE (a0, 16, a1, (64-16));
00127           ((op_t *) dstp)[1] = MERGE (a1, 16, a2, (64-16));
00128           a0 = a2;
00129     
00130           srcp += 2 * OPSIZ;
00131           dstp += 2 * OPSIZ;
00132           len -= 2;
00133         }
00134       while (len != 0);
00135       break;
00136     case 3:
00137       do
00138         {
00139           a1 = ((op_t *) srcp)[1];
00140           a2 = ((op_t *) srcp)[2];
00141           ((op_t *) dstp)[0] = MERGE (a0, 24, a1, (64-24));
00142           ((op_t *) dstp)[1] = MERGE (a1, 24, a2, (64-24));
00143           a0 = a2;
00144     
00145           srcp += 2 * OPSIZ;
00146           dstp += 2 * OPSIZ;
00147           len -= 2;
00148         }
00149       while (len != 0);
00150       break;
00151     case 4:
00152       do
00153         {
00154           a1 = ((op_t *) srcp)[1];
00155           a2 = ((op_t *) srcp)[2];
00156           ((op_t *) dstp)[0] = MERGE (a0, 32, a1, (64-32));
00157           ((op_t *) dstp)[1] = MERGE (a1, 32, a2, (64-32));
00158           a0 = a2;
00159     
00160           srcp += 2 * OPSIZ;
00161           dstp += 2 * OPSIZ;
00162           len -= 2;
00163         }
00164       while (len != 0);
00165       break;
00166     case 5:
00167       do
00168         {
00169           a1 = ((op_t *) srcp)[1];
00170           a2 = ((op_t *) srcp)[2];
00171           ((op_t *) dstp)[0] = MERGE (a0, 40, a1, (64-40));
00172           ((op_t *) dstp)[1] = MERGE (a1, 40, a2, (64-40));
00173           a0 = a2;
00174     
00175           srcp += 2 * OPSIZ;
00176           dstp += 2 * OPSIZ;
00177           len -= 2;
00178         }
00179       while (len != 0);
00180       break;
00181     case 6:
00182       do
00183         {
00184           a1 = ((op_t *) srcp)[1];
00185           a2 = ((op_t *) srcp)[2];
00186           ((op_t *) dstp)[0] = MERGE (a0, 48, a1, (64-48));
00187           ((op_t *) dstp)[1] = MERGE (a1, 48, a2, (64-48));
00188           a0 = a2;
00189     
00190           srcp += 2 * OPSIZ;
00191           dstp += 2 * OPSIZ;
00192           len -= 2;
00193         }
00194       while (len != 0);
00195       break;
00196     case 7:
00197       do
00198         {
00199           a1 = ((op_t *) srcp)[1];
00200           a2 = ((op_t *) srcp)[2];
00201           ((op_t *) dstp)[0] = MERGE (a0, 56, a1, (64-56));
00202           ((op_t *) dstp)[1] = MERGE (a1, 56, a2, (64-56));
00203           a0 = a2;
00204     
00205           srcp += 2 * OPSIZ;
00206           dstp += 2 * OPSIZ;
00207           len -= 2;
00208         }
00209       while (len != 0);
00210       break;
00211     }
00212 
00213 }
00214 
00215 /* _wordcopy_bwd_aligned -- Copy block finishing right before
00216    SRCP to block finishing right before DSTP with LEN `op_t' words
00217    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
00218    operations on `op_t's.  */
00219 
00220 void
00221 _wordcopy_bwd_aligned (dstp, srcp, len)
00222      long int dstp;
00223      long int srcp;
00224      size_t len;
00225 {
00226   op_t a0, a1;
00227 
00228   if (len & 1)
00229   {
00230     srcp -= OPSIZ;
00231     dstp -= OPSIZ;
00232     ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
00233     
00234     if (len == 1)
00235       return;
00236     len -= 1;
00237   }
00238 
00239   do
00240     {
00241       srcp -= 2 * OPSIZ;
00242       dstp -= 2 * OPSIZ;
00243 
00244       a1 = ((op_t *) srcp)[1];
00245       a0 = ((op_t *) srcp)[0];
00246       ((op_t *) dstp)[1] = a1;
00247       ((op_t *) dstp)[0] = a0;
00248 
00249       len -= 2;
00250     }
00251   while (len != 0);
00252 }
00253 
00254 /* _wordcopy_bwd_dest_aligned -- Copy block finishing right
00255    before SRCP to block finishing right before DSTP with LEN `op_t'
00256    words (not LEN bytes!).  DSTP should be aligned for memory
00257    operations on `op_t', but SRCP must *not* be aligned.  */
00258 
00259 void
00260 _wordcopy_bwd_dest_aligned (dstp, srcp, len)
00261      long int dstp;
00262      long int srcp;
00263      size_t len;
00264 {
00265   op_t a0, a1, a2;
00266   int sh_1, sh_2;
00267   int align;
00268 
00269   /* Calculate how to shift a word read at the memory operation
00270      aligned srcp to make it aligned for copy.  */
00271 
00272   align = srcp % OPSIZ;
00273   sh_1 = 8 * (srcp % OPSIZ);
00274   sh_2 = 8 * OPSIZ - sh_1;
00275 
00276   /* Make srcp aligned by rounding it down to the beginning of the op_t
00277      it points in the middle of.  */
00278   srcp &= -OPSIZ;
00279   a2 = ((op_t *) srcp)[0];
00280 
00281   if (len & 1)
00282   {
00283     srcp -= OPSIZ;
00284     dstp -= OPSIZ;
00285     a1 = ((op_t *) srcp)[0];
00286     ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
00287 
00288     if (len == 1)
00289       return;
00290 
00291     a2 = a1;
00292     len -= 1;
00293   }
00294 
00295   switch (align)
00296     {
00297     case 1:
00298       do
00299         {
00300           srcp -= 2 * OPSIZ;
00301           dstp -= 2 * OPSIZ;
00302     
00303           a1 = ((op_t *) srcp)[1];
00304           a0 = ((op_t *) srcp)[0];
00305           ((op_t *) dstp)[1] = MERGE (a1, 8, a2, (64-8));
00306           ((op_t *) dstp)[0] = MERGE (a0, 8, a1, (64-8));
00307           a2 = a0;
00308     
00309           len -= 2;
00310         }
00311       while (len != 0);
00312       break;
00313     case 2:
00314       do
00315         {
00316           srcp -= 2 * OPSIZ;
00317           dstp -= 2 * OPSIZ;
00318     
00319           a1 = ((op_t *) srcp)[1];
00320           a0 = ((op_t *) srcp)[0];
00321           ((op_t *) dstp)[1] = MERGE (a1, 16, a2, (64-16));
00322           ((op_t *) dstp)[0] = MERGE (a0, 16, a1, (64-16));
00323           a2 = a0;
00324     
00325           len -= 2;
00326         }
00327       while (len != 0);
00328       break;
00329     case 3:
00330       do
00331         {
00332           srcp -= 2 * OPSIZ;
00333           dstp -= 2 * OPSIZ;
00334     
00335           a1 = ((op_t *) srcp)[1];
00336           a0 = ((op_t *) srcp)[0];
00337           ((op_t *) dstp)[1] = MERGE (a1, 24, a2, (64-24));
00338           ((op_t *) dstp)[0] = MERGE (a0, 24, a1, (64-24));
00339           a2 = a0;
00340     
00341           len -= 2;
00342         }
00343       while (len != 0);
00344       break;
00345     case 4:
00346       do
00347         {
00348           srcp -= 2 * OPSIZ;
00349           dstp -= 2 * OPSIZ;
00350     
00351           a1 = ((op_t *) srcp)[1];
00352           a0 = ((op_t *) srcp)[0];
00353           ((op_t *) dstp)[1] = MERGE (a1, 32, a2, (64-32));
00354           ((op_t *) dstp)[0] = MERGE (a0, 32, a1, (64-32));
00355           a2 = a0;
00356     
00357           len -= 2;
00358         }
00359       while (len != 0);
00360       break;
00361     case 5:
00362       do
00363         {
00364           srcp -= 2 * OPSIZ;
00365           dstp -= 2 * OPSIZ;
00366     
00367           a1 = ((op_t *) srcp)[1];
00368           a0 = ((op_t *) srcp)[0];
00369           ((op_t *) dstp)[1] = MERGE (a1, 40, a2, (64-40));
00370           ((op_t *) dstp)[0] = MERGE (a0, 40, a1, (64-40));
00371           a2 = a0;
00372     
00373           len -= 2;
00374         }
00375       while (len != 0);
00376       break;
00377     case 6:
00378       do
00379         {
00380           srcp -= 2 * OPSIZ;
00381           dstp -= 2 * OPSIZ;
00382     
00383           a1 = ((op_t *) srcp)[1];
00384           a0 = ((op_t *) srcp)[0];
00385           ((op_t *) dstp)[1] = MERGE (a1, 48, a2, (64-48));
00386           ((op_t *) dstp)[0] = MERGE (a0, 48, a1, (64-48));
00387           a2 = a0;
00388     
00389           len -= 2;
00390         }
00391       while (len != 0);
00392       break;
00393     case 7:
00394       do
00395         {
00396           srcp -= 2 * OPSIZ;
00397           dstp -= 2 * OPSIZ;
00398     
00399           a1 = ((op_t *) srcp)[1];
00400           a0 = ((op_t *) srcp)[0];
00401           ((op_t *) dstp)[1] = MERGE (a1, 56, a2, (64-56));
00402           ((op_t *) dstp)[0] = MERGE (a0, 56, a1, (64-56));
00403           a2 = a0;
00404     
00405           len -= 2;
00406         }
00407       while (len != 0);
00408       break;
00409     }
00410 }