1/* Copyright (C) 1999-2021 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, see 16 <https://www.gnu.org/licenses/>. */ 17 18#include <sysdep.h> 19 20/* void *memcpy(void *dst, const void *src, size_t n); 21 No overlap between the memory of DST and of SRC are assumed. */ 22 23ENTRY(memcpy) 24 mov r4,r3 /* Save destination. */ 25 26 /* If less than 11 bytes, just do a byte copy. */ 27 mov #11,r0 28 cmp/gt r6,r0 29 bt L_byteloop_init 30 31 /* Check if we need to word-align source. */ 32 mov r5,r0 33 tst #1,r0 34 bt L_wordalign 35 36 mov.b @r0+,r1 /* Copy one byte. */ 37 add #-1,r6 38 mov.b r1,@r4 39 add #1,r4 40 41 .balignw 4,0x0009 42L_wordalign: 43 /* Check if we need to longword-align source. */ 44 tst #2,r0 45 bt L_copy 46 47 mov.w @r0+,r1 /* Copy one word. */ 48 add #-2,r6 49#ifdef __BIG_ENDIAN__ 50 add #1,r4 51 mov.b r1,@r4 52 shlr8 r1 53 mov.b r1,@-r4 54 add #2,r4 55#else 56 mov.b r1,@r4 57 add #1,r4 58 shlr8 r1 59 mov.b r1,@r4 60 add #1,r4 61#endif 62L_copy: 63 mov r0,r5 64 65 /* Calculate the correct routine to handle the destination 66 alignment and simultaneously calculate the loop counts for 67 both the 2 word copy loop and byte copy loop. */ 68 mova L_jumptable,r0 69 mov r0,r1 70 mov r4,r0 71 mov r6,r7 72 and #3,r0 73 shlr2 r7 74 shll r0 75 shlr r7 76 mov.w @(r0,r1),r2 77 mov #7,r0 78 braf r2 79 and r0,r6 80L_base: 81 82 .balign 4 83L_jumptable: 84 .word L_copydest0 - L_base 85 .word L_copydest1_or_3 - L_base 86 .word L_copydest2 - L_base 87 .word L_copydest1_or_3 - L_base 88 89 .balign 4 90 /* Copy routine for (dest mod 4) == 1 or == 3. */ 91L_copydest1_or_3: 92 add #-1,r4 93 .balignw 4,0x0009 94L_copydest1_or_3_loop: 95 mov.l @r5+,r0 /* Read first longword. */ 96 dt r7 97 mov.l @r5+,r1 /* Read second longword. */ 98#ifdef __BIG_ENDIAN__ 99 /* Write first longword as byte, word, byte. */ 100 mov.b r0,@(4,r4) 101 shlr8 r0 102 mov.w r0,@(2,r4) 103 shlr16 r0 104 mov.b r0,@(1,r4) 105 mov r1,r0 106 /* Write second longword as byte, word, byte. */ 107 mov.b r0,@(8,r4) 108 shlr8 r0 109 mov.w r0,@(6,r4) 110 shlr16 r0 111 mov.b r0,@(5,r4) 112#else 113 /* Write first longword as byte, word, byte. */ 114 mov.b r0,@(1,r4) 115 shlr8 r0 116 mov.w r0,@(2,r4) 117 shlr16 r0 118 mov.b r0,@(4,r4) 119 mov r1,r0 120 /* Write second longword as byte, word, byte. */ 121 mov.b r0,@(5,r4) 122 shlr8 r0 123 mov.w r0,@(6,r4) 124 shlr16 r0 125 mov.b r0,@(8,r4) 126#endif 127 bf/s L_copydest1_or_3_loop 128 add #8,r4 129 130 bra L_byteloop_init 131 add #1,r4 132 133 .balign 4 134 /* Copy routine for (dest mod 4) == 2. */ 135L_copydest2: 136L_copydest2_loop: 137 mov.l @r5+,r0 138 dt r7 139 mov.l @r5+,r1 140#ifdef __BIG_ENDIAN__ 141 mov.w r0,@(2,r4) 142 shlr16 r0 143 mov.w r0,@r4 144 mov r1,r0 145 mov.w r0,@(6,r4) 146 shlr16 r0 147 mov.w r0,@(4,r4) 148#else 149 mov.w r0,@r4 150 shlr16 r0 151 mov.w r0,@(2,r4) 152 mov r1,r0 153 mov.w r0,@(4,r4) 154 shlr16 r0 155 mov.w r0,@(6,r4) 156#endif 157 bf/s L_copydest2_loop 158 add #8,r4 159 160 bra L_byteloop_init 161 nop 162 163 .balign 4 164 /* Copy routine for (dest mod 4) == 0. */ 165L_copydest0: 166 add #-8,r4 167 .balignw 4,0x0009 168L_copydest0_loop: 169 mov.l @r5+,r0 170 dt r7 171 mov.l @r5+,r1 172 add #8,r4 173 mov.l r0,@r4 174 bf/s L_copydest0_loop 175 mov.l r1,@(4,r4) 176 177 add #8,r4 /* Fall through. */ 178 179L_byteloop_init: 180 tst r6,r6 181 bt L_exit 182 183 .balignw 4,0x0009 184 /* Copy remaining bytes. */ 185L_byteloop: 186 mov.b @r5+,r0 187 dt r6 188 mov.b r0,@r4 189 bf/s L_byteloop 190 add #1,r4 191 192L_exit: 193 rts 194 mov r3,r0 /* Return destination. */ 195END(memcpy) 196libc_hidden_builtin_def (memcpy) 197