Import pre-release gcc-5.0 to new vendor branch
[dragonfly.git] / contrib / gcc-5.0 / libgcc / config / visium / memcpy.c
1 /* Copyright (C) 2012-2015 Free Software Foundation, Inc.
2
3    This file is part of GCC.
4
5    GCC is free software; you can redistribute it and/or modify it
6    under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 3, or (at your option)
8    any later version.
9
10    GCC is distributed in the hope that it will be useful, but WITHOUT
11    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
13    License for more details.
14
15    Under Section 7 of GPL version 3, you are granted additional
16    permissions described in the GCC Runtime Library Exception, version
17    3.1, as published by the Free Software Foundation.
18
19    You should have received a copy of the GNU General Public License and
20    a copy of the GCC Runtime Library Exception along with this program;
21    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22    <http://www.gnu.org/licenses/>.  */
23
24 /* This file must be kept in sync with newlib/libc/machine/visium/memcpy.c  */
25
26 #include <stddef.h>
27 #include "memcpy.h"
28
29 #define INST_BARRIER   __asm__ __volatile__ ("":::"memory");
30
31 #define MOVE_32_OBJECTS(in,out) \
32 do {                            \
33   INST_BARRIER                  \
34   m0 = in [0];                  \
35   m1 = in [1];                  \
36   m2 = in [2];                  \
37   m3 = in [3];                  \
38   out [0] = m0;                 \
39   out [1] = m1;                 \
40   out [2] = m2;                 \
41   out [3] = m3;                 \
42   INST_BARRIER                  \
43   m0 = in [4];                  \
44   m1 = in [5];                  \
45   m2 = in [6];                  \
46   m3 = in [7];                  \
47   out [4] = m0;                 \
48   out [5] = m1;                 \
49   out [6] = m2;                 \
50   out [7] = m3;                 \
51   INST_BARRIER                  \
52   m0 = in [8];                  \
53   m1 = in [9];                  \
54   m2 = in [10];                 \
55   m3 = in [11];                 \
56   out [8] = m0;                 \
57   out [9] = m1;                 \
58   out [10] = m2;                \
59   out [11] = m3;                \
60   INST_BARRIER                  \
61   m0 = in [12];                 \
62   m1 = in [13];                 \
63   m2 = in [14];                 \
64   m3 = in [15];                 \
65   out [12] = m0;                \
66   out [13] = m1;                \
67   out [14] = m2;                \
68   out [15] = m3;                \
69   INST_BARRIER                  \
70   m0 = in [16];                 \
71   m1 = in [17];                 \
72   m2 = in [18];                 \
73   m3 = in [19];                 \
74   out [16] = m0;                \
75   out [17] = m1;                \
76   out [18] = m2;                \
77   out [19] = m3;                \
78   INST_BARRIER                  \
79   m0 = in [20];                 \
80   m1 = in [21];                 \
81   m2 = in [22];                 \
82   m3 = in [23];                 \
83   out [20] = m0;                \
84   out [21] = m1;                \
85   out [22] = m2;                \
86   out [23] = m3;                \
87   INST_BARRIER                  \
88   m0 = in [24];                 \
89   m1 = in [25];                 \
90   m2 = in [26];                 \
91   m3 = in [27];                 \
92   out [24] = m0;                \
93   out [25] = m1;                \
94   out [26] = m2;                \
95   out [27] = m3;                \
96   INST_BARRIER                  \
97   m0 =  in [28];                \
98   m1 = in [29];                 \
99   m2 = in [30];                 \
100   m3 = in [31];                 \
101   out [28] = m0;                \
102   out [29] = m1;                \
103   out [30] = m2;                \
104   out [31] = m3;                \
105   INST_BARRIER                  \
106   in += 32;                     \
107   out += 32;                    \
108 } while(0)
109
110 #define MOVE_16_OBJECTS(in,out) \
111 do {                            \
112   INST_BARRIER                  \
113   m0 = in [0];                  \
114   m1 = in [1];                  \
115   m2 = in [2];                  \
116   m3 = in [3];                  \
117   out [0] = m0;                 \
118   out [1] = m1;                 \
119   out [2] = m2;                 \
120   out [3] = m3;                 \
121   INST_BARRIER                  \
122   m0 = in [4];                  \
123   m1 = in [5];                  \
124   m2 = in [6];                  \
125   m3 = in [7];                  \
126   out [4] = m0;                 \
127   out [5] = m1;                 \
128   out [6] = m2;                 \
129   out [7] = m3;                 \
130   INST_BARRIER                  \
131   m0 = in [8];                  \
132   m1 = in [9];                  \
133   m2 = in [10];                 \
134   m3 = in [11];                 \
135   out [8] = m0;                 \
136   out [9] = m1;                 \
137   out [10] = m2;                \
138   out [11] = m3;                \
139   INST_BARRIER                  \
140   m0 = in [12];                 \
141   m1 = in [13];                 \
142   m2 = in [14];                 \
143   m3 = in [15];                 \
144   out [12] = m0;                \
145   out [13] = m1;                \
146   out [14] = m2;                \
147   out [15] = m3;                \
148   INST_BARRIER                  \
149   in += 16;                     \
150   out += 16;                    \
151 } while(0)
152
153 #define MOVE_12_OBJECTS(in,out) \
154 do {                            \
155   INST_BARRIER                  \
156   m0 = in [0];                  \
157   m1 = in [1];                  \
158   m2 = in [2];                  \
159   m3 = in [3];                  \
160   out [0] = m0;                 \
161   out [1] = m1;                 \
162   out [2] = m2;                 \
163   out [3] = m3;                 \
164   INST_BARRIER                  \
165   m0 = in [4];                  \
166   m1 = in [5];                  \
167   m2 = in [6];                  \
168   m3 = in [7];                  \
169   out [4] = m0;                 \
170   out [5] = m1;                 \
171   out [6] = m2;                 \
172   out [7] = m3;                 \
173   INST_BARRIER                  \
174   m0 = in [8];                  \
175   m1 = in [9];                  \
176   m2 = in [10];                 \
177   m3 = in [11];                 \
178   out [8] = m0;                 \
179   out [9] = m1;                 \
180   out [10] = m2;                \
181   out [11] = m3;                \
182   INST_BARRIER                  \
183   in += 12;                     \
184   out += 12;                    \
185 } while(0)
186
187 #define MOVE_11_OBJECTS(in,out) \
188 do {                            \
189   INST_BARRIER                  \
190   m0 = in [0];                  \
191   m1 = in [1];                  \
192   m2 = in [2];                  \
193   m3 = in [3];                  \
194   out [0] = m0;                 \
195   out [1] = m1;                 \
196   out [2] = m2;                 \
197   out [3] = m3;                 \
198   INST_BARRIER                  \
199   m0 = in [4];                  \
200   m1 = in [5];                  \
201   m2 = in [6];                  \
202   m3 = in [7];                  \
203   out [4] = m0;                 \
204   out [5] = m1;                 \
205   out [6] = m2;                 \
206   out [7] = m3;                 \
207   INST_BARRIER                  \
208   m0 = in [8];                  \
209   m1 = in [9];                  \
210   m2 = in [10];                 \
211   out [8] = m0;                 \
212   out [9] = m1;                 \
213   out [10] = m2;                \
214   INST_BARRIER                  \
215   in += 11;                     \
216   out += 11;                    \
217 } while(0)
218
219 #define MOVE_10_OBJECTS(in,out) \
220 do {                            \
221   INST_BARRIER                  \
222   m0 = in [0];                  \
223   m1 = in [1];                  \
224   m2 = in [2];                  \
225   m3 = in [3];                  \
226   out [0] = m0;                 \
227   out [1] = m1;                 \
228   out [2] = m2;                 \
229   out [3] = m3;                 \
230   INST_BARRIER                  \
231   m0 = in [4];                  \
232   m1 = in [5];                  \
233   m2 = in [6];                  \
234   m3 = in [7];                  \
235   out [4] = m0;                 \
236   m0 = in [8];                  \
237   out [5] = m1;                 \
238   m1 = in [9];                  \
239   out [6] = m2;                 \
240   out [7] = m3;                 \
241   out [8] = m0;                 \
242   out [9] = m1;                 \
243   INST_BARRIER                  \
244   in += 10;                     \
245   out += 10;                    \
246 } while(0)
247
248 #define MOVE_9_OBJECTS(in,out)  \
249 do {                            \
250   INST_BARRIER                  \
251   m0 = in [0];                  \
252   m1 = in [1];                  \
253   m2 = in [2];                  \
254   m3 = in [3];                  \
255   out [0] = m0;                 \
256   out [1] = m1;                 \
257   out [2] = m2;                 \
258   out [3] = m3;                 \
259   INST_BARRIER                  \
260   m0 = in [4];                  \
261   m1 = in [5];                  \
262   m2 = in [6];                  \
263   m3 = in [7];                  \
264   out [4] = m0;                 \
265   out [5] = m1;                 \
266   out [6] = m2;                 \
267   out [7] = m3;                 \
268   INST_BARRIER                  \
269   m0 = in [8];                  \
270   out [8] = m0;                 \
271   in += 9;                      \
272   out += 9;                     \
273 } while(0)
274
275 #define MOVE_8_OBJECTS(in,out)  \
276 do {                            \
277   INST_BARRIER                  \
278   m0 = in [0];                  \
279   m1 = in [1];                  \
280   m2 = in [2];                  \
281   m3 = in [3];                  \
282   out [0] = m0;                 \
283   out [1] = m1;                 \
284   out [2] = m2;                 \
285   out [3] = m3;                 \
286   INST_BARRIER                  \
287   m0 = in [4];                  \
288   m1 = in [5];                  \
289   m2 = in [6];                  \
290   m3 = in [7];                  \
291   out [4] = m0;                 \
292   out [5] = m1;                 \
293   out [6] = m2;                 \
294   out [7] = m3;                 \
295   INST_BARRIER                  \
296   in += 8;                      \
297   out += 8;                     \
298 } while(0)
299
300 #define MOVE_7_OBJECTS(in,out)  \
301 do {                            \
302   INST_BARRIER                  \
303   m0 = in [0];                  \
304   m1 = in [1];                  \
305   m2 = in [2];                  \
306   m3 = in [3];                  \
307   out [0] = m0;                 \
308   out [1] = m1;                 \
309   out [2] = m2;                 \
310   out [3] = m3;                 \
311   INST_BARRIER                  \
312   m0 = in [4];                  \
313   m1 = in [5];                  \
314   m2 = in [6];                  \
315   out [4] = m0;                 \
316   out [5] = m1;                 \
317   out [6] = m2;                 \
318   INST_BARRIER                  \
319   in += 7;                      \
320   out += 7;                     \
321 } while(0)
322
323 #define MOVE_6_OBJECTS(in,out)  \
324 do {                            \
325   INST_BARRIER                  \
326   m0 = in [0];                  \
327   m1 = in [1];                  \
328   m2 = in [2];                  \
329   m3 = in [3];                  \
330   out [0] = m0;                 \
331   INST_BARRIER                  \
332   m0 = in [4];                  \
333   out [1] = m1;                 \
334   INST_BARRIER                  \
335   m1 = in [5];                  \
336   out [2] = m2;                 \
337   out [3] = m3;                 \
338   out [4] = m0;                 \
339   out [5] = m1;                 \
340   INST_BARRIER                  \
341   in += 6;                      \
342   out += 6;                     \
343 } while(0)
344
345 #define MOVE_5_OBJECTS(in,out)  \
346 do {                            \
347   INST_BARRIER                  \
348   m0 = in [0];                  \
349   m1 = in [1];                  \
350   m2 = in [2];                  \
351   m3 = in [3];                  \
352   INST_BARRIER                  \
353   out [0] = m0;                 \
354   m0 = in [4];                  \
355   INST_BARRIER                  \
356   out [1] = m1;                 \
357   out [2] = m2;                 \
358   out [3] = m3;                 \
359   out [4] = m0;                 \
360   INST_BARRIER                  \
361   in += 5;                      \
362   out += 5;                     \
363 } while(0)
364
365 #define MOVE_4_OBJECTS(in,out)  \
366 do {                            \
367   INST_BARRIER                  \
368   m0 = in [0];                  \
369   m1 = in [1];                  \
370   m2 = in [2];                  \
371   m3 = in [3];                  \
372   out [0] = m0;                 \
373   out [1] = m1;                 \
374   out [2] = m2;                 \
375   out [3] = m3;                 \
376   INST_BARRIER                  \
377   in += 4;                      \
378   out += 4;                     \
379 } while(0)
380
381 #define MOVE_3_OBJECTS(in,out)  \
382 do {                            \
383   INST_BARRIER                  \
384   m0 = in [0];                  \
385   m1 = in [1];                  \
386   m2 = in [2];                  \
387   out [0] = m0;                 \
388   out [1] = m1;                 \
389   out [2] = m2;                 \
390   INST_BARRIER                  \
391   in += 3;                      \
392   out += 3;                     \
393 } while(0)
394
395 #define MOVE_2_OBJECTS(in,out)  \
396 do {                            \
397   INST_BARRIER                  \
398   m0 = in [0];                  \
399   m1 = in [1];                  \
400   out [0] = m0;                 \
401   out [1] = m1;                 \
402   INST_BARRIER                  \
403   in += 2;                      \
404   out += 2;                     \
405 } while(0)
406
407 #define MOVE_1_OBJECT(in,out)   \
408 do {                            \
409   INST_BARRIER                  \
410   m0 = in [0];                  \
411   out [0] = m0;                 \
412   INST_BARRIER                  \
413   in += 1;                      \
414   out += 1;                     \
415 } while(0)
416
417
418 static inline void
419 __int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) 
420 {
421   int value = n;
422   int loop_var;
423   const int *in = s2;
424   int *out = s1;
425   int count;
426   int m0,m1,m2,m3;
427
428   /* This code currently give a stall for any value with a 1->2 in the low 5
429      bits, i.e.  1,2, 33,34 ? not acceptable!  */
430   switch (value & 0x1f)
431     {
432     case 0:
433       break;
434     case 1:
435       MOVE_1_OBJECT (in, out);
436       break;
437     case 2:
438       MOVE_2_OBJECTS (in, out);
439       break;
440     case 3:
441       MOVE_3_OBJECTS (in, out);
442       break;
443     case 4:
444       MOVE_4_OBJECTS (in, out);
445       break;
446     case 5:
447       MOVE_5_OBJECTS (in, out);
448       break;
449     case 6:
450       MOVE_6_OBJECTS (in, out);
451       break;
452     case 7:
453       MOVE_7_OBJECTS (in, out);
454       break;
455     case 8:
456       MOVE_8_OBJECTS (in, out);
457       break;
458     case 9:
459       MOVE_9_OBJECTS (in, out);
460       break;
461     case 10:
462       MOVE_10_OBJECTS (in, out);
463       break;
464     case 11:
465       MOVE_11_OBJECTS (in, out);
466       break;
467     case 12:
468       MOVE_12_OBJECTS (in, out);
469       break;
470     case 13:
471       MOVE_9_OBJECTS (in, out);
472       MOVE_4_OBJECTS (in, out);
473       break;
474     case 14:
475       MOVE_12_OBJECTS (in, out);
476       MOVE_2_OBJECTS (in, out);
477       break;
478     case 15:
479       MOVE_11_OBJECTS (in, out);
480       MOVE_4_OBJECTS (in, out);
481       break;
482     case 16:
483       MOVE_16_OBJECTS (in, out);
484       break;
485     case 17:
486       MOVE_11_OBJECTS (in, out);
487       MOVE_6_OBJECTS (in, out);
488       break;
489     case 18:
490       MOVE_9_OBJECTS (in, out);
491       MOVE_9_OBJECTS (in, out);
492       break;
493     case 19:
494       MOVE_16_OBJECTS (in, out);
495       MOVE_3_OBJECTS (in, out);
496       break;
497     case 20:
498       MOVE_16_OBJECTS (in, out);
499       MOVE_4_OBJECTS (in, out);
500       break;
501     case 21:
502       MOVE_16_OBJECTS (in, out);
503       MOVE_5_OBJECTS (in, out);
504       break;
505     case 22:
506       MOVE_16_OBJECTS (in, out);
507       MOVE_6_OBJECTS (in, out);
508       break;
509     case 23:
510       MOVE_16_OBJECTS (in, out);
511       MOVE_7_OBJECTS (in, out);
512       break;
513     case 24:
514       MOVE_16_OBJECTS (in, out);
515       MOVE_8_OBJECTS (in, out);
516       break;
517     case 25:
518       MOVE_16_OBJECTS (in, out);
519       MOVE_9_OBJECTS (in, out);
520       break;
521     case 26:
522       MOVE_16_OBJECTS (in, out);
523       MOVE_10_OBJECTS (in, out);
524       break;
525     case 27:
526       MOVE_16_OBJECTS (in, out);
527       MOVE_11_OBJECTS (in, out);
528       break;
529     case 28:
530       MOVE_16_OBJECTS (in, out);
531       MOVE_8_OBJECTS (in, out);
532       MOVE_4_OBJECTS (in, out);
533       break;
534     case 29:
535       MOVE_16_OBJECTS (in, out);
536       MOVE_9_OBJECTS (in, out);
537       MOVE_4_OBJECTS (in, out);
538       break;
539     case 30:
540       MOVE_16_OBJECTS (in, out);
541       MOVE_12_OBJECTS (in, out);
542       MOVE_2_OBJECTS (in, out);
543       break;
544     case 31:
545       MOVE_16_OBJECTS (in, out);
546       MOVE_11_OBJECTS (in, out);
547       MOVE_4_OBJECTS (in, out);
548       break;
549     }
550
551   /* This loop governs the asmptoptic behaviour of this algorithm, for long
552      word copies.  */
553   count = value >> 5;
554   for (loop_var = 0; loop_var < count; loop_var++)
555     MOVE_32_OBJECTS (in, out);
556 }
557
558 static inline void
559 __shrt_int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) 
560 {
561   int value = n;
562   int loop_var;
563   const short int *in = s2;
564   int short *out = s1;
565   int count;
566   int m0,m1,m2,m3;
567
568  /* This code currently give a stall for any value with a 1->2 in the low 5
569     bits, i.e.  1,2, 33,34 ? not acceptable!  */
570   switch (value & 0x1f)
571     {
572     case 0:
573       break;
574     case 1:
575       MOVE_1_OBJECT (in, out);
576       break;
577     case 2:
578       MOVE_2_OBJECTS (in, out);
579       break;
580     case 3:
581       MOVE_3_OBJECTS (in, out);
582       break;
583     case 4:
584       MOVE_4_OBJECTS (in, out);
585       break;
586     case 5:
587       MOVE_5_OBJECTS (in, out);
588       break;
589     case 6:
590       MOVE_6_OBJECTS (in, out);
591       break;
592     case 7:
593       MOVE_7_OBJECTS (in, out);
594       break;
595     case 8:
596       MOVE_8_OBJECTS (in, out);
597       break;
598     case 9:
599       MOVE_9_OBJECTS (in, out);
600       break;
601     case 10:
602       MOVE_10_OBJECTS (in, out);
603       break;
604     case 11:
605       MOVE_11_OBJECTS (in, out);
606       break;
607     case 12:
608       MOVE_12_OBJECTS (in, out);
609       break;
610     case 13:
611       MOVE_9_OBJECTS (in, out);
612       MOVE_4_OBJECTS (in, out);
613       break;
614     case 14:
615       MOVE_12_OBJECTS (in, out);
616       MOVE_2_OBJECTS (in, out);
617       break;
618     case 15:
619       MOVE_11_OBJECTS (in, out);
620       MOVE_4_OBJECTS (in, out);
621       break;
622     case 16:
623       MOVE_16_OBJECTS (in, out);
624       break;
625     case 17:
626       MOVE_11_OBJECTS (in, out);
627       MOVE_6_OBJECTS (in, out);
628       break;
629     case 18:
630       MOVE_9_OBJECTS (in, out);
631       MOVE_9_OBJECTS (in, out);
632       break;
633     case 19:
634       MOVE_16_OBJECTS (in, out);
635       MOVE_3_OBJECTS (in, out);
636       break;
637     case 20:
638       MOVE_16_OBJECTS (in, out);
639       MOVE_4_OBJECTS (in, out);
640       break;
641     case 21:
642       MOVE_16_OBJECTS (in, out);
643       MOVE_5_OBJECTS (in, out);
644       break;
645     case 22:
646       MOVE_16_OBJECTS (in, out);
647       MOVE_6_OBJECTS (in, out);
648       break;
649     case 23:
650       MOVE_16_OBJECTS (in, out);
651       MOVE_7_OBJECTS (in, out);
652       break;
653     case 24:
654       MOVE_16_OBJECTS (in, out);
655       MOVE_8_OBJECTS (in, out);
656       break;
657     case 25:
658       MOVE_16_OBJECTS (in, out);
659       MOVE_9_OBJECTS (in, out);
660       break;
661     case 26:
662       MOVE_16_OBJECTS (in, out);
663       MOVE_10_OBJECTS (in, out);
664       break;
665     case 27:
666       MOVE_16_OBJECTS (in, out);
667       MOVE_11_OBJECTS (in, out);
668       break;
669     case 28:
670       MOVE_16_OBJECTS (in, out);
671       MOVE_8_OBJECTS (in, out);
672       MOVE_4_OBJECTS (in, out);
673       break;
674     case 29:
675       MOVE_16_OBJECTS (in, out);
676       MOVE_9_OBJECTS (in, out);
677       MOVE_4_OBJECTS (in, out);
678       break;
679     case 30:
680       MOVE_16_OBJECTS (in, out);
681       MOVE_12_OBJECTS (in, out);
682       MOVE_2_OBJECTS (in, out);
683       break;
684     case 31:
685       MOVE_16_OBJECTS (in, out);
686       MOVE_11_OBJECTS (in, out);
687       MOVE_4_OBJECTS (in, out);
688       break;
689     }
690
691   /* This loop governs the asmptoptic behaviour of this algorithm, for long
692      word copies.  */
693   count = value >> 5;
694   for (loop_var = 0; loop_var < count; loop_var++)
695     MOVE_32_OBJECTS (in, out);
696 }
697
698
699 static inline void
700 __byte_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) 
701 {
702   int value = n;
703   int loop_var;
704   const char *in = s2;
705   char *out = s1;
706   int count;
707   int m0,m1,m2,m3;
708
709  /* This code currently give a stall for any value with a 1->2 in the low 5
710     bits, i.e.  1,2, 33,34 ? not acceptable!  */
711   switch (value & 0x1f)
712     {
713     case 0:
714       break;
715     case 1:
716       MOVE_1_OBJECT (in, out);
717       break;
718     case 2:
719       MOVE_2_OBJECTS (in, out);
720       break;
721     case 3:
722       MOVE_3_OBJECTS (in, out);
723       break;
724     case 4:
725       MOVE_4_OBJECTS (in, out);
726       break;
727     case 5:
728       MOVE_5_OBJECTS (in, out);
729       break;
730     case 6:
731       MOVE_6_OBJECTS (in, out);
732       break;
733     case 7:
734       MOVE_7_OBJECTS (in, out);
735       break;
736     case 8:
737       MOVE_8_OBJECTS (in, out);
738       break;
739     case 9:
740       MOVE_9_OBJECTS (in, out);
741       break;
742     case 10:
743       MOVE_10_OBJECTS (in, out);
744       break;
745     case 11:
746       MOVE_11_OBJECTS (in, out);
747       break;
748     case 12:
749       MOVE_12_OBJECTS (in, out);
750       break;
751     case 13:
752       MOVE_9_OBJECTS (in, out);
753       MOVE_4_OBJECTS (in, out);
754       break;
755     case 14:
756       MOVE_12_OBJECTS (in, out);
757       MOVE_2_OBJECTS (in, out);
758       break;
759     case 15:
760       MOVE_11_OBJECTS (in, out);
761       MOVE_4_OBJECTS (in, out);
762       break;
763     case 16:
764       MOVE_16_OBJECTS (in, out);
765       break;
766     case 17:
767       MOVE_11_OBJECTS (in, out);
768       MOVE_6_OBJECTS (in, out);
769       break;
770     case 18:
771       MOVE_9_OBJECTS (in, out);
772       MOVE_9_OBJECTS (in, out);
773       break;
774     case 19:
775       MOVE_16_OBJECTS (in, out);
776       MOVE_3_OBJECTS (in, out);
777       break;
778     case 20:
779       MOVE_16_OBJECTS (in, out);
780       MOVE_4_OBJECTS (in, out);
781       break;
782     case 21:
783       MOVE_16_OBJECTS (in, out);
784       MOVE_5_OBJECTS (in, out);
785       break;
786     case 22:
787       MOVE_16_OBJECTS (in, out);
788       MOVE_6_OBJECTS (in, out);
789       break;
790     case 23:
791       MOVE_16_OBJECTS (in, out);
792       MOVE_7_OBJECTS (in, out);
793       break;
794     case 24:
795       MOVE_16_OBJECTS (in, out);
796       MOVE_8_OBJECTS (in, out);
797       break;
798     case 25:
799       MOVE_16_OBJECTS (in, out);
800       MOVE_9_OBJECTS (in, out);
801       break;
802     case 26:
803       MOVE_16_OBJECTS (in, out);
804       MOVE_10_OBJECTS (in, out);
805       break;
806     case 27:
807       MOVE_16_OBJECTS (in, out);
808       MOVE_11_OBJECTS (in, out);
809       break;
810     case 28:
811       MOVE_16_OBJECTS (in, out);
812       MOVE_8_OBJECTS (in, out);
813       MOVE_4_OBJECTS (in, out);
814       break;
815     case 29:
816       MOVE_16_OBJECTS (in, out);
817       MOVE_9_OBJECTS (in, out);
818       MOVE_4_OBJECTS (in, out);
819       break;
820     case 30:
821       MOVE_16_OBJECTS (in, out);
822       MOVE_12_OBJECTS (in, out);
823       MOVE_2_OBJECTS (in, out);
824       break;
825     case 31:
826       MOVE_16_OBJECTS (in, out);
827       MOVE_11_OBJECTS (in, out);
828       MOVE_4_OBJECTS (in, out);
829       break;
830     }
831
832   /* This loop governs the asmptoptic behaviour of this algorithm, for long
833      word copies.  */
834   count = value >> 5;
835   for (loop_var = 0; loop_var < count; loop_var++)
836     MOVE_32_OBJECTS (in, out);
837 }
838
839
840 /* Exposed interface.  */
841
842 #ifndef __VISIUM_ARCH_BMI__
843
844 void
845 __long_int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n)
846 {
847   __int_memcpy (s1, s2, n);
848 }
849
850 #endif /* !__VISIUM_ARCH_BMI__ */
851
852 void
853 __wrd_memcpy (void *__restrict s1, const void *__restrict s2, size_t n)
854 {
855   __shrt_int_memcpy (s1, s2, n);
856 }
857
858 void
859 __byt_memcpy (void *__restrict s1, const void *__restrict s2, size_t n)
860 {
861   __byte_memcpy (s1, s2, n);
862 }