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
);