| /* 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); |
| } |