source: trunk/libs/newlib/src/newlib/libc/machine/visium/memcpy.c @ 444

Last change on this file since 444 was 444, checked in by satin@…, 6 years ago

add newlib,libalmos-mkh, restructure shared_syscalls.h and mini-libc

File size: 18.5 KB
Line 
1/* memcpy for the Visium processor.
2
3   Copyright (c) 2015 Rolls-Royce Controls and Data Services Limited.
4   All rights reserved.
5
6   Redistribution and use in source and binary forms, with or without
7   modification, are permitted provided that the following conditions are met:
8
9     * Redistributions of source code must retain the above copyright notice,
10       this list of conditions and the following disclaimer.
11     * Redistributions in binary form must reproduce the above copyright
12       notice, this list of conditions and the following disclaimer in the
13       documentation and/or other materials provided with the distribution.
14     * Neither the name of Rolls-Royce Controls and Data Services Limited nor
15       the names of its contributors may be used to endorse or promote products
16       derived from this software without specific prior written permission.
17
18   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28   THE POSSIBILITY OF SUCH DAMAGE.  */
29
30/* This file must be kept in sync with libgcc/config/visium/memcpy.c  */
31
32#include <stddef.h>
33#include "memcpy.h"
34
35#define INST_BARRIER   __asm__ __volatile__ ("":::"memory");
36
37#define MOVE_32_OBJECTS(in,out) \
38do {                            \
39  INST_BARRIER                  \
40  m0 = in [0];                  \
41  m1 = in [1];                  \
42  m2 = in [2];                  \
43  m3 = in [3];                  \
44  out [0] = m0;                 \
45  out [1] = m1;                 \
46  out [2] = m2;                 \
47  out [3] = m3;                 \
48  INST_BARRIER                  \
49  m0 = in [4];                  \
50  m1 = in [5];                  \
51  m2 = in [6];                  \
52  m3 = in [7];                  \
53  out [4] = m0;                 \
54  out [5] = m1;                 \
55  out [6] = m2;                 \
56  out [7] = m3;                 \
57  INST_BARRIER                  \
58  m0 = in [8];                  \
59  m1 = in [9];                  \
60  m2 = in [10];                 \
61  m3 = in [11];                 \
62  out [8] = m0;                 \
63  out [9] = m1;                 \
64  out [10] = m2;                \
65  out [11] = m3;                \
66  INST_BARRIER                  \
67  m0 = in [12];                 \
68  m1 = in [13];                 \
69  m2 = in [14];                 \
70  m3 = in [15];                 \
71  out [12] = m0;                \
72  out [13] = m1;                \
73  out [14] = m2;                \
74  out [15] = m3;                \
75  INST_BARRIER                  \
76  m0 = in [16];                 \
77  m1 = in [17];                 \
78  m2 = in [18];                 \
79  m3 = in [19];                 \
80  out [16] = m0;                \
81  out [17] = m1;                \
82  out [18] = m2;                \
83  out [19] = m3;                \
84  INST_BARRIER                  \
85  m0 = in [20];                 \
86  m1 = in [21];                 \
87  m2 = in [22];                 \
88  m3 = in [23];                 \
89  out [20] = m0;                \
90  out [21] = m1;                \
91  out [22] = m2;                \
92  out [23] = m3;                \
93  INST_BARRIER                  \
94  m0 = in [24];                 \
95  m1 = in [25];                 \
96  m2 = in [26];                 \
97  m3 = in [27];                 \
98  out [24] = m0;                \
99  out [25] = m1;                \
100  out [26] = m2;                \
101  out [27] = m3;                \
102  INST_BARRIER                  \
103  m0 =  in [28];                \
104  m1 = in [29];                 \
105  m2 = in [30];                 \
106  m3 = in [31];                 \
107  out [28] = m0;                \
108  out [29] = m1;                \
109  out [30] = m2;                \
110  out [31] = m3;                \
111  INST_BARRIER                  \
112  in += 32;                     \
113  out += 32;                    \
114} while(0)
115
116#define MOVE_16_OBJECTS(in,out) \
117do {                            \
118  INST_BARRIER                  \
119  m0 = in [0];                  \
120  m1 = in [1];                  \
121  m2 = in [2];                  \
122  m3 = in [3];                  \
123  out [0] = m0;                 \
124  out [1] = m1;                 \
125  out [2] = m2;                 \
126  out [3] = m3;                 \
127  INST_BARRIER                  \
128  m0 = in [4];                  \
129  m1 = in [5];                  \
130  m2 = in [6];                  \
131  m3 = in [7];                  \
132  out [4] = m0;                 \
133  out [5] = m1;                 \
134  out [6] = m2;                 \
135  out [7] = m3;                 \
136  INST_BARRIER                  \
137  m0 = in [8];                  \
138  m1 = in [9];                  \
139  m2 = in [10];                 \
140  m3 = in [11];                 \
141  out [8] = m0;                 \
142  out [9] = m1;                 \
143  out [10] = m2;                \
144  out [11] = m3;                \
145  INST_BARRIER                  \
146  m0 = in [12];                 \
147  m1 = in [13];                 \
148  m2 = in [14];                 \
149  m3 = in [15];                 \
150  out [12] = m0;                \
151  out [13] = m1;                \
152  out [14] = m2;                \
153  out [15] = m3;                \
154  INST_BARRIER                  \
155  in += 16;                     \
156  out += 16;                    \
157} while(0)
158
159#define MOVE_12_OBJECTS(in,out) \
160do {                            \
161  INST_BARRIER                  \
162  m0 = in [0];                  \
163  m1 = in [1];                  \
164  m2 = in [2];                  \
165  m3 = in [3];                  \
166  out [0] = m0;                 \
167  out [1] = m1;                 \
168  out [2] = m2;                 \
169  out [3] = m3;                 \
170  INST_BARRIER                  \
171  m0 = in [4];                  \
172  m1 = in [5];                  \
173  m2 = in [6];                  \
174  m3 = in [7];                  \
175  out [4] = m0;                 \
176  out [5] = m1;                 \
177  out [6] = m2;                 \
178  out [7] = m3;                 \
179  INST_BARRIER                  \
180  m0 = in [8];                  \
181  m1 = in [9];                  \
182  m2 = in [10];                 \
183  m3 = in [11];                 \
184  out [8] = m0;                 \
185  out [9] = m1;                 \
186  out [10] = m2;                \
187  out [11] = m3;                \
188  INST_BARRIER                  \
189  in += 12;                     \
190  out += 12;                    \
191} while(0)
192
193#define MOVE_11_OBJECTS(in,out) \
194do {                            \
195  INST_BARRIER                  \
196  m0 = in [0];                  \
197  m1 = in [1];                  \
198  m2 = in [2];                  \
199  m3 = in [3];                  \
200  out [0] = m0;                 \
201  out [1] = m1;                 \
202  out [2] = m2;                 \
203  out [3] = m3;                 \
204  INST_BARRIER                  \
205  m0 = in [4];                  \
206  m1 = in [5];                  \
207  m2 = in [6];                  \
208  m3 = in [7];                  \
209  out [4] = m0;                 \
210  out [5] = m1;                 \
211  out [6] = m2;                 \
212  out [7] = m3;                 \
213  INST_BARRIER                  \
214  m0 = in [8];                  \
215  m1 = in [9];                  \
216  m2 = in [10];                 \
217  out [8] = m0;                 \
218  out [9] = m1;                 \
219  out [10] = m2;                \
220  INST_BARRIER                  \
221  in += 11;                     \
222  out += 11;                    \
223} while(0)
224
225#define MOVE_10_OBJECTS(in,out) \
226do {                            \
227  INST_BARRIER                  \
228  m0 = in [0];                  \
229  m1 = in [1];                  \
230  m2 = in [2];                  \
231  m3 = in [3];                  \
232  out [0] = m0;                 \
233  out [1] = m1;                 \
234  out [2] = m2;                 \
235  out [3] = m3;                 \
236  INST_BARRIER                  \
237  m0 = in [4];                  \
238  m1 = in [5];                  \
239  m2 = in [6];                  \
240  m3 = in [7];                  \
241  out [4] = m0;                 \
242  m0 = in [8];                  \
243  out [5] = m1;                 \
244  m1 = in [9];                  \
245  out [6] = m2;                 \
246  out [7] = m3;                 \
247  out [8] = m0;                 \
248  out [9] = m1;                 \
249  INST_BARRIER                  \
250  in += 10;                     \
251  out += 10;                    \
252} while(0)
253
254#define MOVE_9_OBJECTS(in,out)  \
255do {                            \
256  INST_BARRIER                  \
257  m0 = in [0];                  \
258  m1 = in [1];                  \
259  m2 = in [2];                  \
260  m3 = in [3];                  \
261  out [0] = m0;                 \
262  out [1] = m1;                 \
263  out [2] = m2;                 \
264  out [3] = m3;                 \
265  INST_BARRIER                  \
266  m0 = in [4];                  \
267  m1 = in [5];                  \
268  m2 = in [6];                  \
269  m3 = in [7];                  \
270  out [4] = m0;                 \
271  out [5] = m1;                 \
272  out [6] = m2;                 \
273  out [7] = m3;                 \
274  INST_BARRIER                  \
275  m0 = in [8];                  \
276  out [8] = m0;                 \
277  in += 9;                      \
278  out += 9;                     \
279} while(0)
280
281#define MOVE_8_OBJECTS(in,out)  \
282do {                            \
283  INST_BARRIER                  \
284  m0 = in [0];                  \
285  m1 = in [1];                  \
286  m2 = in [2];                  \
287  m3 = in [3];                  \
288  out [0] = m0;                 \
289  out [1] = m1;                 \
290  out [2] = m2;                 \
291  out [3] = m3;                 \
292  INST_BARRIER                  \
293  m0 = in [4];                  \
294  m1 = in [5];                  \
295  m2 = in [6];                  \
296  m3 = in [7];                  \
297  out [4] = m0;                 \
298  out [5] = m1;                 \
299  out [6] = m2;                 \
300  out [7] = m3;                 \
301  INST_BARRIER                  \
302  in += 8;                      \
303  out += 8;                     \
304} while(0)
305
306#define MOVE_7_OBJECTS(in,out)  \
307do {                            \
308  INST_BARRIER                  \
309  m0 = in [0];                  \
310  m1 = in [1];                  \
311  m2 = in [2];                  \
312  m3 = in [3];                  \
313  out [0] = m0;                 \
314  out [1] = m1;                 \
315  out [2] = m2;                 \
316  out [3] = m3;                 \
317  INST_BARRIER                  \
318  m0 = in [4];                  \
319  m1 = in [5];                  \
320  m2 = in [6];                  \
321  out [4] = m0;                 \
322  out [5] = m1;                 \
323  out [6] = m2;                 \
324  INST_BARRIER                  \
325  in += 7;                      \
326  out += 7;                     \
327} while(0)
328
329#define MOVE_6_OBJECTS(in,out)  \
330do {                            \
331  INST_BARRIER                  \
332  m0 = in [0];                  \
333  m1 = in [1];                  \
334  m2 = in [2];                  \
335  m3 = in [3];                  \
336  out [0] = m0;                 \
337  INST_BARRIER                  \
338  m0 = in [4];                  \
339  out [1] = m1;                 \
340  INST_BARRIER                  \
341  m1 = in [5];                  \
342  out [2] = m2;                 \
343  out [3] = m3;                 \
344  out [4] = m0;                 \
345  out [5] = m1;                 \
346  INST_BARRIER                  \
347  in += 6;                      \
348  out += 6;                     \
349} while(0)
350
351#define MOVE_5_OBJECTS(in,out)  \
352do {                            \
353  INST_BARRIER                  \
354  m0 = in [0];                  \
355  m1 = in [1];                  \
356  m2 = in [2];                  \
357  m3 = in [3];                  \
358  INST_BARRIER                  \
359  out [0] = m0;                 \
360  m0 = in [4];                  \
361  INST_BARRIER                  \
362  out [1] = m1;                 \
363  out [2] = m2;                 \
364  out [3] = m3;                 \
365  out [4] = m0;                 \
366  INST_BARRIER                  \
367  in += 5;                      \
368  out += 5;                     \
369} while(0)
370
371#define MOVE_4_OBJECTS(in,out)  \
372do {                            \
373  INST_BARRIER                  \
374  m0 = in [0];                  \
375  m1 = in [1];                  \
376  m2 = in [2];                  \
377  m3 = in [3];                  \
378  out [0] = m0;                 \
379  out [1] = m1;                 \
380  out [2] = m2;                 \
381  out [3] = m3;                 \
382  INST_BARRIER                  \
383  in += 4;                      \
384  out += 4;                     \
385} while(0)
386
387#define MOVE_3_OBJECTS(in,out)  \
388do {                            \
389  INST_BARRIER                  \
390  m0 = in [0];                  \
391  m1 = in [1];                  \
392  m2 = in [2];                  \
393  out [0] = m0;                 \
394  out [1] = m1;                 \
395  out [2] = m2;                 \
396  INST_BARRIER                  \
397  in += 3;                      \
398  out += 3;                     \
399} while(0)
400
401#define MOVE_2_OBJECTS(in,out)  \
402do {                            \
403  INST_BARRIER                  \
404  m0 = in [0];                  \
405  m1 = in [1];                  \
406  out [0] = m0;                 \
407  out [1] = m1;                 \
408  INST_BARRIER                  \
409  in += 2;                      \
410  out += 2;                     \
411} while(0)
412
413#define MOVE_1_OBJECT(in,out)   \
414do {                            \
415  INST_BARRIER                  \
416  m0 = in [0];                  \
417  out [0] = m0;                 \
418  INST_BARRIER                  \
419  in += 1;                      \
420  out += 1;                     \
421} while(0)
422
423
424static inline void
425__int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) 
426{
427  int value = n;
428  int loop_var;
429  const int *in = s2;
430  int *out = s1;
431  int count;
432  int m0,m1,m2,m3;
433
434  /* This code currently give a stall for any value with a 1->2 in the low 5
435     bits, i.e.  1,2, 33,34 ? not acceptable!  */
436  switch (value & 0x1f)
437    {
438    case 0:
439      break;
440    case 1:
441      MOVE_1_OBJECT (in, out);
442      break;
443    case 2:
444      MOVE_2_OBJECTS (in, out);
445      break;
446    case 3:
447      MOVE_3_OBJECTS (in, out);
448      break;
449    case 4:
450      MOVE_4_OBJECTS (in, out);
451      break;
452    case 5:
453      MOVE_5_OBJECTS (in, out);
454      break;
455    case 6:
456      MOVE_6_OBJECTS (in, out);
457      break;
458    case 7:
459      MOVE_7_OBJECTS (in, out);
460      break;
461    case 8:
462      MOVE_8_OBJECTS (in, out);
463      break;
464    case 9:
465      MOVE_9_OBJECTS (in, out);
466      break;
467    case 10:
468      MOVE_10_OBJECTS (in, out);
469      break;
470    case 11:
471      MOVE_11_OBJECTS (in, out);
472      break;
473    case 12:
474      MOVE_12_OBJECTS (in, out);
475      break;
476    case 13:
477      MOVE_9_OBJECTS (in, out);
478      MOVE_4_OBJECTS (in, out);
479      break;
480    case 14:
481      MOVE_12_OBJECTS (in, out);
482      MOVE_2_OBJECTS (in, out);
483      break;
484    case 15:
485      MOVE_11_OBJECTS (in, out);
486      MOVE_4_OBJECTS (in, out);
487      break;
488    case 16:
489      MOVE_16_OBJECTS (in, out);
490      break;
491    case 17:
492      MOVE_11_OBJECTS (in, out);
493      MOVE_6_OBJECTS (in, out);
494      break;
495    case 18:
496      MOVE_9_OBJECTS (in, out);
497      MOVE_9_OBJECTS (in, out);
498      break;
499    case 19:
500      MOVE_16_OBJECTS (in, out);
501      MOVE_3_OBJECTS (in, out);
502      break;
503    case 20:
504      MOVE_16_OBJECTS (in, out);
505      MOVE_4_OBJECTS (in, out);
506      break;
507    case 21:
508      MOVE_16_OBJECTS (in, out);
509      MOVE_5_OBJECTS (in, out);
510      break;
511    case 22:
512      MOVE_16_OBJECTS (in, out);
513      MOVE_6_OBJECTS (in, out);
514      break;
515    case 23:
516      MOVE_16_OBJECTS (in, out);
517      MOVE_7_OBJECTS (in, out);
518      break;
519    case 24:
520      MOVE_16_OBJECTS (in, out);
521      MOVE_8_OBJECTS (in, out);
522      break;
523    case 25:
524      MOVE_16_OBJECTS (in, out);
525      MOVE_9_OBJECTS (in, out);
526      break;
527    case 26:
528      MOVE_16_OBJECTS (in, out);
529      MOVE_10_OBJECTS (in, out);
530      break;
531    case 27:
532      MOVE_16_OBJECTS (in, out);
533      MOVE_11_OBJECTS (in, out);
534      break;
535    case 28:
536      MOVE_16_OBJECTS (in, out);
537      MOVE_8_OBJECTS (in, out);
538      MOVE_4_OBJECTS (in, out);
539      break;
540    case 29:
541      MOVE_16_OBJECTS (in, out);
542      MOVE_9_OBJECTS (in, out);
543      MOVE_4_OBJECTS (in, out);
544      break;
545    case 30:
546      MOVE_16_OBJECTS (in, out);
547      MOVE_12_OBJECTS (in, out);
548      MOVE_2_OBJECTS (in, out);
549      break;
550    case 31:
551      MOVE_16_OBJECTS (in, out);
552      MOVE_11_OBJECTS (in, out);
553      MOVE_4_OBJECTS (in, out);
554      break;
555    }
556
557  /* This loop governs the asmptoptic behaviour of this algorithm, for long
558     word copies.  */
559  count = value >> 5;
560  for (loop_var = 0; loop_var < count; loop_var++)
561    MOVE_32_OBJECTS (in, out);
562}
563
564static inline void
565__shrt_int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) 
566{
567  int value = n;
568  int loop_var;
569  const short int *in = s2;
570  int short *out = s1;
571  int count;
572  int m0,m1,m2,m3;
573
574 /* This code currently give a stall for any value with a 1->2 in the low 5
575    bits, i.e.  1,2, 33,34 ? not acceptable!  */
576  switch (value & 0x1f)
577    {
578    case 0:
579      break;
580    case 1:
581      MOVE_1_OBJECT (in, out);
582      break;
583    case 2:
584      MOVE_2_OBJECTS (in, out);
585      break;
586    case 3:
587      MOVE_3_OBJECTS (in, out);
588      break;
589    case 4:
590      MOVE_4_OBJECTS (in, out);
591      break;
592    case 5:
593      MOVE_5_OBJECTS (in, out);
594      break;
595    case 6:
596      MOVE_6_OBJECTS (in, out);
597      break;
598    case 7:
599      MOVE_7_OBJECTS (in, out);
600      break;
601    case 8:
602      MOVE_8_OBJECTS (in, out);
603      break;
604    case 9:
605      MOVE_9_OBJECTS (in, out);
606      break;
607    case 10:
608      MOVE_10_OBJECTS (in, out);
609      break;
610    case 11:
611      MOVE_11_OBJECTS (in, out);
612      break;
613    case 12:
614      MOVE_12_OBJECTS (in, out);
615      break;
616    case 13:
617      MOVE_9_OBJECTS (in, out);
618      MOVE_4_OBJECTS (in, out);
619      break;
620    case 14:
621      MOVE_12_OBJECTS (in, out);
622      MOVE_2_OBJECTS (in, out);
623      break;
624    case 15:
625      MOVE_11_OBJECTS (in, out);
626      MOVE_4_OBJECTS (in, out);
627      break;
628    case 16:
629      MOVE_16_OBJECTS (in, out);
630      break;
631    case 17:
632      MOVE_11_OBJECTS (in, out);
633      MOVE_6_OBJECTS (in, out);
634      break;
635    case 18:
636      MOVE_9_OBJECTS (in, out);
637      MOVE_9_OBJECTS (in, out);
638      break;
639    case 19:
640      MOVE_16_OBJECTS (in, out);
641      MOVE_3_OBJECTS (in, out);
642      break;
643    case 20:
644      MOVE_16_OBJECTS (in, out);
645      MOVE_4_OBJECTS (in, out);
646      break;
647    case 21:
648      MOVE_16_OBJECTS (in, out);
649      MOVE_5_OBJECTS (in, out);
650      break;
651    case 22:
652      MOVE_16_OBJECTS (in, out);
653      MOVE_6_OBJECTS (in, out);
654      break;
655    case 23:
656      MOVE_16_OBJECTS (in, out);
657      MOVE_7_OBJECTS (in, out);
658      break;
659    case 24:
660      MOVE_16_OBJECTS (in, out);
661      MOVE_8_OBJECTS (in, out);
662      break;
663    case 25:
664      MOVE_16_OBJECTS (in, out);
665      MOVE_9_OBJECTS (in, out);
666      break;
667    case 26:
668      MOVE_16_OBJECTS (in, out);
669      MOVE_10_OBJECTS (in, out);
670      break;
671    case 27:
672      MOVE_16_OBJECTS (in, out);
673      MOVE_11_OBJECTS (in, out);
674      break;
675    case 28:
676      MOVE_16_OBJECTS (in, out);
677      MOVE_8_OBJECTS (in, out);
678      MOVE_4_OBJECTS (in, out);
679      break;
680    case 29:
681      MOVE_16_OBJECTS (in, out);
682      MOVE_9_OBJECTS (in, out);
683      MOVE_4_OBJECTS (in, out);
684      break;
685    case 30:
686      MOVE_16_OBJECTS (in, out);
687      MOVE_12_OBJECTS (in, out);
688      MOVE_2_OBJECTS (in, out);
689      break;
690    case 31:
691      MOVE_16_OBJECTS (in, out);
692      MOVE_11_OBJECTS (in, out);
693      MOVE_4_OBJECTS (in, out);
694      break;
695    }
696
697  /* This loop governs the asmptoptic behaviour of this algorithm, for long
698     word copies.  */
699  count = value >> 5;
700  for (loop_var = 0; loop_var < count; loop_var++)
701    MOVE_32_OBJECTS (in, out);
702}
703
704
705static inline void
706__byte_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) 
707{
708  int value = n;
709  int loop_var;
710  const char *in = s2;
711  char *out = s1;
712  int count;
713  int m0,m1,m2,m3;
714
715 /* This code currently give a stall for any value with a 1->2 in the low 5
716    bits, i.e.  1,2, 33,34 ? not acceptable!  */
717  switch (value & 0x1f)
718    {
719    case 0:
720      break;
721    case 1:
722      MOVE_1_OBJECT (in, out);
723      break;
724    case 2:
725      MOVE_2_OBJECTS (in, out);
726      break;
727    case 3:
728      MOVE_3_OBJECTS (in, out);
729      break;
730    case 4:
731      MOVE_4_OBJECTS (in, out);
732      break;
733    case 5:
734      MOVE_5_OBJECTS (in, out);
735      break;
736    case 6:
737      MOVE_6_OBJECTS (in, out);
738      break;
739    case 7:
740      MOVE_7_OBJECTS (in, out);
741      break;
742    case 8:
743      MOVE_8_OBJECTS (in, out);
744      break;
745    case 9:
746      MOVE_9_OBJECTS (in, out);
747      break;
748    case 10:
749      MOVE_10_OBJECTS (in, out);
750      break;
751    case 11:
752      MOVE_11_OBJECTS (in, out);
753      break;
754    case 12:
755      MOVE_12_OBJECTS (in, out);
756      break;
757    case 13:
758      MOVE_9_OBJECTS (in, out);
759      MOVE_4_OBJECTS (in, out);
760      break;
761    case 14:
762      MOVE_12_OBJECTS (in, out);
763      MOVE_2_OBJECTS (in, out);
764      break;
765    case 15:
766      MOVE_11_OBJECTS (in, out);
767      MOVE_4_OBJECTS (in, out);
768      break;
769    case 16:
770      MOVE_16_OBJECTS (in, out);
771      break;
772    case 17:
773      MOVE_11_OBJECTS (in, out);
774      MOVE_6_OBJECTS (in, out);
775      break;
776    case 18:
777      MOVE_9_OBJECTS (in, out);
778      MOVE_9_OBJECTS (in, out);
779      break;
780    case 19:
781      MOVE_16_OBJECTS (in, out);
782      MOVE_3_OBJECTS (in, out);
783      break;
784    case 20:
785      MOVE_16_OBJECTS (in, out);
786      MOVE_4_OBJECTS (in, out);
787      break;
788    case 21:
789      MOVE_16_OBJECTS (in, out);
790      MOVE_5_OBJECTS (in, out);
791      break;
792    case 22:
793      MOVE_16_OBJECTS (in, out);
794      MOVE_6_OBJECTS (in, out);
795      break;
796    case 23:
797      MOVE_16_OBJECTS (in, out);
798      MOVE_7_OBJECTS (in, out);
799      break;
800    case 24:
801      MOVE_16_OBJECTS (in, out);
802      MOVE_8_OBJECTS (in, out);
803      break;
804    case 25:
805      MOVE_16_OBJECTS (in, out);
806      MOVE_9_OBJECTS (in, out);
807      break;
808    case 26:
809      MOVE_16_OBJECTS (in, out);
810      MOVE_10_OBJECTS (in, out);
811      break;
812    case 27:
813      MOVE_16_OBJECTS (in, out);
814      MOVE_11_OBJECTS (in, out);
815      break;
816    case 28:
817      MOVE_16_OBJECTS (in, out);
818      MOVE_8_OBJECTS (in, out);
819      MOVE_4_OBJECTS (in, out);
820      break;
821    case 29:
822      MOVE_16_OBJECTS (in, out);
823      MOVE_9_OBJECTS (in, out);
824      MOVE_4_OBJECTS (in, out);
825      break;
826    case 30:
827      MOVE_16_OBJECTS (in, out);
828      MOVE_12_OBJECTS (in, out);
829      MOVE_2_OBJECTS (in, out);
830      break;
831    case 31:
832      MOVE_16_OBJECTS (in, out);
833      MOVE_11_OBJECTS (in, out);
834      MOVE_4_OBJECTS (in, out);
835      break;
836    }
837
838  /* This loop governs the asmptoptic behaviour of this algorithm, for long
839     word copies.  */
840  count = value >> 5;
841  for (loop_var = 0; loop_var < count; loop_var++)
842    MOVE_32_OBJECTS (in, out);
843}
844
845
846/* Exposed interface.  */
847
848void *
849memcpy (void *__restrict s1, const void *__restrict s2, size_t n)
850{
851  void *result = s1;
852
853  /* None of the following handles copying zero bytes.  */
854  if (n != 0)
855    {
856      unsigned test = (unsigned) s2 | (unsigned) s1 | (unsigned) n;
857
858      if (test & 1)
859        __byte_memcpy (s1, s2, n);
860      else if (test & 2)
861        __shrt_int_memcpy (s1, s2, n >> 1);
862      else
863#ifdef __VISIUM_ARCH_BMI__
864        __asm__ __volatile__ ("bmd     %0,%1,%2"
865                              : "+t" (s1), "+u" (s2), "+v" (n)
866                              :
867                              : "r4", "r5", "r6", "memory");
868#else
869        __int_memcpy (s1, s2, n >> 2);
870#endif /* __VISIUM_ARCH_BMI__ */
871    }
872
873  return result;
874}
Note: See TracBrowser for help on using the repository browser.