1129202Scognet/* $NetBSD: memmove.S,v 1.4 2003/10/14 07:51:45 scw Exp $ */ 2129202Scognet 3129202Scognet/*- 4129202Scognet * Copyright (c) 1997 The NetBSD Foundation, Inc. 5129202Scognet * All rights reserved. 6129202Scognet * 7129202Scognet * This code is derived from software contributed to The NetBSD Foundation 8129202Scognet * by Neil A. Carson and Mark Brinicombe 9129202Scognet * 10129202Scognet * Redistribution and use in source and binary forms, with or without 11129202Scognet * modification, are permitted provided that the following conditions 12129202Scognet * are met: 13129202Scognet * 1. Redistributions of source code must retain the above copyright 14129202Scognet * notice, this list of conditions and the following disclaimer. 15129202Scognet * 2. Redistributions in binary form must reproduce the above copyright 16129202Scognet * notice, this list of conditions and the following disclaimer in the 17129202Scognet * documentation and/or other materials provided with the distribution. 18129202Scognet * 19129202Scognet * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20129202Scognet * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21129202Scognet * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22129202Scognet * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23129202Scognet * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24129202Scognet * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25129202Scognet * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26129202Scognet * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27129202Scognet * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28129202Scognet * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29129202Scognet * POSSIBILITY OF SUCH DAMAGE. 30129202Scognet */ 31129202Scognet 32129202Scognet#include <machine/asm.h> 33129202Scognet__FBSDID("$FreeBSD$"); 34129202Scognet 35275256Sandrew.syntax unified 36275256Sandrew 37129202Scognet#ifndef _BCOPY 38129202Scognet/* LINTSTUB: Func: void *memmove(void *, const void *, size_t) */ 39129202ScognetENTRY(memmove) 40129202Scognet#else 41129202Scognet/* bcopy = memcpy/memmove with arguments reversed. */ 42129202Scognet/* LINTSTUB: Func: void bcopy(void *, void *, size_t) */ 43129202ScognetENTRY(bcopy) 44129202Scognet /* switch the source and destination registers */ 45129202Scognet eor r0, r1, r0 46129202Scognet eor r1, r0, r1 47129202Scognet eor r0, r1, r0 48129202Scognet#endif 49129202Scognet /* Do the buffers overlap? */ 50129202Scognet cmp r0, r1 51283831Sandrew it eq 52137464Scognet RETeq /* Bail now if src/dst are the same */ 53283831Sandrew ite cc 54129202Scognet subcc r3, r0, r1 /* if (dst > src) r3 = dst - src */ 55129202Scognet subcs r3, r1, r0 /* if (src > dsr) r3 = src - dst */ 56129202Scognet cmp r3, r2 /* if (r3 < len) we have an overlap */ 57129202Scognet bcc PIC_SYM(_C_LABEL(memcpy), PLT) 58129202Scognet 59129202Scognet /* Determine copy direction */ 60129202Scognet cmp r1, r0 61283831Sandrew it cc 62129202Scognet bcc .Lmemmove_backwards 63129202Scognet 64283831Sandrew itt eq 65129202Scognet moveq r0, #0 /* Quick abort for len=0 */ 66137464Scognet RETeq 67129202Scognet 68129202Scognet stmdb sp!, {r0, lr} /* memmove() returns dest addr */ 69129202Scognet subs r2, r2, #4 70129202Scognet blt .Lmemmove_fl4 /* less than 4 bytes */ 71129202Scognet ands r12, r0, #3 72129202Scognet bne .Lmemmove_fdestul /* oh unaligned destination addr */ 73129202Scognet ands r12, r1, #3 74129202Scognet bne .Lmemmove_fsrcul /* oh unaligned source addr */ 75129202Scognet 76129202Scognet.Lmemmove_ft8: 77129202Scognet /* We have aligned source and destination */ 78129202Scognet subs r2, r2, #8 79129202Scognet blt .Lmemmove_fl12 /* less than 12 bytes (4 from above) */ 80129202Scognet subs r2, r2, #0x14 81129202Scognet blt .Lmemmove_fl32 /* less than 32 bytes (12 from above) */ 82129202Scognet stmdb sp!, {r4} /* borrow r4 */ 83129202Scognet 84129202Scognet /* blat 32 bytes at a time */ 85129202Scognet /* XXX for really big copies perhaps we should use more registers */ 86129202Scognet.Lmemmove_floop32: 87129202Scognet ldmia r1!, {r3, r4, r12, lr} 88129202Scognet stmia r0!, {r3, r4, r12, lr} 89129202Scognet ldmia r1!, {r3, r4, r12, lr} 90129202Scognet stmia r0!, {r3, r4, r12, lr} 91129202Scognet subs r2, r2, #0x20 92129202Scognet bge .Lmemmove_floop32 93129202Scognet 94129202Scognet cmn r2, #0x10 95283831Sandrew ittt ge 96275256Sandrew ldmiage r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ 97275256Sandrew stmiage r0!, {r3, r4, r12, lr} 98129202Scognet subge r2, r2, #0x10 99129202Scognet ldmia sp!, {r4} /* return r4 */ 100129202Scognet 101129202Scognet.Lmemmove_fl32: 102129202Scognet adds r2, r2, #0x14 103129202Scognet 104129202Scognet /* blat 12 bytes at a time */ 105129202Scognet.Lmemmove_floop12: 106283831Sandrew ittt ge 107275256Sandrew ldmiage r1!, {r3, r12, lr} 108275256Sandrew stmiage r0!, {r3, r12, lr} 109275256Sandrew subsge r2, r2, #0x0c 110129202Scognet bge .Lmemmove_floop12 111129202Scognet 112129202Scognet.Lmemmove_fl12: 113129202Scognet adds r2, r2, #8 114129202Scognet blt .Lmemmove_fl4 115129202Scognet 116129202Scognet subs r2, r2, #4 117283831Sandrew itt lt 118129202Scognet ldrlt r3, [r1], #4 119129202Scognet strlt r3, [r0], #4 120283831Sandrew ittt ge 121275256Sandrew ldmiage r1!, {r3, r12} 122275256Sandrew stmiage r0!, {r3, r12} 123129202Scognet subge r2, r2, #4 124129202Scognet 125129202Scognet.Lmemmove_fl4: 126129202Scognet /* less than 4 bytes to go */ 127129202Scognet adds r2, r2, #4 128283831Sandrew it eq 129275256Sandrew ldmiaeq sp!, {r0, pc} /* done */ 130129202Scognet 131129202Scognet /* copy the crud byte at a time */ 132129202Scognet cmp r2, #2 133129202Scognet ldrb r3, [r1], #1 134129202Scognet strb r3, [r0], #1 135283831Sandrew itt ge 136275256Sandrew ldrbge r3, [r1], #1 137275256Sandrew strbge r3, [r0], #1 138283831Sandrew itt gt 139275256Sandrew ldrbgt r3, [r1], #1 140275256Sandrew strbgt r3, [r0], #1 141129202Scognet ldmia sp!, {r0, pc} 142129202Scognet 143129202Scognet /* erg - unaligned destination */ 144129202Scognet.Lmemmove_fdestul: 145129202Scognet rsb r12, r12, #4 146129202Scognet cmp r12, #2 147129202Scognet 148129202Scognet /* align destination with byte copies */ 149129202Scognet ldrb r3, [r1], #1 150129202Scognet strb r3, [r0], #1 151283831Sandrew itt ge 152275256Sandrew ldrbge r3, [r1], #1 153275256Sandrew strbge r3, [r0], #1 154283831Sandrew itt gt 155275256Sandrew ldrbgt r3, [r1], #1 156275256Sandrew strbgt r3, [r0], #1 157129202Scognet subs r2, r2, r12 158129202Scognet blt .Lmemmove_fl4 /* less the 4 bytes */ 159129202Scognet 160129202Scognet ands r12, r1, #3 161129202Scognet beq .Lmemmove_ft8 /* we have an aligned source */ 162129202Scognet 163129202Scognet /* erg - unaligned source */ 164129202Scognet /* This is where it gets nasty ... */ 165129202Scognet.Lmemmove_fsrcul: 166129202Scognet bic r1, r1, #3 167129202Scognet ldr lr, [r1], #4 168129202Scognet cmp r12, #2 169129202Scognet bgt .Lmemmove_fsrcul3 170129202Scognet beq .Lmemmove_fsrcul2 171129202Scognet cmp r2, #0x0c 172129202Scognet blt .Lmemmove_fsrcul1loop4 173129202Scognet sub r2, r2, #0x0c 174129202Scognet stmdb sp!, {r4, r5} 175129202Scognet 176129202Scognet.Lmemmove_fsrcul1loop16: 177129202Scognet#ifdef __ARMEB__ 178129202Scognet mov r3, lr, lsl #8 179129202Scognet#else 180129202Scognet mov r3, lr, lsr #8 181129202Scognet#endif 182129202Scognet ldmia r1!, {r4, r5, r12, lr} 183129202Scognet#ifdef __ARMEB__ 184129202Scognet orr r3, r3, r4, lsr #24 185129202Scognet mov r4, r4, lsl #8 186129202Scognet orr r4, r4, r5, lsr #24 187129202Scognet mov r5, r5, lsl #8 188129202Scognet orr r5, r5, r12, lsr #24 189129202Scognet mov r12, r12, lsl #8 190129202Scognet orr r12, r12, lr, lsr #24 191129202Scognet#else 192129202Scognet orr r3, r3, r4, lsl #24 193129202Scognet mov r4, r4, lsr #8 194129202Scognet orr r4, r4, r5, lsl #24 195129202Scognet mov r5, r5, lsr #8 196129202Scognet orr r5, r5, r12, lsl #24 197129202Scognet mov r12, r12, lsr #8 198129202Scognet orr r12, r12, lr, lsl #24 199129202Scognet#endif 200129202Scognet stmia r0!, {r3-r5, r12} 201129202Scognet subs r2, r2, #0x10 202129202Scognet bge .Lmemmove_fsrcul1loop16 203129202Scognet ldmia sp!, {r4, r5} 204129202Scognet adds r2, r2, #0x0c 205129202Scognet blt .Lmemmove_fsrcul1l4 206129202Scognet 207129202Scognet.Lmemmove_fsrcul1loop4: 208129202Scognet#ifdef __ARMEB__ 209129202Scognet mov r12, lr, lsl #8 210129202Scognet#else 211129202Scognet mov r12, lr, lsr #8 212129202Scognet#endif 213129202Scognet ldr lr, [r1], #4 214129202Scognet#ifdef __ARMEB__ 215129202Scognet orr r12, r12, lr, lsr #24 216129202Scognet#else 217129202Scognet orr r12, r12, lr, lsl #24 218129202Scognet#endif 219129202Scognet str r12, [r0], #4 220129202Scognet subs r2, r2, #4 221129202Scognet bge .Lmemmove_fsrcul1loop4 222129202Scognet 223129202Scognet.Lmemmove_fsrcul1l4: 224129202Scognet sub r1, r1, #3 225129202Scognet b .Lmemmove_fl4 226129202Scognet 227129202Scognet.Lmemmove_fsrcul2: 228129202Scognet cmp r2, #0x0c 229129202Scognet blt .Lmemmove_fsrcul2loop4 230129202Scognet sub r2, r2, #0x0c 231129202Scognet stmdb sp!, {r4, r5} 232129202Scognet 233129202Scognet.Lmemmove_fsrcul2loop16: 234129202Scognet#ifdef __ARMEB__ 235129202Scognet mov r3, lr, lsl #16 236129202Scognet#else 237129202Scognet mov r3, lr, lsr #16 238129202Scognet#endif 239129202Scognet ldmia r1!, {r4, r5, r12, lr} 240129202Scognet#ifdef __ARMEB__ 241129202Scognet orr r3, r3, r4, lsr #16 242129202Scognet mov r4, r4, lsl #16 243129202Scognet orr r4, r4, r5, lsr #16 244129202Scognet mov r5, r5, lsl #16 245129202Scognet orr r5, r5, r12, lsr #16 246129202Scognet mov r12, r12, lsl #16 247129202Scognet orr r12, r12, lr, lsr #16 248129202Scognet#else 249129202Scognet orr r3, r3, r4, lsl #16 250129202Scognet mov r4, r4, lsr #16 251129202Scognet orr r4, r4, r5, lsl #16 252129202Scognet mov r5, r5, lsr #16 253129202Scognet orr r5, r5, r12, lsl #16 254129202Scognet mov r12, r12, lsr #16 255129202Scognet orr r12, r12, lr, lsl #16 256129202Scognet#endif 257129202Scognet stmia r0!, {r3-r5, r12} 258129202Scognet subs r2, r2, #0x10 259129202Scognet bge .Lmemmove_fsrcul2loop16 260129202Scognet ldmia sp!, {r4, r5} 261129202Scognet adds r2, r2, #0x0c 262129202Scognet blt .Lmemmove_fsrcul2l4 263129202Scognet 264129202Scognet.Lmemmove_fsrcul2loop4: 265129202Scognet#ifdef __ARMEB__ 266129202Scognet mov r12, lr, lsl #16 267129202Scognet#else 268129202Scognet mov r12, lr, lsr #16 269129202Scognet#endif 270129202Scognet ldr lr, [r1], #4 271129202Scognet#ifdef __ARMEB__ 272129202Scognet orr r12, r12, lr, lsr #16 273129202Scognet#else 274129202Scognet orr r12, r12, lr, lsl #16 275129202Scognet#endif 276129202Scognet str r12, [r0], #4 277129202Scognet subs r2, r2, #4 278129202Scognet bge .Lmemmove_fsrcul2loop4 279129202Scognet 280129202Scognet.Lmemmove_fsrcul2l4: 281129202Scognet sub r1, r1, #2 282129202Scognet b .Lmemmove_fl4 283129202Scognet 284129202Scognet.Lmemmove_fsrcul3: 285129202Scognet cmp r2, #0x0c 286129202Scognet blt .Lmemmove_fsrcul3loop4 287129202Scognet sub r2, r2, #0x0c 288129202Scognet stmdb sp!, {r4, r5} 289129202Scognet 290129202Scognet.Lmemmove_fsrcul3loop16: 291129202Scognet#ifdef __ARMEB__ 292129202Scognet mov r3, lr, lsl #24 293129202Scognet#else 294129202Scognet mov r3, lr, lsr #24 295129202Scognet#endif 296129202Scognet ldmia r1!, {r4, r5, r12, lr} 297129202Scognet#ifdef __ARMEB__ 298129202Scognet orr r3, r3, r4, lsr #8 299129202Scognet mov r4, r4, lsl #24 300129202Scognet orr r4, r4, r5, lsr #8 301129202Scognet mov r5, r5, lsl #24 302129202Scognet orr r5, r5, r12, lsr #8 303129202Scognet mov r12, r12, lsl #24 304129202Scognet orr r12, r12, lr, lsr #8 305129202Scognet#else 306129202Scognet orr r3, r3, r4, lsl #8 307129202Scognet mov r4, r4, lsr #24 308129202Scognet orr r4, r4, r5, lsl #8 309129202Scognet mov r5, r5, lsr #24 310129202Scognet orr r5, r5, r12, lsl #8 311129202Scognet mov r12, r12, lsr #24 312129202Scognet orr r12, r12, lr, lsl #8 313129202Scognet#endif 314129202Scognet stmia r0!, {r3-r5, r12} 315129202Scognet subs r2, r2, #0x10 316129202Scognet bge .Lmemmove_fsrcul3loop16 317129202Scognet ldmia sp!, {r4, r5} 318129202Scognet adds r2, r2, #0x0c 319129202Scognet blt .Lmemmove_fsrcul3l4 320129202Scognet 321129202Scognet.Lmemmove_fsrcul3loop4: 322129202Scognet#ifdef __ARMEB__ 323129202Scognet mov r12, lr, lsl #24 324129202Scognet#else 325129202Scognet mov r12, lr, lsr #24 326129202Scognet#endif 327129202Scognet ldr lr, [r1], #4 328129202Scognet#ifdef __ARMEB__ 329129202Scognet orr r12, r12, lr, lsr #8 330129202Scognet#else 331129202Scognet orr r12, r12, lr, lsl #8 332129202Scognet#endif 333129202Scognet str r12, [r0], #4 334129202Scognet subs r2, r2, #4 335129202Scognet bge .Lmemmove_fsrcul3loop4 336129202Scognet 337129202Scognet.Lmemmove_fsrcul3l4: 338129202Scognet sub r1, r1, #1 339129202Scognet b .Lmemmove_fl4 340129202Scognet 341129202Scognet.Lmemmove_backwards: 342129202Scognet add r1, r1, r2 343129202Scognet add r0, r0, r2 344129202Scognet subs r2, r2, #4 345129202Scognet blt .Lmemmove_bl4 /* less than 4 bytes */ 346129202Scognet ands r12, r0, #3 347129202Scognet bne .Lmemmove_bdestul /* oh unaligned destination addr */ 348129202Scognet ands r12, r1, #3 349129202Scognet bne .Lmemmove_bsrcul /* oh unaligned source addr */ 350129202Scognet 351129202Scognet.Lmemmove_bt8: 352129202Scognet /* We have aligned source and destination */ 353129202Scognet subs r2, r2, #8 354129202Scognet blt .Lmemmove_bl12 /* less than 12 bytes (4 from above) */ 355129202Scognet stmdb sp!, {r4, lr} 356129202Scognet subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ 357129202Scognet blt .Lmemmove_bl32 358129202Scognet 359129202Scognet /* blat 32 bytes at a time */ 360129202Scognet /* XXX for really big copies perhaps we should use more registers */ 361129202Scognet.Lmemmove_bloop32: 362129202Scognet ldmdb r1!, {r3, r4, r12, lr} 363129202Scognet stmdb r0!, {r3, r4, r12, lr} 364129202Scognet ldmdb r1!, {r3, r4, r12, lr} 365129202Scognet stmdb r0!, {r3, r4, r12, lr} 366129202Scognet subs r2, r2, #0x20 367129202Scognet bge .Lmemmove_bloop32 368129202Scognet 369129202Scognet.Lmemmove_bl32: 370129202Scognet cmn r2, #0x10 371283831Sandrew ittt ge 372275256Sandrew ldmdbge r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ 373275256Sandrew stmdbge r0!, {r3, r4, r12, lr} 374129202Scognet subge r2, r2, #0x10 375129202Scognet adds r2, r2, #0x14 376283831Sandrew ittt ge 377275256Sandrew ldmdbge r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ 378275256Sandrew stmdbge r0!, {r3, r12, lr} 379129202Scognet subge r2, r2, #0x0c 380129202Scognet ldmia sp!, {r4, lr} 381129202Scognet 382129202Scognet.Lmemmove_bl12: 383129202Scognet adds r2, r2, #8 384129202Scognet blt .Lmemmove_bl4 385129202Scognet subs r2, r2, #4 386283831Sandrew itt lt 387129202Scognet ldrlt r3, [r1, #-4]! 388129202Scognet strlt r3, [r0, #-4]! 389283831Sandrew ittt ge 390275256Sandrew ldmdbge r1!, {r3, r12} 391275256Sandrew stmdbge r0!, {r3, r12} 392129202Scognet subge r2, r2, #4 393129202Scognet 394129202Scognet.Lmemmove_bl4: 395129202Scognet /* less than 4 bytes to go */ 396129202Scognet adds r2, r2, #4 397283831Sandrew it eq 398137464Scognet RETeq /* done */ 399129202Scognet 400129202Scognet /* copy the crud byte at a time */ 401129202Scognet cmp r2, #2 402129202Scognet ldrb r3, [r1, #-1]! 403129202Scognet strb r3, [r0, #-1]! 404283831Sandrew itt ge 405275256Sandrew ldrbge r3, [r1, #-1]! 406275256Sandrew strbge r3, [r0, #-1]! 407283831Sandrew itt gt 408275256Sandrew ldrbgt r3, [r1, #-1]! 409275256Sandrew strbgt r3, [r0, #-1]! 410137464Scognet RET 411129202Scognet 412129202Scognet /* erg - unaligned destination */ 413129202Scognet.Lmemmove_bdestul: 414129202Scognet cmp r12, #2 415129202Scognet 416129202Scognet /* align destination with byte copies */ 417129202Scognet ldrb r3, [r1, #-1]! 418129202Scognet strb r3, [r0, #-1]! 419283831Sandrew itt ge 420275256Sandrew ldrbge r3, [r1, #-1]! 421275256Sandrew strbge r3, [r0, #-1]! 422283831Sandrew itt gt 423275256Sandrew ldrbgt r3, [r1, #-1]! 424275256Sandrew strbgt r3, [r0, #-1]! 425129202Scognet subs r2, r2, r12 426129202Scognet blt .Lmemmove_bl4 /* less than 4 bytes to go */ 427129202Scognet ands r12, r1, #3 428129202Scognet beq .Lmemmove_bt8 /* we have an aligned source */ 429129202Scognet 430129202Scognet /* erg - unaligned source */ 431129202Scognet /* This is where it gets nasty ... */ 432129202Scognet.Lmemmove_bsrcul: 433129202Scognet bic r1, r1, #3 434129202Scognet ldr r3, [r1, #0] 435129202Scognet cmp r12, #2 436129202Scognet blt .Lmemmove_bsrcul1 437129202Scognet beq .Lmemmove_bsrcul2 438129202Scognet cmp r2, #0x0c 439129202Scognet blt .Lmemmove_bsrcul3loop4 440129202Scognet sub r2, r2, #0x0c 441129202Scognet stmdb sp!, {r4, r5, lr} 442129202Scognet 443129202Scognet.Lmemmove_bsrcul3loop16: 444129202Scognet#ifdef __ARMEB__ 445129202Scognet mov lr, r3, lsr #8 446129202Scognet#else 447129202Scognet mov lr, r3, lsl #8 448129202Scognet#endif 449129202Scognet ldmdb r1!, {r3-r5, r12} 450129202Scognet#ifdef __ARMEB__ 451129202Scognet orr lr, lr, r12, lsl #24 452129202Scognet mov r12, r12, lsr #8 453129202Scognet orr r12, r12, r5, lsl #24 454129202Scognet mov r5, r5, lsr #8 455129202Scognet orr r5, r5, r4, lsl #24 456129202Scognet mov r4, r4, lsr #8 457129202Scognet orr r4, r4, r3, lsl #24 458129202Scognet#else 459129202Scognet orr lr, lr, r12, lsr #24 460129202Scognet mov r12, r12, lsl #8 461129202Scognet orr r12, r12, r5, lsr #24 462129202Scognet mov r5, r5, lsl #8 463129202Scognet orr r5, r5, r4, lsr #24 464129202Scognet mov r4, r4, lsl #8 465129202Scognet orr r4, r4, r3, lsr #24 466129202Scognet#endif 467129202Scognet stmdb r0!, {r4, r5, r12, lr} 468129202Scognet subs r2, r2, #0x10 469129202Scognet bge .Lmemmove_bsrcul3loop16 470129202Scognet ldmia sp!, {r4, r5, lr} 471129202Scognet adds r2, r2, #0x0c 472129202Scognet blt .Lmemmove_bsrcul3l4 473129202Scognet 474129202Scognet.Lmemmove_bsrcul3loop4: 475129202Scognet#ifdef __ARMEB__ 476129202Scognet mov r12, r3, lsr #8 477129202Scognet#else 478129202Scognet mov r12, r3, lsl #8 479129202Scognet#endif 480129202Scognet ldr r3, [r1, #-4]! 481129202Scognet#ifdef __ARMEB__ 482129202Scognet orr r12, r12, r3, lsl #24 483129202Scognet#else 484129202Scognet orr r12, r12, r3, lsr #24 485129202Scognet#endif 486129202Scognet str r12, [r0, #-4]! 487129202Scognet subs r2, r2, #4 488129202Scognet bge .Lmemmove_bsrcul3loop4 489129202Scognet 490129202Scognet.Lmemmove_bsrcul3l4: 491129202Scognet add r1, r1, #3 492129202Scognet b .Lmemmove_bl4 493129202Scognet 494129202Scognet.Lmemmove_bsrcul2: 495129202Scognet cmp r2, #0x0c 496129202Scognet blt .Lmemmove_bsrcul2loop4 497129202Scognet sub r2, r2, #0x0c 498129202Scognet stmdb sp!, {r4, r5, lr} 499129202Scognet 500129202Scognet.Lmemmove_bsrcul2loop16: 501129202Scognet#ifdef __ARMEB__ 502129202Scognet mov lr, r3, lsr #16 503129202Scognet#else 504129202Scognet mov lr, r3, lsl #16 505129202Scognet#endif 506129202Scognet ldmdb r1!, {r3-r5, r12} 507129202Scognet#ifdef __ARMEB__ 508129202Scognet orr lr, lr, r12, lsl #16 509129202Scognet mov r12, r12, lsr #16 510129202Scognet orr r12, r12, r5, lsl #16 511129202Scognet mov r5, r5, lsr #16 512129202Scognet orr r5, r5, r4, lsl #16 513129202Scognet mov r4, r4, lsr #16 514129202Scognet orr r4, r4, r3, lsl #16 515129202Scognet#else 516129202Scognet orr lr, lr, r12, lsr #16 517129202Scognet mov r12, r12, lsl #16 518129202Scognet orr r12, r12, r5, lsr #16 519129202Scognet mov r5, r5, lsl #16 520129202Scognet orr r5, r5, r4, lsr #16 521129202Scognet mov r4, r4, lsl #16 522129202Scognet orr r4, r4, r3, lsr #16 523129202Scognet#endif 524129202Scognet stmdb r0!, {r4, r5, r12, lr} 525129202Scognet subs r2, r2, #0x10 526129202Scognet bge .Lmemmove_bsrcul2loop16 527129202Scognet ldmia sp!, {r4, r5, lr} 528129202Scognet adds r2, r2, #0x0c 529129202Scognet blt .Lmemmove_bsrcul2l4 530129202Scognet 531129202Scognet.Lmemmove_bsrcul2loop4: 532129202Scognet#ifdef __ARMEB__ 533129202Scognet mov r12, r3, lsr #16 534129202Scognet#else 535129202Scognet mov r12, r3, lsl #16 536129202Scognet#endif 537129202Scognet ldr r3, [r1, #-4]! 538129202Scognet#ifdef __ARMEB__ 539129202Scognet orr r12, r12, r3, lsl #16 540129202Scognet#else 541129202Scognet orr r12, r12, r3, lsr #16 542129202Scognet#endif 543129202Scognet str r12, [r0, #-4]! 544129202Scognet subs r2, r2, #4 545129202Scognet bge .Lmemmove_bsrcul2loop4 546129202Scognet 547129202Scognet.Lmemmove_bsrcul2l4: 548129202Scognet add r1, r1, #2 549129202Scognet b .Lmemmove_bl4 550129202Scognet 551129202Scognet.Lmemmove_bsrcul1: 552129202Scognet cmp r2, #0x0c 553129202Scognet blt .Lmemmove_bsrcul1loop4 554129202Scognet sub r2, r2, #0x0c 555129202Scognet stmdb sp!, {r4, r5, lr} 556129202Scognet 557129202Scognet.Lmemmove_bsrcul1loop32: 558129202Scognet#ifdef __ARMEB__ 559129202Scognet mov lr, r3, lsr #24 560129202Scognet#else 561129202Scognet mov lr, r3, lsl #24 562129202Scognet#endif 563129202Scognet ldmdb r1!, {r3-r5, r12} 564129202Scognet#ifdef __ARMEB__ 565129202Scognet orr lr, lr, r12, lsl #8 566129202Scognet mov r12, r12, lsr #24 567129202Scognet orr r12, r12, r5, lsl #8 568129202Scognet mov r5, r5, lsr #24 569129202Scognet orr r5, r5, r4, lsl #8 570129202Scognet mov r4, r4, lsr #24 571129202Scognet orr r4, r4, r3, lsl #8 572129202Scognet#else 573129202Scognet orr lr, lr, r12, lsr #8 574129202Scognet mov r12, r12, lsl #24 575129202Scognet orr r12, r12, r5, lsr #8 576129202Scognet mov r5, r5, lsl #24 577129202Scognet orr r5, r5, r4, lsr #8 578129202Scognet mov r4, r4, lsl #24 579129202Scognet orr r4, r4, r3, lsr #8 580129202Scognet#endif 581129202Scognet stmdb r0!, {r4, r5, r12, lr} 582129202Scognet subs r2, r2, #0x10 583129202Scognet bge .Lmemmove_bsrcul1loop32 584129202Scognet ldmia sp!, {r4, r5, lr} 585129202Scognet adds r2, r2, #0x0c 586129202Scognet blt .Lmemmove_bsrcul1l4 587129202Scognet 588129202Scognet.Lmemmove_bsrcul1loop4: 589129202Scognet#ifdef __ARMEB__ 590129202Scognet mov r12, r3, lsr #24 591129202Scognet#else 592129202Scognet mov r12, r3, lsl #24 593129202Scognet#endif 594129202Scognet ldr r3, [r1, #-4]! 595129202Scognet#ifdef __ARMEB__ 596129202Scognet orr r12, r12, r3, lsl #8 597129202Scognet#else 598129202Scognet orr r12, r12, r3, lsr #8 599129202Scognet#endif 600129202Scognet str r12, [r0, #-4]! 601129202Scognet subs r2, r2, #4 602129202Scognet bge .Lmemmove_bsrcul1loop4 603129202Scognet 604129202Scognet.Lmemmove_bsrcul1l4: 605129202Scognet add r1, r1, #1 606129202Scognet b .Lmemmove_bl4 607270882Sian#ifndef _BCOPY 608270882SianEND(memmove) 609270882Sian#else 610270882SianEND(bcopy) 611270882Sian#endif 612288373Skib 613288373Skib .section .note.GNU-stack,"",%progbits 614