2.9
[glibc/nacl-glibc.git] / sysdeps / powerpc / powerpc32 / power4 / wordcopy.c
blobf71b41dc4238e30844c41e2f4097bde57d0de265
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, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 /* BE VERY CAREFUL IF YOU CHANGE THIS CODE...! */
23 #include <stddef.h>
24 #include <memcopy.h>
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. */
30 void
31 _wordcopy_fwd_aligned (dstp, srcp, len)
32 long int dstp;
33 long int srcp;
34 size_t len;
36 op_t a0, a1;
38 if (len & 1)
40 ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
42 if (len == 1)
43 return;
44 srcp += OPSIZ;
45 dstp += OPSIZ;
46 len -= 1;
51 a0 = ((op_t *) srcp)[0];
52 a1 = ((op_t *) srcp)[1];
53 ((op_t *) dstp)[0] = a0;
54 ((op_t *) dstp)[1] = a1;
56 srcp += 2 * OPSIZ;
57 dstp += 2 * OPSIZ;
58 len -= 2;
60 while (len != 0);
63 /* _wordcopy_fwd_dest_aligned -- Copy block beginning at SRCP to
64 block beginning at DSTP with LEN `op_t' words (not LEN bytes!).
65 DSTP should be aligned for memory operations on `op_t's, but SRCP must
66 *not* be aligned. */
68 void
69 _wordcopy_fwd_dest_aligned (dstp, srcp, len)
70 long int dstp;
71 long int srcp;
72 size_t len;
74 op_t a0, a1, a2;
75 int sh_1, sh_2;
77 /* Calculate how to shift a word read at the memory operation
78 aligned srcp to make it aligned for copy. */
80 sh_1 = 8 * (srcp % OPSIZ);
81 sh_2 = 8 * OPSIZ - sh_1;
83 /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
84 it points in the middle of. */
85 srcp &= -OPSIZ;
86 a0 = ((op_t *) srcp)[0];
88 if (len & 1)
90 a1 = ((op_t *) srcp)[1];
91 ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
93 if (len == 1)
94 return;
96 a0 = a1;
97 srcp += OPSIZ;
98 dstp += OPSIZ;
99 len -= 1;
104 a1 = ((op_t *) srcp)[1];
105 a2 = ((op_t *) srcp)[2];
106 ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
107 ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
108 a0 = a2;
110 srcp += 2 * OPSIZ;
111 dstp += 2 * OPSIZ;
112 len -= 2;
114 while (len != 0);
117 /* _wordcopy_bwd_aligned -- Copy block finishing right before
118 SRCP to block finishing right before DSTP with LEN `op_t' words
119 (not LEN bytes!). Both SRCP and DSTP should be aligned for memory
120 operations on `op_t's. */
122 void
123 _wordcopy_bwd_aligned (dstp, srcp, len)
124 long int dstp;
125 long int srcp;
126 size_t len;
128 op_t a0, a1;
130 if (len & 1)
132 srcp -= OPSIZ;
133 dstp -= OPSIZ;
134 ((op_t *) dstp)[0] = ((op_t *) srcp)[0];
136 if (len == 1)
137 return;
138 len -= 1;
143 srcp -= 2 * OPSIZ;
144 dstp -= 2 * OPSIZ;
146 a1 = ((op_t *) srcp)[1];
147 a0 = ((op_t *) srcp)[0];
148 ((op_t *) dstp)[1] = a1;
149 ((op_t *) dstp)[0] = a0;
151 len -= 2;
153 while (len != 0);
156 /* _wordcopy_bwd_dest_aligned -- Copy block finishing right
157 before SRCP to block finishing right before DSTP with LEN `op_t'
158 words (not LEN bytes!). DSTP should be aligned for memory
159 operations on `op_t', but SRCP must *not* be aligned. */
161 void
162 _wordcopy_bwd_dest_aligned (dstp, srcp, len)
163 long int dstp;
164 long int srcp;
165 size_t len;
167 op_t a0, a1, a2;
168 int sh_1, sh_2;
170 /* Calculate how to shift a word read at the memory operation
171 aligned srcp to make it aligned for copy. */
173 sh_1 = 8 * (srcp % OPSIZ);
174 sh_2 = 8 * OPSIZ - sh_1;
176 /* Make srcp aligned by rounding it down to the beginning of the op_t
177 it points in the middle of. */
178 srcp &= -OPSIZ;
179 a2 = ((op_t *) srcp)[0];
181 if (len & 1)
183 srcp -= OPSIZ;
184 dstp -= OPSIZ;
185 a1 = ((op_t *) srcp)[0];
186 ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
188 if (len == 1)
189 return;
191 a2 = a1;
192 len -= 1;
197 srcp -= 2 * OPSIZ;
198 dstp -= 2 * OPSIZ;
200 a1 = ((op_t *) srcp)[1];
201 a0 = ((op_t *) srcp)[0];
202 ((op_t *) dstp)[1] = MERGE (a1, sh_1, a2, sh_2);
203 ((op_t *) dstp)[0] = MERGE (a0, sh_1, a1, sh_2);
204 a2 = a0;
206 len -= 2;
208 while (len != 0);