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