src/libc/wordcopy.c

Go to the documentation of this file.
00001 
00009 /* 
00010  * Some of the code below has been extracted from the GNU C Library. 
00011  * Library's license follows.
00012  */
00013 
00014 /* _memcopy.c -- subroutines for memory copy functions.
00015    Copyright (C) 1991, 1996 Free Software Foundation, Inc.
00016    This file is part of the GNU C Library.
00017    Contributed by Torbjorn Granlund (tege@sics.se).
00018 
00019    The GNU C Library is free software; you can redistribute it and/or
00020    modify it under the terms of the GNU Lesser General Public
00021    License as published by the Free Software Foundation; either
00022    version 2.1 of the License, or (at your option) any later version.
00023 
00024    The GNU C Library is distributed in the hope that it will be useful,
00025    but WITHOUT ANY WARRANTY; without even the implied warranty of
00026    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00027    Lesser General Public License for more details.
00028 
00029    You should have received a copy of the GNU Lesser General Public
00030    License along with the GNU C Library; if not, write to the Free
00031    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00032    02111-1307 USA.  */
00033 
00034 
00035 #include <stddef.h>
00036 #include "wordcopy.h"
00037 #include "memcopy.h"
00038 #include "libc_internal.h"
00039 
00040 
00041 /* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
00042    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
00043    Both SRCP and DSTP should be aligned for memory operations on `op_t's.  */
00044 
00045 void
00046 txc_libc_wordcopy_fwd_aligned (long int dstp, long int srcp, size_t len)
00047 {
00048   op_t a0, a1;
00049 
00050   switch (len % 8)
00051     {
00052     case 2:
00053       a0 = ((op_t *) srcp)[0];
00054       srcp -= 6 * OPSIZ;
00055       dstp -= 7 * OPSIZ;
00056       len += 6;
00057       goto do1;
00058     case 3:
00059       a1 = ((op_t *) srcp)[0];
00060       srcp -= 5 * OPSIZ;
00061       dstp -= 6 * OPSIZ;
00062       len += 5;
00063       goto do2;
00064     case 4:
00065       a0 = ((op_t *) srcp)[0];
00066       srcp -= 4 * OPSIZ;
00067       dstp -= 5 * OPSIZ;
00068       len += 4;
00069       goto do3;
00070     case 5:
00071       a1 = ((op_t *) srcp)[0];
00072       srcp -= 3 * OPSIZ;
00073       dstp -= 4 * OPSIZ;
00074       len += 3;
00075       goto do4;
00076     case 6:
00077       a0 = ((op_t *) srcp)[0];
00078       srcp -= 2 * OPSIZ;
00079       dstp -= 3 * OPSIZ;
00080       len += 2;
00081       goto do5;
00082     case 7:
00083       a1 = ((op_t *) srcp)[0];
00084       srcp -= 1 * OPSIZ;
00085       dstp -= 2 * OPSIZ;
00086       len += 1;
00087       goto do6;
00088 
00089     case 0:
00090       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00091         return;
00092       a0 = ((op_t *) srcp)[0];
00093       srcp -= 0 * OPSIZ;
00094       dstp -= 1 * OPSIZ;
00095       goto do7;
00096     case 1:
00097       a1 = ((op_t *) srcp)[0];
00098       srcp -=-1 * OPSIZ;
00099       dstp -= 0 * OPSIZ;
00100       len -= 1;
00101       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00102         goto do0;
00103       goto do8;                 /* No-op.  */
00104     }
00105 
00106   do
00107     {
00108     do8:
00109       a0 = ((op_t *) srcp)[0];
00110       ((op_t *) dstp)[0] = a1;
00111     do7:
00112       a1 = ((op_t *) srcp)[1];
00113       ((op_t *) dstp)[1] = a0;
00114     do6:
00115       a0 = ((op_t *) srcp)[2];
00116       ((op_t *) dstp)[2] = a1;
00117     do5:
00118       a1 = ((op_t *) srcp)[3];
00119       ((op_t *) dstp)[3] = a0;
00120     do4:
00121       a0 = ((op_t *) srcp)[4];
00122       ((op_t *) dstp)[4] = a1;
00123     do3:
00124       a1 = ((op_t *) srcp)[5];
00125       ((op_t *) dstp)[5] = a0;
00126     do2:
00127       a0 = ((op_t *) srcp)[6];
00128       ((op_t *) dstp)[6] = a1;
00129     do1:
00130       a1 = ((op_t *) srcp)[7];
00131       ((op_t *) dstp)[7] = a0;
00132 
00133       srcp += 8 * OPSIZ;
00134       dstp += 8 * OPSIZ;
00135       len -= 8;
00136     }
00137   while (len != 0);
00138 
00139   /* This is the right position for do0.  Please don't move
00140      it into the loop.  */
00141  do0:
00142   ((op_t *) dstp)[0] = a1;
00143 }
00144 
00145 
00146 /* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
00147    block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
00148    DSTP should be aligned for memory operations on `op_t's, but SRCP must
00149    *not* be aligned.  */
00150 
00151 void
00152 txc_libc_wordcopy_fwd_dest_aligned (long int dstp, long int srcp, size_t len)
00153 {
00154   op_t a0, a1, a2, a3;
00155   int sh_1, sh_2;
00156 
00157   /* Calculate how to shift a word read at the memory operation
00158      aligned srcp to make it aligned for copy.  */
00159 
00160   sh_1 = 8 * (srcp % OPSIZ);
00161   sh_2 = 8 * OPSIZ - sh_1;
00162 
00163   /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
00164      it points in the middle of.  */
00165   srcp &= -OPSIZ;
00166 
00167   switch (len % 4)
00168     {
00169     case 2:
00170       a1 = ((op_t *) srcp)[0];
00171       a2 = ((op_t *) srcp)[1];
00172       srcp -= 1 * OPSIZ;
00173       dstp -= 3 * OPSIZ;
00174       len += 2;
00175       goto do1;
00176     case 3:
00177       a0 = ((op_t *) srcp)[0];
00178       a1 = ((op_t *) srcp)[1];
00179       srcp -= 0 * OPSIZ;
00180       dstp -= 2 * OPSIZ;
00181       len += 1;
00182       goto do2;
00183     case 0:
00184       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00185         return;
00186       a3 = ((op_t *) srcp)[0];
00187       a0 = ((op_t *) srcp)[1];
00188       srcp -=-1 * OPSIZ;
00189       dstp -= 1 * OPSIZ;
00190       len += 0;
00191       goto do3;
00192     case 1:
00193       a2 = ((op_t *) srcp)[0];
00194       a3 = ((op_t *) srcp)[1];
00195       srcp -=-2 * OPSIZ;
00196       dstp -= 0 * OPSIZ;
00197       len -= 1;
00198       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00199         goto do0;
00200       goto do4;                 /* No-op.  */
00201     }
00202 
00203   do
00204     {
00205     do4:
00206       a0 = ((op_t *) srcp)[0];
00207       ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
00208     do3:
00209       a1 = ((op_t *) srcp)[1];
00210       ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
00211     do2:
00212       a2 = ((op_t *) srcp)[2];
00213       ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
00214     do1:
00215       a3 = ((op_t *) srcp)[3];
00216       ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
00217 
00218       srcp += 4 * OPSIZ;
00219       dstp += 4 * OPSIZ;
00220       len -= 4;
00221     }
00222   while (len != 0);
00223 
00224   /* This is the right position for do0.  Please don't move
00225      it into the loop.  */
00226  do0:
00227   ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
00228 }
00229 
00230 
00231 /* _wordcopy_bwd_aligned -- Copy block finishing right before
00232    SRCP to block finishing right before DSTP with LEN `op_t' words
00233    (not LEN bytes!).  Both SRCP and DSTP should be aligned for memory
00234    operations on `op_t's.  */
00235 
00236 void
00237 txc_libc_wordcopy_bwd_aligned (long int dstp, long int srcp, size_t len)
00238 {
00239   op_t a0, a1;
00240 
00241   switch (len % 8)
00242     {
00243     case 2:
00244       srcp -= 2 * OPSIZ;
00245       dstp -= 1 * OPSIZ;
00246       a0 = ((op_t *) srcp)[1];
00247       len += 6;
00248       goto do1;
00249     case 3:
00250       srcp -= 3 * OPSIZ;
00251       dstp -= 2 * OPSIZ;
00252       a1 = ((op_t *) srcp)[2];
00253       len += 5;
00254       goto do2;
00255     case 4:
00256       srcp -= 4 * OPSIZ;
00257       dstp -= 3 * OPSIZ;
00258       a0 = ((op_t *) srcp)[3];
00259       len += 4;
00260       goto do3;
00261     case 5:
00262       srcp -= 5 * OPSIZ;
00263       dstp -= 4 * OPSIZ;
00264       a1 = ((op_t *) srcp)[4];
00265       len += 3;
00266       goto do4;
00267     case 6:
00268       srcp -= 6 * OPSIZ;
00269       dstp -= 5 * OPSIZ;
00270       a0 = ((op_t *) srcp)[5];
00271       len += 2;
00272       goto do5;
00273     case 7:
00274       srcp -= 7 * OPSIZ;
00275       dstp -= 6 * OPSIZ;
00276       a1 = ((op_t *) srcp)[6];
00277       len += 1;
00278       goto do6;
00279 
00280     case 0:
00281       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00282         return;
00283       srcp -= 8 * OPSIZ;
00284       dstp -= 7 * OPSIZ;
00285       a0 = ((op_t *) srcp)[7];
00286       goto do7;
00287     case 1:
00288       srcp -= 9 * OPSIZ;
00289       dstp -= 8 * OPSIZ;
00290       a1 = ((op_t *) srcp)[8];
00291       len -= 1;
00292       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00293         goto do0;
00294       goto do8;                 /* No-op.  */
00295     }
00296 
00297   do
00298     {
00299     do8:
00300       a0 = ((op_t *) srcp)[7];
00301       ((op_t *) dstp)[7] = a1;
00302     do7:
00303       a1 = ((op_t *) srcp)[6];
00304       ((op_t *) dstp)[6] = a0;
00305     do6:
00306       a0 = ((op_t *) srcp)[5];
00307       ((op_t *) dstp)[5] = a1;
00308     do5:
00309       a1 = ((op_t *) srcp)[4];
00310       ((op_t *) dstp)[4] = a0;
00311     do4:
00312       a0 = ((op_t *) srcp)[3];
00313       ((op_t *) dstp)[3] = a1;
00314     do3:
00315       a1 = ((op_t *) srcp)[2];
00316       ((op_t *) dstp)[2] = a0;
00317     do2:
00318       a0 = ((op_t *) srcp)[1];
00319       ((op_t *) dstp)[1] = a1;
00320     do1:
00321       a1 = ((op_t *) srcp)[0];
00322       ((op_t *) dstp)[0] = a0;
00323 
00324       srcp -= 8 * OPSIZ;
00325       dstp -= 8 * OPSIZ;
00326       len -= 8;
00327     }
00328   while (len != 0);
00329 
00330   /* This is the right position for do0.  Please don't move
00331      it into the loop.  */
00332  do0:
00333   ((op_t *) dstp)[7] = a1;
00334 }
00335 
00336 
00337 /* _wordcopy_bwd_dest_aligned -- Copy block finishing right
00338    before SRCP to block finishing right before DSTP with LEN `op_t'
00339    words (not LEN bytes!).  DSTP should be aligned for memory
00340    operations on `op_t', but SRCP must *not* be aligned.  */
00341 
00342 void
00343 txc_libc_wordcopy_bwd_dest_aligned (long int dstp, long int srcp, size_t len)
00344 {
00345   op_t a0, a1, a2, a3;
00346   int sh_1, sh_2;
00347 
00348   /* Calculate how to shift a word read at the memory operation
00349      aligned srcp to make it aligned for copy.  */
00350 
00351   sh_1 = 8 * (srcp % OPSIZ);
00352   sh_2 = 8 * OPSIZ - sh_1;
00353 
00354   /* Make srcp aligned by rounding it down to the beginning of the op_t
00355      it points in the middle of.  */
00356   srcp &= -OPSIZ;
00357   srcp += OPSIZ;
00358 
00359   switch (len % 4)
00360     {
00361     case 2:
00362       srcp -= 3 * OPSIZ;
00363       dstp -= 1 * OPSIZ;
00364       a2 = ((op_t *) srcp)[2];
00365       a1 = ((op_t *) srcp)[1];
00366       len += 2;
00367       goto do1;
00368     case 3:
00369       srcp -= 4 * OPSIZ;
00370       dstp -= 2 * OPSIZ;
00371       a3 = ((op_t *) srcp)[3];
00372       a2 = ((op_t *) srcp)[2];
00373       len += 1;
00374       goto do2;
00375     case 0:
00376       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00377         return;
00378       srcp -= 5 * OPSIZ;
00379       dstp -= 3 * OPSIZ;
00380       a0 = ((op_t *) srcp)[4];
00381       a3 = ((op_t *) srcp)[3];
00382       goto do3;
00383     case 1:
00384       srcp -= 6 * OPSIZ;
00385       dstp -= 4 * OPSIZ;
00386       a1 = ((op_t *) srcp)[5];
00387       a0 = ((op_t *) srcp)[4];
00388       len -= 1;
00389       if (OP_T_THRES <= 3 * OPSIZ && len == 0)
00390         goto do0;
00391       goto do4;                 /* No-op.  */
00392     }
00393 
00394   do
00395     {
00396     do4:
00397       a3 = ((op_t *) srcp)[3];
00398       ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
00399     do3:
00400       a2 = ((op_t *) srcp)[2];
00401       ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
00402     do2:
00403       a1 = ((op_t *) srcp)[1];
00404       ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
00405     do1:
00406       a0 = ((op_t *) srcp)[0];
00407       ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
00408 
00409       srcp -= 4 * OPSIZ;
00410       dstp -= 4 * OPSIZ;
00411       len -= 4;
00412     }
00413   while (len != 0);
00414 
00415   /* This is the right position for do0.  Please don't move
00416      it into the loop.  */
00417  do0:
00418   ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
00419 }

Generated on Wed Dec 9 20:32:39 2009 for xCalls by  doxygen 1.4.7