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