~linaro-toolchain-dev/cortex-strings/trunk

« back to all changes in this revision

Viewing changes to reference/glibc-c/wordcopy.c

  • Committer: Michael Hope
  • Date: 2012-06-12 03:19:48 UTC
  • Revision ID: michael.hope@linaro.org-20120612031948-4ii8jicywtzjprak
Added the C only routines from GLIBC 2.16+20120607~git24a6dbe

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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).
 
5
 
 
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.
 
10
 
 
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.
 
15
 
 
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/>.  */
 
19
 
 
20
/* BE VERY CAREFUL IF YOU CHANGE THIS CODE...!  */
 
21
 
 
22
#include <stddef.h>
 
23
#include "memcopy.h"
 
24
 
 
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.  */
 
28
 
 
29
void
 
30
_wordcopy_fwd_aligned (dstp, srcp, len)
 
31
     long int dstp;
 
32
     long int srcp;
 
33
     size_t len;
 
34
{
 
35
  op_t a0, a1;
 
36
 
 
37
  switch (len % 8)
 
38
    {
 
39
    case 2:
 
40
      a0 = ((op_t *) srcp)[0];
 
41
      srcp -= 6 * OPSIZ;
 
42
      dstp -= 7 * OPSIZ;
 
43
      len += 6;
 
44
      goto do1;
 
45
    case 3:
 
46
      a1 = ((op_t *) srcp)[0];
 
47
      srcp -= 5 * OPSIZ;
 
48
      dstp -= 6 * OPSIZ;
 
49
      len += 5;
 
50
      goto do2;
 
51
    case 4:
 
52
      a0 = ((op_t *) srcp)[0];
 
53
      srcp -= 4 * OPSIZ;
 
54
      dstp -= 5 * OPSIZ;
 
55
      len += 4;
 
56
      goto do3;
 
57
    case 5:
 
58
      a1 = ((op_t *) srcp)[0];
 
59
      srcp -= 3 * OPSIZ;
 
60
      dstp -= 4 * OPSIZ;
 
61
      len += 3;
 
62
      goto do4;
 
63
    case 6:
 
64
      a0 = ((op_t *) srcp)[0];
 
65
      srcp -= 2 * OPSIZ;
 
66
      dstp -= 3 * OPSIZ;
 
67
      len += 2;
 
68
      goto do5;
 
69
    case 7:
 
70
      a1 = ((op_t *) srcp)[0];
 
71
      srcp -= 1 * OPSIZ;
 
72
      dstp -= 2 * OPSIZ;
 
73
      len += 1;
 
74
      goto do6;
 
75
 
 
76
    case 0:
 
77
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
78
        return;
 
79
      a0 = ((op_t *) srcp)[0];
 
80
      srcp -= 0 * OPSIZ;
 
81
      dstp -= 1 * OPSIZ;
 
82
      goto do7;
 
83
    case 1:
 
84
      a1 = ((op_t *) srcp)[0];
 
85
      srcp -=-1 * OPSIZ;
 
86
      dstp -= 0 * OPSIZ;
 
87
      len -= 1;
 
88
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
89
        goto do0;
 
90
      goto do8;                 /* No-op.  */
 
91
    }
 
92
 
 
93
  do
 
94
    {
 
95
    do8:
 
96
      a0 = ((op_t *) srcp)[0];
 
97
      ((op_t *) dstp)[0] = a1;
 
98
    do7:
 
99
      a1 = ((op_t *) srcp)[1];
 
100
      ((op_t *) dstp)[1] = a0;
 
101
    do6:
 
102
      a0 = ((op_t *) srcp)[2];
 
103
      ((op_t *) dstp)[2] = a1;
 
104
    do5:
 
105
      a1 = ((op_t *) srcp)[3];
 
106
      ((op_t *) dstp)[3] = a0;
 
107
    do4:
 
108
      a0 = ((op_t *) srcp)[4];
 
109
      ((op_t *) dstp)[4] = a1;
 
110
    do3:
 
111
      a1 = ((op_t *) srcp)[5];
 
112
      ((op_t *) dstp)[5] = a0;
 
113
    do2:
 
114
      a0 = ((op_t *) srcp)[6];
 
115
      ((op_t *) dstp)[6] = a1;
 
116
    do1:
 
117
      a1 = ((op_t *) srcp)[7];
 
118
      ((op_t *) dstp)[7] = a0;
 
119
 
 
120
      srcp += 8 * OPSIZ;
 
121
      dstp += 8 * OPSIZ;
 
122
      len -= 8;
 
123
    }
 
124
  while (len != 0);
 
125
 
 
126
  /* This is the right position for do0.  Please don't move
 
127
     it into the loop.  */
 
128
 do0:
 
129
  ((op_t *) dstp)[0] = a1;
 
130
}
 
131
 
 
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
 
135
   *not* be aligned.  */
 
136
 
 
137
void
 
138
_wordcopy_fwd_dest_aligned (dstp, srcp, len)
 
139
     long int dstp;
 
140
     long int srcp;
 
141
     size_t len;
 
142
{
 
143
  op_t a0, a1, a2, a3;
 
144
  int sh_1, sh_2;
 
145
 
 
146
  /* Calculate how to shift a word read at the memory operation
 
147
     aligned srcp to make it aligned for copy.  */
 
148
 
 
149
  sh_1 = 8 * (srcp % OPSIZ);
 
150
  sh_2 = 8 * OPSIZ - sh_1;
 
151
 
 
152
  /* Make SRCP aligned by rounding it down to the beginning of the `op_t'
 
153
     it points in the middle of.  */
 
154
  srcp &= -OPSIZ;
 
155
 
 
156
  switch (len % 4)
 
157
    {
 
158
    case 2:
 
159
      a1 = ((op_t *) srcp)[0];
 
160
      a2 = ((op_t *) srcp)[1];
 
161
      srcp -= 1 * OPSIZ;
 
162
      dstp -= 3 * OPSIZ;
 
163
      len += 2;
 
164
      goto do1;
 
165
    case 3:
 
166
      a0 = ((op_t *) srcp)[0];
 
167
      a1 = ((op_t *) srcp)[1];
 
168
      srcp -= 0 * OPSIZ;
 
169
      dstp -= 2 * OPSIZ;
 
170
      len += 1;
 
171
      goto do2;
 
172
    case 0:
 
173
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
174
        return;
 
175
      a3 = ((op_t *) srcp)[0];
 
176
      a0 = ((op_t *) srcp)[1];
 
177
      srcp -=-1 * OPSIZ;
 
178
      dstp -= 1 * OPSIZ;
 
179
      len += 0;
 
180
      goto do3;
 
181
    case 1:
 
182
      a2 = ((op_t *) srcp)[0];
 
183
      a3 = ((op_t *) srcp)[1];
 
184
      srcp -=-2 * OPSIZ;
 
185
      dstp -= 0 * OPSIZ;
 
186
      len -= 1;
 
187
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
188
        goto do0;
 
189
      goto do4;                 /* No-op.  */
 
190
    }
 
191
 
 
192
  do
 
193
    {
 
194
    do4:
 
195
      a0 = ((op_t *) srcp)[0];
 
196
      ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
 
197
    do3:
 
198
      a1 = ((op_t *) srcp)[1];
 
199
      ((op_t *) dstp)[1] = MERGE (a3, sh_1, a0, sh_2);
 
200
    do2:
 
201
      a2 = ((op_t *) srcp)[2];
 
202
      ((op_t *) dstp)[2] = MERGE (a0, sh_1, a1, sh_2);
 
203
    do1:
 
204
      a3 = ((op_t *) srcp)[3];
 
205
      ((op_t *) dstp)[3] = MERGE (a1, sh_1, a2, sh_2);
 
206
 
 
207
      srcp += 4 * OPSIZ;
 
208
      dstp += 4 * OPSIZ;
 
209
      len -= 4;
 
210
    }
 
211
  while (len != 0);
 
212
 
 
213
  /* This is the right position for do0.  Please don't move
 
214
     it into the loop.  */
 
215
 do0:
 
216
  ((op_t *) dstp)[0] = MERGE (a2, sh_1, a3, sh_2);
 
217
}
 
218
 
 
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.  */
 
223
 
 
224
void
 
225
_wordcopy_bwd_aligned (dstp, srcp, len)
 
226
     long int dstp;
 
227
     long int srcp;
 
228
     size_t len;
 
229
{
 
230
  op_t a0, a1;
 
231
 
 
232
  switch (len % 8)
 
233
    {
 
234
    case 2:
 
235
      srcp -= 2 * OPSIZ;
 
236
      dstp -= 1 * OPSIZ;
 
237
      a0 = ((op_t *) srcp)[1];
 
238
      len += 6;
 
239
      goto do1;
 
240
    case 3:
 
241
      srcp -= 3 * OPSIZ;
 
242
      dstp -= 2 * OPSIZ;
 
243
      a1 = ((op_t *) srcp)[2];
 
244
      len += 5;
 
245
      goto do2;
 
246
    case 4:
 
247
      srcp -= 4 * OPSIZ;
 
248
      dstp -= 3 * OPSIZ;
 
249
      a0 = ((op_t *) srcp)[3];
 
250
      len += 4;
 
251
      goto do3;
 
252
    case 5:
 
253
      srcp -= 5 * OPSIZ;
 
254
      dstp -= 4 * OPSIZ;
 
255
      a1 = ((op_t *) srcp)[4];
 
256
      len += 3;
 
257
      goto do4;
 
258
    case 6:
 
259
      srcp -= 6 * OPSIZ;
 
260
      dstp -= 5 * OPSIZ;
 
261
      a0 = ((op_t *) srcp)[5];
 
262
      len += 2;
 
263
      goto do5;
 
264
    case 7:
 
265
      srcp -= 7 * OPSIZ;
 
266
      dstp -= 6 * OPSIZ;
 
267
      a1 = ((op_t *) srcp)[6];
 
268
      len += 1;
 
269
      goto do6;
 
270
 
 
271
    case 0:
 
272
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
273
        return;
 
274
      srcp -= 8 * OPSIZ;
 
275
      dstp -= 7 * OPSIZ;
 
276
      a0 = ((op_t *) srcp)[7];
 
277
      goto do7;
 
278
    case 1:
 
279
      srcp -= 9 * OPSIZ;
 
280
      dstp -= 8 * OPSIZ;
 
281
      a1 = ((op_t *) srcp)[8];
 
282
      len -= 1;
 
283
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
284
        goto do0;
 
285
      goto do8;                 /* No-op.  */
 
286
    }
 
287
 
 
288
  do
 
289
    {
 
290
    do8:
 
291
      a0 = ((op_t *) srcp)[7];
 
292
      ((op_t *) dstp)[7] = a1;
 
293
    do7:
 
294
      a1 = ((op_t *) srcp)[6];
 
295
      ((op_t *) dstp)[6] = a0;
 
296
    do6:
 
297
      a0 = ((op_t *) srcp)[5];
 
298
      ((op_t *) dstp)[5] = a1;
 
299
    do5:
 
300
      a1 = ((op_t *) srcp)[4];
 
301
      ((op_t *) dstp)[4] = a0;
 
302
    do4:
 
303
      a0 = ((op_t *) srcp)[3];
 
304
      ((op_t *) dstp)[3] = a1;
 
305
    do3:
 
306
      a1 = ((op_t *) srcp)[2];
 
307
      ((op_t *) dstp)[2] = a0;
 
308
    do2:
 
309
      a0 = ((op_t *) srcp)[1];
 
310
      ((op_t *) dstp)[1] = a1;
 
311
    do1:
 
312
      a1 = ((op_t *) srcp)[0];
 
313
      ((op_t *) dstp)[0] = a0;
 
314
 
 
315
      srcp -= 8 * OPSIZ;
 
316
      dstp -= 8 * OPSIZ;
 
317
      len -= 8;
 
318
    }
 
319
  while (len != 0);
 
320
 
 
321
  /* This is the right position for do0.  Please don't move
 
322
     it into the loop.  */
 
323
 do0:
 
324
  ((op_t *) dstp)[7] = a1;
 
325
}
 
326
 
 
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.  */
 
331
 
 
332
void
 
333
_wordcopy_bwd_dest_aligned (dstp, srcp, len)
 
334
     long int dstp;
 
335
     long int srcp;
 
336
     size_t len;
 
337
{
 
338
  op_t a0, a1, a2, a3;
 
339
  int sh_1, sh_2;
 
340
 
 
341
  /* Calculate how to shift a word read at the memory operation
 
342
     aligned srcp to make it aligned for copy.  */
 
343
 
 
344
  sh_1 = 8 * (srcp % OPSIZ);
 
345
  sh_2 = 8 * OPSIZ - sh_1;
 
346
 
 
347
  /* Make srcp aligned by rounding it down to the beginning of the op_t
 
348
     it points in the middle of.  */
 
349
  srcp &= -OPSIZ;
 
350
  srcp += OPSIZ;
 
351
 
 
352
  switch (len % 4)
 
353
    {
 
354
    case 2:
 
355
      srcp -= 3 * OPSIZ;
 
356
      dstp -= 1 * OPSIZ;
 
357
      a2 = ((op_t *) srcp)[2];
 
358
      a1 = ((op_t *) srcp)[1];
 
359
      len += 2;
 
360
      goto do1;
 
361
    case 3:
 
362
      srcp -= 4 * OPSIZ;
 
363
      dstp -= 2 * OPSIZ;
 
364
      a3 = ((op_t *) srcp)[3];
 
365
      a2 = ((op_t *) srcp)[2];
 
366
      len += 1;
 
367
      goto do2;
 
368
    case 0:
 
369
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
370
        return;
 
371
      srcp -= 5 * OPSIZ;
 
372
      dstp -= 3 * OPSIZ;
 
373
      a0 = ((op_t *) srcp)[4];
 
374
      a3 = ((op_t *) srcp)[3];
 
375
      goto do3;
 
376
    case 1:
 
377
      srcp -= 6 * OPSIZ;
 
378
      dstp -= 4 * OPSIZ;
 
379
      a1 = ((op_t *) srcp)[5];
 
380
      a0 = ((op_t *) srcp)[4];
 
381
      len -= 1;
 
382
      if (OP_T_THRES <= 3 * OPSIZ && len == 0)
 
383
        goto do0;
 
384
      goto do4;                 /* No-op.  */
 
385
    }
 
386
 
 
387
  do
 
388
    {
 
389
    do4:
 
390
      a3 = ((op_t *) srcp)[3];
 
391
      ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
 
392
    do3:
 
393
      a2 = ((op_t *) srcp)[2];
 
394
      ((op_t *) dstp)[2] = MERGE (a3, sh_1, a0, sh_2);
 
395
    do2:
 
396
      a1 = ((op_t *) srcp)[1];
 
397
      ((op_t *) dstp)[1] = MERGE (a2, sh_1, a3, sh_2);
 
398
    do1:
 
399
      a0 = ((op_t *) srcp)[0];
 
400
      ((op_t *) dstp)[0] = MERGE (a1, sh_1, a2, sh_2);
 
401
 
 
402
      srcp -= 4 * OPSIZ;
 
403
      dstp -= 4 * OPSIZ;
 
404
      len -= 4;
 
405
    }
 
406
  while (len != 0);
 
407
 
 
408
  /* This is the right position for do0.  Please don't move
 
409
     it into the loop.  */
 
410
 do0:
 
411
  ((op_t *) dstp)[3] = MERGE (a0, sh_1, a1, sh_2);
 
412
}