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