1
/* _memcopy.c -- subroutines for memory copy functions.
2
Copyright (C) 1991, 1996 Free Software Foundation, Inc.
3
This file is part of the GNU C Library.
4
Contributed by Torbjorn Granlund (tege@sics.se).
6
The GNU C Library is free software; you can redistribute it and/or
7
modify it under the terms of the GNU Lesser General Public
8
License as published by the Free Software Foundation; either
9
version 2.1 of the License, or (at your option) any later version.
11
The GNU C Library is distributed in the hope that it will be useful,
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
Lesser General Public License for more details.
16
You should have received a copy of the GNU Lesser General Public
17
License along with the GNU C Library; if not, see
18
<http://www.gnu.org/licenses/>. */
20
/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */
25
/* _wordcopy_fwd_aligned -- Copy block beginning at SRCP to
26
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
27
Both SRCP and DSTP should be aligned for memory operations on `op_t's. */
30
_wordcopy_fwd_aligned (dstp, srcp, len)
40
a0 = ((op_t *) srcp)[0];
46
a1 = ((op_t *) srcp)[0];
52
a0 = ((op_t *) srcp)[0];
58
a1 = ((op_t *) srcp)[0];
64
a0 = ((op_t *) srcp)[0];
70
a1 = ((op_t *) srcp)[0];
77
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
79
a0 = ((op_t *) srcp)[0];
84
a1 = ((op_t *) srcp)[0];
88
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
90
goto do8; /* No-op. */
96
a0 = ((op_t *) srcp)[0];
97
((op_t *) dstp)[0] = a1;
99
a1 = ((op_t *) srcp)[1];
100
((op_t *) dstp)[1] = a0;
102
a0 = ((op_t *) srcp)[2];
103
((op_t *) dstp)[2] = a1;
105
a1 = ((op_t *) srcp)[3];
106
((op_t *) dstp)[3] = a0;
108
a0 = ((op_t *) srcp)[4];
109
((op_t *) dstp)[4] = a1;
111
a1 = ((op_t *) srcp)[5];
112
((op_t *) dstp)[5] = a0;
114
a0 = ((op_t *) srcp)[6];
115
((op_t *) dstp)[6] = a1;
117
a1 = ((op_t *) srcp)[7];
118
((op_t *) dstp)[7] = a0;
126
/* This is the right position for do0. Please don't move
129
((op_t *) dstp)[0] = a1;
132
/* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
133
block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
134
DSTP should be aligned for memory operations on `op_t's, but SRCP must
138
_wordcopy_fwd_dest_aligned (dstp, srcp, len)
146
/* Calculate how to shift a word read at the memory operation
147
aligned srcp to make it aligned for copy. */
149
sh_1 = 8 * (srcp % OPSIZ);
150
sh_2 = 8 * OPSIZ - sh_1;
152
/* Make SRCP aligned by rounding it down to the beginning of the `op_t'
153
it points in the middle of. */
159
a1 = ((op_t *) srcp)[0];
160
a2 = ((op_t *) srcp)[1];
166
a0 = ((op_t *) srcp)[0];
167
a1 = ((op_t *) srcp)[1];
173
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
175
a3 = ((op_t *) srcp)[0];
176
a0 = ((op_t *) srcp)[1];
182
a2 = ((op_t *) srcp)[0];
183
a3 = ((op_t *) srcp)[1];
187
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
189
goto do4; /* No-op. */
195
a0 = ((op_t *) srcp)[0];
196
((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
198
a1 = ((op_t *) srcp)[1];
199
((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
201
a2 = ((op_t *) srcp)[2];
202
((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
204
a3 = ((op_t *) srcp)[3];
205
((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
213
/* This is the right position for do0. Please don't move
216
((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
219
/* _wordcopy_bwd_aligned -- Copy block finishing right before
220
SRCP to block finishing right before DSTP with LEN `op_t' words
221
(not LEN bytes!). Both SRCP and DSTP should be aligned for memory
222
operations on `op_t's. */
225
_wordcopy_bwd_aligned (dstp, srcp, len)
237
a0 = ((op_t *) srcp)[1];
243
a1 = ((op_t *) srcp)[2];
249
a0 = ((op_t *) srcp)[3];
255
a1 = ((op_t *) srcp)[4];
261
a0 = ((op_t *) srcp)[5];
267
a1 = ((op_t *) srcp)[6];
272
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
276
a0 = ((op_t *) srcp)[7];
281
a1 = ((op_t *) srcp)[8];
283
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
285
goto do8; /* No-op. */
291
a0 = ((op_t *) srcp)[7];
292
((op_t *) dstp)[7] = a1;
294
a1 = ((op_t *) srcp)[6];
295
((op_t *) dstp)[6] = a0;
297
a0 = ((op_t *) srcp)[5];
298
((op_t *) dstp)[5] = a1;
300
a1 = ((op_t *) srcp)[4];
301
((op_t *) dstp)[4] = a0;
303
a0 = ((op_t *) srcp)[3];
304
((op_t *) dstp)[3] = a1;
306
a1 = ((op_t *) srcp)[2];
307
((op_t *) dstp)[2] = a0;
309
a0 = ((op_t *) srcp)[1];
310
((op_t *) dstp)[1] = a1;
312
a1 = ((op_t *) srcp)[0];
313
((op_t *) dstp)[0] = a0;
321
/* This is the right position for do0. Please don't move
324
((op_t *) dstp)[7] = a1;
327
/* _wordcopy_bwd_dest_aligned -- Copy block finishing right
328
before SRCP to block finishing right before DSTP with LEN `op_t'
329
words (not LEN bytes!). DSTP should be aligned for memory
330
operations on `op_t', but SRCP must *not* be aligned. */
333
_wordcopy_bwd_dest_aligned (dstp, srcp, len)
341
/* Calculate how to shift a word read at the memory operation
342
aligned srcp to make it aligned for copy. */
344
sh_1 = 8 * (srcp % OPSIZ);
345
sh_2 = 8 * OPSIZ - sh_1;
347
/* Make srcp aligned by rounding it down to the beginning of the op_t
348
it points in the middle of. */
357
a2 = ((op_t *) srcp)[2];
358
a1 = ((op_t *) srcp)[1];
364
a3 = ((op_t *) srcp)[3];
365
a2 = ((op_t *) srcp)[2];
369
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
373
a0 = ((op_t *) srcp)[4];
374
a3 = ((op_t *) srcp)[3];
379
a1 = ((op_t *) srcp)[5];
380
a0 = ((op_t *) srcp)[4];
382
if (OP_T_THRES <= 3 * OPSIZ && len == 0)
384
goto do4; /* No-op. */
390
a3 = ((op_t *) srcp)[3];
391
((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
393
a2 = ((op_t *) srcp)[2];
394
((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
396
a1 = ((op_t *) srcp)[1];
397
((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
399
a0 = ((op_t *) srcp)[0];
400
((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
408
/* This is the right position for do0. Please don't move
411
((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);