1/* Copyright (C) 2012-2020 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)	\
32do {				\
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)	\
111do {				\
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)	\
154do {				\
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)	\
188do {				\
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)	\
220do {				\
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)	\
249do {				\
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)	\
276do {				\
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)	\
301do {				\
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)	\
324do {				\
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)	\
346do {				\
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)	\
366do {				\
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)	\
382do {				\
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)	\
396do {				\
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)	\
408do {				\
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
418static 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
558static 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
699static 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
844void
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
852void
853__wrd_memcpy (void *__restrict s1, const void *__restrict s2, size_t n)
854{
855  __shrt_int_memcpy (s1, s2, n);
856}
857
858void
859__byt_memcpy (void *__restrict s1, const void *__restrict s2, size_t n)
860{
861  __byte_memcpy (s1, s2, n);
862}
863