1! Copyright (C) 2013 Imagination Technologies Ltd. 2 3! Licensed under LGPL v2.1 or later, see the file COPYING.LIB in this tarball. 4 5 6 .text 7 .global _memmove 8 .type _memmove,function 9! D1Ar1 dst 10! D0Ar2 src 11! D1Ar3 cnt 12! D0Re0 dst 13_memmove: 14 CMP D1Ar3, #0 15 MOV D0Re0, D1Ar1 16 BZ $LEND2 17 MSETL [A0StP], D0.5, D0.6, D0.7 18 MOV D1Ar5, D0Ar2 19 CMP D1Ar1, D1Ar5 20 BLT $Lforwards_copy 21 SUB D0Ar4, D1Ar1, D1Ar3 22 ADD D0Ar4, D0Ar4, #1 23 CMP D0Ar2, D0Ar4 24 BLT $Lforwards_copy 25 ! should copy backwards 26 MOV D1Re0, D0Ar2 27 ! adjust pointer to the end of mem 28 ADD D0Ar2, D1Re0, D1Ar3 29 ADD D1Ar1, D1Ar1, D1Ar3 30 31 MOV A1.2, D0Ar2 32 MOV A0.2, D1Ar1 33 CMP D1Ar3, #8 34 BLT $Lbbyte_loop 35 36 MOV D0Ar4, D0Ar2 37 MOV D1Ar5, D1Ar1 38 39 ! test 8 byte alignment 40 ANDS D1Ar5, D1Ar5, #7 41 BNE $Lbdest_unaligned 42 43 ANDS D0Ar4, D0Ar4, #7 44 BNE $Lbsrc_unaligned 45 46 LSR D1Ar5, D1Ar3, #3 47 48$Lbaligned_loop: 49 GETL D0Re0, D1Re0, [--A1.2] 50 SETL [--A0.2], D0Re0, D1Re0 51 SUBS D1Ar5, D1Ar5, #1 52 BNE $Lbaligned_loop 53 54 ANDS D1Ar3, D1Ar3, #7 55 BZ $Lbbyte_loop_exit 56$Lbbyte_loop: 57 GETB D1Re0, [--A1.2] 58 SETB [--A0.2], D1Re0 59 SUBS D1Ar3, D1Ar3, #1 60 BNE $Lbbyte_loop 61$Lbbyte_loop_exit: 62 MOV D0Re0, A0.2 63$LEND: 64 SUB A0.2, A0StP, #24 65 MGETL D0.5, D0.6, D0.7, [A0.2] 66 SUB A0StP, A0StP, #24 67$LEND2: 68 MOV PC, D1RtP 69 70$Lbdest_unaligned: 71 GETB D0Re0, [--A1.2] 72 SETB [--A0.2], D0Re0 73 SUBS D1Ar5, D1Ar5, #1 74 SUB D1Ar3, D1Ar3, #1 75 BNE $Lbdest_unaligned 76 CMP D1Ar3, #8 77 BLT $Lbbyte_loop 78$Lbsrc_unaligned: 79 LSR D1Ar5, D1Ar3, #3 80 ! adjust A1.2 81 MOV D0Ar4, A1.2 82 ! save original address 83 MOV D0Ar6, A1.2 84 85 ADD D0Ar4, D0Ar4, #7 86 ANDMB D0Ar4, D0Ar4, #0xfff8 87 ! new address is the 8-byte aligned one above the original 88 MOV A1.2, D0Ar4 89 90 ! A0.2 dst 64-bit is aligned 91 ! measure the gap size 92 SUB D0Ar6, D0Ar4, D0Ar6 93 MOVS D0Ar4, D0Ar6 94 ! keep this information for the later adjustment 95 ! both aligned 96 BZ $Lbaligned_loop 97 98 ! prefetch 99 GETL D0Re0, D1Re0, [--A1.2] 100 101 CMP D0Ar6, #4 102 BLT $Lbunaligned_1_2_3 103 ! 32-bit aligned 104 BZ $Lbaligned_4 105 106 SUB D0Ar6, D0Ar6, #4 107 ! D1.6 stores the gap size in bits 108 MULW D1.6, D0Ar6, #8 109 MOV D0.6, #32 110 ! D0.6 stores the complement of the gap size 111 SUB D0.6, D0.6, D1.6 112 113$Lbunaligned_5_6_7: 114 GETL D0.7, D1.7, [--A1.2] 115 ! form 64-bit data in D0Re0, D1Re0 116 MOV D1Re0, D0Re0 117 ! D1Re0 << gap-size 118 LSL D1Re0, D1Re0, D1.6 119 MOV D0Re0, D1.7 120 ! D0Re0 >> complement 121 LSR D0Re0, D0Re0, D0.6 122 MOV D1.5, D0Re0 123 ! combine the both 124 ADD D1Re0, D1Re0, D1.5 125 126 MOV D1.5, D1.7 127 LSL D1.5, D1.5, D1.6 128 MOV D0Re0, D0.7 129 LSR D0Re0, D0Re0, D0.6 130 MOV D0.5, D1.5 131 ADD D0Re0, D0Re0, D0.5 132 133 SETL [--A0.2], D0Re0, D1Re0 134 MOV D0Re0, D0.7 135 MOV D1Re0, D1.7 136 SUBS D1Ar5, D1Ar5, #1 137 BNE $Lbunaligned_5_6_7 138 139 ANDS D1Ar3, D1Ar3, #7 140 BZ $Lbbyte_loop_exit 141 ! Adjust A1.2 142 ! A1.2 <- A1.2 +8 - gapsize 143 ADD A1.2, A1.2, #8 144 SUB A1.2, A1.2, D0Ar4 145 B $Lbbyte_loop 146 147$Lbunaligned_1_2_3: 148 MULW D1.6, D0Ar6, #8 149 MOV D0.6, #32 150 SUB D0.6, D0.6, D1.6 151 152$Lbunaligned_1_2_3_loop: 153 GETL D0.7, D1.7, [--A1.2] 154 ! form 64-bit data in D0Re0, D1Re0 155 LSL D1Re0, D1Re0, D1.6 156 ! save D0Re0 for later use 157 MOV D0.5, D0Re0 158 LSR D0Re0, D0Re0, D0.6 159 MOV D1.5, D0Re0 160 ADD D1Re0, D1Re0, D1.5 161 162 ! orignal data in D0Re0 163 MOV D1.5, D0.5 164 LSL D1.5, D1.5, D1.6 165 MOV D0Re0, D1.7 166 LSR D0Re0, D0Re0, D0.6 167 MOV D0.5, D1.5 168 ADD D0Re0, D0Re0, D0.5 169 170 SETL [--A0.2], D0Re0, D1Re0 171 MOV D0Re0, D0.7 172 MOV D1Re0, D1.7 173 SUBS D1Ar5, D1Ar5, #1 174 BNE $Lbunaligned_1_2_3_loop 175 176 ANDS D1Ar3, D1Ar3, #7 177 BZ $Lbbyte_loop_exit 178 ! Adjust A1.2 179 ADD A1.2, A1.2, #8 180 SUB A1.2, A1.2, D0Ar4 181 B $Lbbyte_loop 182 183$Lbaligned_4: 184 GETL D0.7, D1.7, [--A1.2] 185 MOV D1Re0, D0Re0 186 MOV D0Re0, D1.7 187 SETL [--A0.2], D0Re0, D1Re0 188 MOV D0Re0, D0.7 189 MOV D1Re0, D1.7 190 SUBS D1Ar5, D1Ar5, #1 191 BNE $Lbaligned_4 192 ANDS D1Ar3, D1Ar3, #7 193 BZ $Lbbyte_loop_exit 194 ! Adjust A1.2 195 ADD A1.2, A1.2, #8 196 SUB A1.2, A1.2, D0Ar4 197 B $Lbbyte_loop 198 199$Lforwards_copy: 200 MOV A1.2, D0Ar2 201 MOV A0.2, D1Ar1 202 CMP D1Ar3, #8 203 BLT $Lfbyte_loop 204 205 MOV D0Ar4, D0Ar2 206 MOV D1Ar5, D1Ar1 207 208 ANDS D1Ar5, D1Ar5, #7 209 BNE $Lfdest_unaligned 210 211 ANDS D0Ar4, D0Ar4, #7 212 BNE $Lfsrc_unaligned 213 214 LSR D1Ar5, D1Ar3, #3 215 216$Lfaligned_loop: 217 GETL D0Re0, D1Re0, [A1.2++] 218 SUBS D1Ar5, D1Ar5, #1 219 SETL [A0.2++], D0Re0, D1Re0 220 BNE $Lfaligned_loop 221 222 ANDS D1Ar3, D1Ar3, #7 223 BZ $Lfbyte_loop_exit 224$Lfbyte_loop: 225 GETB D1Re0, [A1.2++] 226 SETB [A0.2++], D1Re0 227 SUBS D1Ar3, D1Ar3, #1 228 BNE $Lfbyte_loop 229$Lfbyte_loop_exit: 230 MOV D0Re0, D1Ar1 231 B $LEND 232 233$Lfdest_unaligned: 234 GETB D0Re0, [A1.2++] 235 ADD D1Ar5, D1Ar5, #1 236 SUB D1Ar3, D1Ar3, #1 237 SETB [A0.2++], D0Re0 238 CMP D1Ar5, #8 239 BNE $Lfdest_unaligned 240 CMP D1Ar3, #8 241 BLT $Lfbyte_loop 242$Lfsrc_unaligned: 243 ! adjust A1.2 244 LSR D1Ar5, D1Ar3, #3 245 246 MOV D0Ar4, A1.2 247 MOV D0Ar6, A1.2 248 ANDMB D0Ar4, D0Ar4, #0xfff8 249 MOV A1.2, D0Ar4 250 251 ! A0.2 dst 64-bit is aligned 252 SUB D0Ar6, D0Ar6, D0Ar4 253 ! keep the information for the later adjustment 254 MOVS D0Ar4, D0Ar6 255 256 ! both aligned 257 BZ $Lfaligned_loop 258 259 ! prefetch 260 GETL D0Re0, D1Re0, [A1.2] 261 262 CMP D0Ar6, #4 263 BLT $Lfunaligned_1_2_3 264 BZ $Lfaligned_4 265 266 SUB D0Ar6, D0Ar6, #4 267 MULW D0.6, D0Ar6, #8 268 MOV D1.6, #32 269 SUB D1.6, D1.6, D0.6 270 271$Lfunaligned_5_6_7: 272 GETL D0.7, D1.7, [++A1.2] 273 ! form 64-bit data in D0Re0, D1Re0 274 MOV D0Re0, D1Re0 275 LSR D0Re0, D0Re0, D0.6 276 MOV D1Re0, D0.7 277 LSL D1Re0, D1Re0, D1.6 278 MOV D0.5, D1Re0 279 ADD D0Re0, D0Re0, D0.5 280 281 MOV D0.5, D0.7 282 LSR D0.5, D0.5, D0.6 283 MOV D1Re0, D1.7 284 LSL D1Re0, D1Re0, D1.6 285 MOV D1.5, D0.5 286 ADD D1Re0, D1Re0, D1.5 287 288 SETL [A0.2++], D0Re0, D1Re0 289 MOV D0Re0, D0.7 290 MOV D1Re0, D1.7 291 SUBS D1Ar5, D1Ar5, #1 292 BNE $Lfunaligned_5_6_7 293 294 ANDS D1Ar3, D1Ar3, #7 295 BZ $Lfbyte_loop_exit 296 ! Adjust A1.2 297 ADD A1.2, A1.2, D0Ar4 298 B $Lfbyte_loop 299 300$Lfunaligned_1_2_3: 301 MULW D0.6, D0Ar6, #8 302 MOV D1.6, #32 303 SUB D1.6, D1.6, D0.6 304 305$Lfunaligned_1_2_3_loop: 306 GETL D0.7, D1.7, [++A1.2] 307 ! form 64-bit data in D0Re0, D1Re0 308 LSR D0Re0, D0Re0, D0.6 309 MOV D1.5, D1Re0 310 LSL D1Re0, D1Re0, D1.6 311 MOV D0.5, D1Re0 312 ADD D0Re0, D0Re0, D0.5 313 314 MOV D0.5, D1.5 315 LSR D0.5, D0.5, D0.6 316 MOV D1Re0, D0.7 317 LSL D1Re0, D1Re0, D1.6 318 MOV D1.5, D0.5 319 ADD D1Re0, D1Re0, D1.5 320 321 SETL [A0.2++], D0Re0, D1Re0 322 MOV D0Re0, D0.7 323 MOV D1Re0, D1.7 324 SUBS D1Ar5, D1Ar5, #1 325 BNE $Lfunaligned_1_2_3_loop 326 327 ANDS D1Ar3, D1Ar3, #7 328 BZ $Lfbyte_loop_exit 329 ! Adjust A1.2 330 ADD A1.2, A1.2, D0Ar4 331 B $Lfbyte_loop 332 333$Lfaligned_4: 334 GETL D0.7, D1.7, [++A1.2] 335 MOV D0Re0, D1Re0 336 MOV D1Re0, D0.7 337 SETL [A0.2++], D0Re0, D1Re0 338 MOV D0Re0, D0.7 339 MOV D1Re0, D1.7 340 SUBS D1Ar5, D1Ar5, #1 341 BNE $Lfaligned_4 342 ANDS D1Ar3, D1Ar3, #7 343 BZ $Lfbyte_loop_exit 344 ! Adjust A1.2 345 ADD A1.2, A1.2, D0Ar4 346 B $Lfbyte_loop 347 348 .size _memmove,.-_memmove 349 350libc_hidden_def(memmove) 351