1 /* _memcopy.c -- subroutines for memory copy functions.
2 Copyright (C) 1991 Free Software Foundation, Inc.
3 Contributed by Torbjorn Granlund (tege@sics.se).
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
18 Cambridge, MA 02139, USA. */
20 /* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */
26 /* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
27 block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
28 Both SRCP and DSTP should be aligned for memory operations on `op_t's. */
31 DEFUN(_wordcopy_fwd_aligned, (dstp, srcp, len),
32 long int dstp AND long int srcp AND size_t len)
39 a0 = ((op_t *) srcp)[0];
45 a1 = ((op_t *) srcp)[0];
51 a0 = ((op_t *) srcp)[0];
57 a1 = ((op_t *) srcp)[0];
63 a0 = ((op_t *) srcp)[0];
69 a1 = ((op_t *) srcp)[0];
76 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
78 a0 = ((op_t *) srcp)[0];
83 a1 = ((op_t *) srcp)[0];
87 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
89 goto do8; /* No-op. */
95 a0 = ((op_t *) srcp)[0];
96 ((op_t *) dstp)[0] = a1;
98 a1 = ((op_t *) srcp)[1];
99 ((op_t *) dstp)[1] = a0;
101 a0 = ((op_t *) srcp)[2];
102 ((op_t *) dstp)[2] = a1;
104 a1 = ((op_t *) srcp)[3];
105 ((op_t *) dstp)[3] = a0;
107 a0 = ((op_t *) srcp)[4];
108 ((op_t *) dstp)[4] = a1;
110 a1 = ((op_t *) srcp)[5];
111 ((op_t *) dstp)[5] = a0;
113 a0 = ((op_t *) srcp)[6];
114 ((op_t *) dstp)[6] = a1;
116 a1 = ((op_t *) srcp)[7];
117 ((op_t *) dstp)[7] = a0;
125 /* This is the right position for do0. Please don't move
128 ((op_t *) dstp)[0] = a1;
131 /* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
132 block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
133 DSTP should be aligned for memory operations on `op_t's, but SRCP must
137 DEFUN(_wordcopy_fwd_dest_aligned, (dstp, srcp, len),
138 long int dstp AND long int srcp AND size_t len)
143 /* Calculate how to shift a word read at the memory operation
144 aligned srcp to make it aligned for copy. */
146 sh_1 = 8 * (srcp % OPSIZ);
147 sh_2 = 8 * OPSIZ - sh_1;
149 /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
150 it points in the middle of. */
156 a1 = ((op_t *) srcp)[0];
157 a2 = ((op_t *) srcp)[1];
163 a0 = ((op_t *) srcp)[0];
164 a1 = ((op_t *) srcp)[1];
170 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
172 a3 = ((op_t *) srcp)[0];
173 a0 = ((op_t *) srcp)[1];
179 a2 = ((op_t *) srcp)[0];
180 a3 = ((op_t *) srcp)[1];
184 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
186 goto do4; /* No-op. */
192 a0 = ((op_t *) srcp)[0];
193 ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
195 a1 = ((op_t *) srcp)[1];
196 ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
198 a2 = ((op_t *) srcp)[2];
199 ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
201 a3 = ((op_t *) srcp)[3];
202 ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
210 /* This is the right position for do0. Please don't move
213 ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
216 /* _wordcopy_bwd_aligned -- Copy block finishing right before
217 SRCP to block finishing right before DSTP with LEN `op_t' words
218 (not LEN bytes!). Both SRCP and DSTP should be aligned for memory
219 operations on `op_t's. */
222 DEFUN(_wordcopy_bwd_aligned, (dstp, srcp, len),
223 long int dstp AND long int srcp AND size_t len)
232 a0 = ((op_t *) srcp)[1];
238 a1 = ((op_t *) srcp)[2];
244 a0 = ((op_t *) srcp)[3];
250 a1 = ((op_t *) srcp)[4];
256 a0 = ((op_t *) srcp)[5];
262 a1 = ((op_t *) srcp)[6];
267 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
271 a0 = ((op_t *) srcp)[7];
276 a1 = ((op_t *) srcp)[8];
278 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
280 goto do8; /* No-op. */
286 a0 = ((op_t *) srcp)[7];
287 ((op_t *) dstp)[7] = a1;
289 a1 = ((op_t *) srcp)[6];
290 ((op_t *) dstp)[6] = a0;
292 a0 = ((op_t *) srcp)[5];
293 ((op_t *) dstp)[5] = a1;
295 a1 = ((op_t *) srcp)[4];
296 ((op_t *) dstp)[4] = a0;
298 a0 = ((op_t *) srcp)[3];
299 ((op_t *) dstp)[3] = a1;
301 a1 = ((op_t *) srcp)[2];
302 ((op_t *) dstp)[2] = a0;
304 a0 = ((op_t *) srcp)[1];
305 ((op_t *) dstp)[1] = a1;
307 a1 = ((op_t *) srcp)[0];
308 ((op_t *) dstp)[0] = a0;
316 /* This is the right position for do0. Please don't move
319 ((op_t *) dstp)[7] = a1;
322 /* _wordcopy_bwd_dest_aligned -- Copy block finishing right
323 before SRCP to block finishing right before DSTP with LEN `op_t'
324 words (not LEN bytes!). DSTP should be aligned for memory
325 operations on `op_t', but SRCP must *not* be aligned. */
328 DEFUN(_wordcopy_bwd_dest_aligned, (dstp, srcp, len),
329 long int dstp AND long int srcp AND size_t len)
334 /* Calculate how to shift a word read at the memory operation
335 aligned srcp to make it aligned for copy. */
337 sh_1 = 8 * (srcp % OPSIZ);
338 sh_2 = 8 * OPSIZ - sh_1;
340 /* Make srcp aligned by rounding it down to the beginning of the op_t
341 it points in the middle of. */
350 a2 = ((op_t *) srcp)[2];
351 a1 = ((op_t *) srcp)[1];
357 a3 = ((op_t *) srcp)[3];
358 a2 = ((op_t *) srcp)[2];
362 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
366 a0 = ((op_t *) srcp)[4];
367 a3 = ((op_t *) srcp)[3];
372 a1 = ((op_t *) srcp)[5];
373 a0 = ((op_t *) srcp)[4];
375 if (OP_T_THRES <= 3 * OPSIZ && len == 0)
377 goto do4; /* No-op. */
383 a3 = ((op_t *) srcp)[3];
384 ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
386 a2 = ((op_t *) srcp)[2];
387 ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
389 a1 = ((op_t *) srcp)[1];
390 ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
392 a0 = ((op_t *) srcp)[0];
393 ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
401 /* This is the right position for do0. Please don't move
404 ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);