|  | /* Copyright (C) 2012-2021 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GCC. | 
|  |  | 
|  | GCC is free software; you can redistribute it and/or modify it | 
|  | under the terms of the GNU General Public License as published by | 
|  | the Free Software Foundation; either version 3, or (at your option) | 
|  | any later version. | 
|  |  | 
|  | GCC is distributed in the hope that it will be useful, but WITHOUT | 
|  | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | 
|  | or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public | 
|  | License for more details. | 
|  |  | 
|  | Under Section 7 of GPL version 3, you are granted additional | 
|  | permissions described in the GCC Runtime Library Exception, version | 
|  | 3.1, as published by the Free Software Foundation. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License and | 
|  | a copy of the GCC Runtime Library Exception along with this program; | 
|  | see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see | 
|  | <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | /* This file must be kept in sync with newlib/libc/machine/visium/memcpy.c  */ | 
|  |  | 
|  | #include <stddef.h> | 
|  | #include "memcpy.h" | 
|  |  | 
|  | #define INST_BARRIER   __asm__ __volatile__ ("":::"memory"); | 
|  |  | 
|  | #define MOVE_32_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [8];			\ | 
|  | m1 = in [9];			\ | 
|  | m2 = in [10];			\ | 
|  | m3 = in [11];			\ | 
|  | out [8] = m0;			\ | 
|  | out [9] = m1;			\ | 
|  | out [10] = m2;		\ | 
|  | out [11] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [12];			\ | 
|  | m1 = in [13];			\ | 
|  | m2 = in [14];			\ | 
|  | m3 = in [15];			\ | 
|  | out [12] = m0;		\ | 
|  | out [13] = m1;		\ | 
|  | out [14] = m2;		\ | 
|  | out [15] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [16];			\ | 
|  | m1 = in [17];			\ | 
|  | m2 = in [18];			\ | 
|  | m3 = in [19];			\ | 
|  | out [16] = m0;		\ | 
|  | out [17] = m1;		\ | 
|  | out [18] = m2;		\ | 
|  | out [19] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [20];			\ | 
|  | m1 = in [21];			\ | 
|  | m2 = in [22];			\ | 
|  | m3 = in [23];			\ | 
|  | out [20] = m0;		\ | 
|  | out [21] = m1;		\ | 
|  | out [22] = m2;		\ | 
|  | out [23] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [24];			\ | 
|  | m1 = in [25];			\ | 
|  | m2 = in [26];			\ | 
|  | m3 = in [27];			\ | 
|  | out [24] = m0;		\ | 
|  | out [25] = m1;		\ | 
|  | out [26] = m2;		\ | 
|  | out [27] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | m0 =	in [28];		\ | 
|  | m1 = in [29];			\ | 
|  | m2 = in [30];			\ | 
|  | m3 = in [31];			\ | 
|  | out [28] = m0;		\ | 
|  | out [29] = m1;		\ | 
|  | out [30] = m2;		\ | 
|  | out [31] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | in += 32;			\ | 
|  | out += 32;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_16_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [8];			\ | 
|  | m1 = in [9];			\ | 
|  | m2 = in [10];			\ | 
|  | m3 = in [11];			\ | 
|  | out [8] = m0;			\ | 
|  | out [9] = m1;			\ | 
|  | out [10] = m2;		\ | 
|  | out [11] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [12];			\ | 
|  | m1 = in [13];			\ | 
|  | m2 = in [14];			\ | 
|  | m3 = in [15];			\ | 
|  | out [12] = m0;		\ | 
|  | out [13] = m1;		\ | 
|  | out [14] = m2;		\ | 
|  | out [15] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | in += 16;			\ | 
|  | out += 16;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_12_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [8];			\ | 
|  | m1 = in [9];			\ | 
|  | m2 = in [10];			\ | 
|  | m3 = in [11];			\ | 
|  | out [8] = m0;			\ | 
|  | out [9] = m1;			\ | 
|  | out [10] = m2;		\ | 
|  | out [11] = m3;		\ | 
|  | INST_BARRIER			\ | 
|  | in += 12;			\ | 
|  | out += 12;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_11_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [8];			\ | 
|  | m1 = in [9];			\ | 
|  | m2 = in [10];			\ | 
|  | out [8] = m0;			\ | 
|  | out [9] = m1;			\ | 
|  | out [10] = m2;		\ | 
|  | INST_BARRIER			\ | 
|  | in += 11;			\ | 
|  | out += 11;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_10_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | m0 = in [8];			\ | 
|  | out [5] = m1;			\ | 
|  | m1 = in [9];			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | out [8] = m0;			\ | 
|  | out [9] = m1;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 10;			\ | 
|  | out += 10;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_9_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [8];			\ | 
|  | out [8] = m0;			\ | 
|  | in += 9;			\ | 
|  | out += 9;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_8_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | m3 = in [7];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | out [7] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 8;			\ | 
|  | out += 8;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_7_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | m1 = in [5];			\ | 
|  | m2 = in [6];			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | out [6] = m2;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 7;			\ | 
|  | out += 7;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_6_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [4];			\ | 
|  | out [1] = m1;			\ | 
|  | INST_BARRIER			\ | 
|  | m1 = in [5];			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | out [4] = m0;			\ | 
|  | out [5] = m1;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 6;			\ | 
|  | out += 6;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_5_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | INST_BARRIER			\ | 
|  | out [0] = m0;			\ | 
|  | m0 = in [4];			\ | 
|  | INST_BARRIER			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | out [4] = m0;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 5;			\ | 
|  | out += 5;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_4_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | m3 = in [3];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | out [3] = m3;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 4;			\ | 
|  | out += 4;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_3_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | m2 = in [2];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | out [2] = m2;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 3;			\ | 
|  | out += 3;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_2_OBJECTS(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | m1 = in [1];			\ | 
|  | out [0] = m0;			\ | 
|  | out [1] = m1;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 2;			\ | 
|  | out += 2;			\ | 
|  | } while(0) | 
|  |  | 
|  | #define MOVE_1_OBJECT(in,out)	\ | 
|  | do {				\ | 
|  | INST_BARRIER			\ | 
|  | m0 = in [0];			\ | 
|  | out [0] = m0;			\ | 
|  | INST_BARRIER			\ | 
|  | in += 1;			\ | 
|  | out += 1;			\ | 
|  | } while(0) | 
|  |  | 
|  |  | 
|  | static inline void | 
|  | __int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) | 
|  | { | 
|  | int value = n; | 
|  | int loop_var; | 
|  | const int *in = s2; | 
|  | int *out = s1; | 
|  | int count; | 
|  | int m0,m1,m2,m3; | 
|  |  | 
|  | /* This code currently give a stall for any value with a 1->2 in the low 5 | 
|  | bits, i.e.  1,2, 33,34 ? not acceptable!  */ | 
|  | switch (value & 0x1f) | 
|  | { | 
|  | case 0: | 
|  | break; | 
|  | case 1: | 
|  | MOVE_1_OBJECT (in, out); | 
|  | break; | 
|  | case 2: | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 3: | 
|  | MOVE_3_OBJECTS (in, out); | 
|  | break; | 
|  | case 4: | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 5: | 
|  | MOVE_5_OBJECTS (in, out); | 
|  | break; | 
|  | case 6: | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 7: | 
|  | MOVE_7_OBJECTS (in, out); | 
|  | break; | 
|  | case 8: | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | break; | 
|  | case 9: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 10: | 
|  | MOVE_10_OBJECTS (in, out); | 
|  | break; | 
|  | case 11: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | break; | 
|  | case 12: | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | break; | 
|  | case 13: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 14: | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 15: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 16: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | break; | 
|  | case 17: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 18: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 19: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_3_OBJECTS (in, out); | 
|  | break; | 
|  | case 20: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 21: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_5_OBJECTS (in, out); | 
|  | break; | 
|  | case 22: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 23: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_7_OBJECTS (in, out); | 
|  | break; | 
|  | case 24: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | break; | 
|  | case 25: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 26: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_10_OBJECTS (in, out); | 
|  | break; | 
|  | case 27: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | break; | 
|  | case 28: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 29: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 30: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 31: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* This loop governs the asmptoptic behaviour of this algorithm, for long | 
|  | word copies.  */ | 
|  | count = value >> 5; | 
|  | for (loop_var = 0; loop_var < count; loop_var++) | 
|  | MOVE_32_OBJECTS (in, out); | 
|  | } | 
|  |  | 
|  | static inline void | 
|  | __shrt_int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) | 
|  | { | 
|  | int value = n; | 
|  | int loop_var; | 
|  | const short int *in = s2; | 
|  | int short *out = s1; | 
|  | int count; | 
|  | int m0,m1,m2,m3; | 
|  |  | 
|  | /* This code currently give a stall for any value with a 1->2 in the low 5 | 
|  | bits, i.e.  1,2, 33,34 ? not acceptable!  */ | 
|  | switch (value & 0x1f) | 
|  | { | 
|  | case 0: | 
|  | break; | 
|  | case 1: | 
|  | MOVE_1_OBJECT (in, out); | 
|  | break; | 
|  | case 2: | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 3: | 
|  | MOVE_3_OBJECTS (in, out); | 
|  | break; | 
|  | case 4: | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 5: | 
|  | MOVE_5_OBJECTS (in, out); | 
|  | break; | 
|  | case 6: | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 7: | 
|  | MOVE_7_OBJECTS (in, out); | 
|  | break; | 
|  | case 8: | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | break; | 
|  | case 9: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 10: | 
|  | MOVE_10_OBJECTS (in, out); | 
|  | break; | 
|  | case 11: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | break; | 
|  | case 12: | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | break; | 
|  | case 13: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 14: | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 15: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 16: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | break; | 
|  | case 17: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 18: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 19: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_3_OBJECTS (in, out); | 
|  | break; | 
|  | case 20: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 21: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_5_OBJECTS (in, out); | 
|  | break; | 
|  | case 22: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 23: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_7_OBJECTS (in, out); | 
|  | break; | 
|  | case 24: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | break; | 
|  | case 25: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 26: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_10_OBJECTS (in, out); | 
|  | break; | 
|  | case 27: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | break; | 
|  | case 28: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 29: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 30: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 31: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* This loop governs the asmptoptic behaviour of this algorithm, for long | 
|  | word copies.  */ | 
|  | count = value >> 5; | 
|  | for (loop_var = 0; loop_var < count; loop_var++) | 
|  | MOVE_32_OBJECTS (in, out); | 
|  | } | 
|  |  | 
|  |  | 
|  | static inline void | 
|  | __byte_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) | 
|  | { | 
|  | int value = n; | 
|  | int loop_var; | 
|  | const char *in = s2; | 
|  | char *out = s1; | 
|  | int count; | 
|  | int m0,m1,m2,m3; | 
|  |  | 
|  | /* This code currently give a stall for any value with a 1->2 in the low 5 | 
|  | bits, i.e.  1,2, 33,34 ? not acceptable!  */ | 
|  | switch (value & 0x1f) | 
|  | { | 
|  | case 0: | 
|  | break; | 
|  | case 1: | 
|  | MOVE_1_OBJECT (in, out); | 
|  | break; | 
|  | case 2: | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 3: | 
|  | MOVE_3_OBJECTS (in, out); | 
|  | break; | 
|  | case 4: | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 5: | 
|  | MOVE_5_OBJECTS (in, out); | 
|  | break; | 
|  | case 6: | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 7: | 
|  | MOVE_7_OBJECTS (in, out); | 
|  | break; | 
|  | case 8: | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | break; | 
|  | case 9: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 10: | 
|  | MOVE_10_OBJECTS (in, out); | 
|  | break; | 
|  | case 11: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | break; | 
|  | case 12: | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | break; | 
|  | case 13: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 14: | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 15: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 16: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | break; | 
|  | case 17: | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 18: | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 19: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_3_OBJECTS (in, out); | 
|  | break; | 
|  | case 20: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 21: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_5_OBJECTS (in, out); | 
|  | break; | 
|  | case 22: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_6_OBJECTS (in, out); | 
|  | break; | 
|  | case 23: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_7_OBJECTS (in, out); | 
|  | break; | 
|  | case 24: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | break; | 
|  | case 25: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | break; | 
|  | case 26: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_10_OBJECTS (in, out); | 
|  | break; | 
|  | case 27: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | break; | 
|  | case 28: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_8_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 29: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_9_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | case 30: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_12_OBJECTS (in, out); | 
|  | MOVE_2_OBJECTS (in, out); | 
|  | break; | 
|  | case 31: | 
|  | MOVE_16_OBJECTS (in, out); | 
|  | MOVE_11_OBJECTS (in, out); | 
|  | MOVE_4_OBJECTS (in, out); | 
|  | break; | 
|  | } | 
|  |  | 
|  | /* This loop governs the asmptoptic behaviour of this algorithm, for long | 
|  | word copies.  */ | 
|  | count = value >> 5; | 
|  | for (loop_var = 0; loop_var < count; loop_var++) | 
|  | MOVE_32_OBJECTS (in, out); | 
|  | } | 
|  |  | 
|  |  | 
|  | /* Exposed interface.  */ | 
|  |  | 
|  | #ifndef __VISIUM_ARCH_BMI__ | 
|  |  | 
|  | void | 
|  | __long_int_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) | 
|  | { | 
|  | __int_memcpy (s1, s2, n); | 
|  | } | 
|  |  | 
|  | #endif /* !__VISIUM_ARCH_BMI__ */ | 
|  |  | 
|  | void | 
|  | __wrd_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) | 
|  | { | 
|  | __shrt_int_memcpy (s1, s2, n); | 
|  | } | 
|  |  | 
|  | void | 
|  | __byt_memcpy (void *__restrict s1, const void *__restrict s2, size_t n) | 
|  | { | 
|  | __byte_memcpy (s1, s2, n); | 
|  | } |