12357939bSOlivier Houchard/* $NetBSD: memmove.S,v 1.4 2003/10/14 07:51:45 scw Exp $ */ 22357939bSOlivier Houchard 32357939bSOlivier Houchard/*- 42357939bSOlivier Houchard * Copyright (c) 1997 The NetBSD Foundation, Inc. 52357939bSOlivier Houchard * All rights reserved. 62357939bSOlivier Houchard * 72357939bSOlivier Houchard * This code is derived from software contributed to The NetBSD Foundation 82357939bSOlivier Houchard * by Neil A. Carson and Mark Brinicombe 92357939bSOlivier Houchard * 102357939bSOlivier Houchard * Redistribution and use in source and binary forms, with or without 112357939bSOlivier Houchard * modification, are permitted provided that the following conditions 122357939bSOlivier Houchard * are met: 132357939bSOlivier Houchard * 1. Redistributions of source code must retain the above copyright 142357939bSOlivier Houchard * notice, this list of conditions and the following disclaimer. 152357939bSOlivier Houchard * 2. Redistributions in binary form must reproduce the above copyright 162357939bSOlivier Houchard * notice, this list of conditions and the following disclaimer in the 172357939bSOlivier Houchard * documentation and/or other materials provided with the distribution. 182357939bSOlivier Houchard * 192357939bSOlivier Houchard * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 202357939bSOlivier Houchard * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 212357939bSOlivier Houchard * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 222357939bSOlivier Houchard * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 232357939bSOlivier Houchard * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 242357939bSOlivier Houchard * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 252357939bSOlivier Houchard * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 262357939bSOlivier Houchard * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 272357939bSOlivier Houchard * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 282357939bSOlivier Houchard * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 292357939bSOlivier Houchard * POSSIBILITY OF SUCH DAMAGE. 302357939bSOlivier Houchard */ 312357939bSOlivier Houchard 322357939bSOlivier Houchard#include <machine/asm.h> 33a215cdfdSAndrew Turner.syntax unified 34a215cdfdSAndrew Turner 352357939bSOlivier Houchard#ifndef _BCOPY 362357939bSOlivier Houchard/* LINTSTUB: Func: void *memmove(void *, const void *, size_t) */ 372357939bSOlivier HouchardENTRY(memmove) 382357939bSOlivier Houchard#else 392357939bSOlivier Houchard/* bcopy = memcpy/memmove with arguments reversed. */ 402357939bSOlivier Houchard/* LINTSTUB: Func: void bcopy(void *, void *, size_t) */ 412357939bSOlivier HouchardENTRY(bcopy) 422357939bSOlivier Houchard /* switch the source and destination registers */ 432357939bSOlivier Houchard eor r0, r1, r0 442357939bSOlivier Houchard eor r1, r0, r1 452357939bSOlivier Houchard eor r0, r1, r0 462357939bSOlivier Houchard#endif 472357939bSOlivier Houchard /* Do the buffers overlap? */ 482357939bSOlivier Houchard cmp r0, r1 496c5bc49cSAndrew Turner it eq 5031489a9aSOlivier Houchard RETeq /* Bail now if src/dst are the same */ 516c5bc49cSAndrew Turner ite cc 522357939bSOlivier Houchard subcc r3, r0, r1 /* if (dst > src) r3 = dst - src */ 532357939bSOlivier Houchard subcs r3, r1, r0 /* if (src > dsr) r3 = src - dst */ 542357939bSOlivier Houchard cmp r3, r2 /* if (r3 < len) we have an overlap */ 552357939bSOlivier Houchard bcc PIC_SYM(_C_LABEL(memcpy), PLT) 562357939bSOlivier Houchard 572357939bSOlivier Houchard /* Determine copy direction */ 582357939bSOlivier Houchard cmp r1, r0 596c5bc49cSAndrew Turner it cc 602357939bSOlivier Houchard bcc .Lmemmove_backwards 612357939bSOlivier Houchard 626c5bc49cSAndrew Turner itt eq 632357939bSOlivier Houchard moveq r0, #0 /* Quick abort for len=0 */ 6431489a9aSOlivier Houchard RETeq 652357939bSOlivier Houchard 662357939bSOlivier Houchard stmdb sp!, {r0, lr} /* memmove() returns dest addr */ 672357939bSOlivier Houchard subs r2, r2, #4 682357939bSOlivier Houchard blt .Lmemmove_fl4 /* less than 4 bytes */ 692357939bSOlivier Houchard ands r12, r0, #3 702357939bSOlivier Houchard bne .Lmemmove_fdestul /* oh unaligned destination addr */ 712357939bSOlivier Houchard ands r12, r1, #3 722357939bSOlivier Houchard bne .Lmemmove_fsrcul /* oh unaligned source addr */ 732357939bSOlivier Houchard 742357939bSOlivier Houchard.Lmemmove_ft8: 752357939bSOlivier Houchard /* We have aligned source and destination */ 762357939bSOlivier Houchard subs r2, r2, #8 772357939bSOlivier Houchard blt .Lmemmove_fl12 /* less than 12 bytes (4 from above) */ 782357939bSOlivier Houchard subs r2, r2, #0x14 792357939bSOlivier Houchard blt .Lmemmove_fl32 /* less than 32 bytes (12 from above) */ 802357939bSOlivier Houchard stmdb sp!, {r4} /* borrow r4 */ 812357939bSOlivier Houchard 822357939bSOlivier Houchard /* blat 32 bytes at a time */ 832357939bSOlivier Houchard /* XXX for really big copies perhaps we should use more registers */ 842357939bSOlivier Houchard.Lmemmove_floop32: 852357939bSOlivier Houchard ldmia r1!, {r3, r4, r12, lr} 862357939bSOlivier Houchard stmia r0!, {r3, r4, r12, lr} 872357939bSOlivier Houchard ldmia r1!, {r3, r4, r12, lr} 882357939bSOlivier Houchard stmia r0!, {r3, r4, r12, lr} 892357939bSOlivier Houchard subs r2, r2, #0x20 902357939bSOlivier Houchard bge .Lmemmove_floop32 912357939bSOlivier Houchard 922357939bSOlivier Houchard cmn r2, #0x10 936c5bc49cSAndrew Turner ittt ge 94a215cdfdSAndrew Turner ldmiage r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ 95a215cdfdSAndrew Turner stmiage r0!, {r3, r4, r12, lr} 962357939bSOlivier Houchard subge r2, r2, #0x10 972357939bSOlivier Houchard ldmia sp!, {r4} /* return r4 */ 982357939bSOlivier Houchard 992357939bSOlivier Houchard.Lmemmove_fl32: 1002357939bSOlivier Houchard adds r2, r2, #0x14 1012357939bSOlivier Houchard 1022357939bSOlivier Houchard /* blat 12 bytes at a time */ 1032357939bSOlivier Houchard.Lmemmove_floop12: 1046c5bc49cSAndrew Turner ittt ge 105a215cdfdSAndrew Turner ldmiage r1!, {r3, r12, lr} 106a215cdfdSAndrew Turner stmiage r0!, {r3, r12, lr} 107a215cdfdSAndrew Turner subsge r2, r2, #0x0c 1082357939bSOlivier Houchard bge .Lmemmove_floop12 1092357939bSOlivier Houchard 1102357939bSOlivier Houchard.Lmemmove_fl12: 1112357939bSOlivier Houchard adds r2, r2, #8 1122357939bSOlivier Houchard blt .Lmemmove_fl4 1132357939bSOlivier Houchard 1142357939bSOlivier Houchard subs r2, r2, #4 1156c5bc49cSAndrew Turner itt lt 1162357939bSOlivier Houchard ldrlt r3, [r1], #4 1172357939bSOlivier Houchard strlt r3, [r0], #4 1186c5bc49cSAndrew Turner ittt ge 119a215cdfdSAndrew Turner ldmiage r1!, {r3, r12} 120a215cdfdSAndrew Turner stmiage r0!, {r3, r12} 1212357939bSOlivier Houchard subge r2, r2, #4 1222357939bSOlivier Houchard 1232357939bSOlivier Houchard.Lmemmove_fl4: 1242357939bSOlivier Houchard /* less than 4 bytes to go */ 1252357939bSOlivier Houchard adds r2, r2, #4 1266c5bc49cSAndrew Turner it eq 127a215cdfdSAndrew Turner ldmiaeq sp!, {r0, pc} /* done */ 1282357939bSOlivier Houchard 1292357939bSOlivier Houchard /* copy the crud byte at a time */ 1302357939bSOlivier Houchard cmp r2, #2 1312357939bSOlivier Houchard ldrb r3, [r1], #1 1322357939bSOlivier Houchard strb r3, [r0], #1 1336c5bc49cSAndrew Turner itt ge 134a215cdfdSAndrew Turner ldrbge r3, [r1], #1 135a215cdfdSAndrew Turner strbge r3, [r0], #1 1366c5bc49cSAndrew Turner itt gt 137a215cdfdSAndrew Turner ldrbgt r3, [r1], #1 138a215cdfdSAndrew Turner strbgt r3, [r0], #1 1392357939bSOlivier Houchard ldmia sp!, {r0, pc} 1402357939bSOlivier Houchard 1412357939bSOlivier Houchard /* erg - unaligned destination */ 1422357939bSOlivier Houchard.Lmemmove_fdestul: 1432357939bSOlivier Houchard rsb r12, r12, #4 1442357939bSOlivier Houchard cmp r12, #2 1452357939bSOlivier Houchard 1462357939bSOlivier Houchard /* align destination with byte copies */ 1472357939bSOlivier Houchard ldrb r3, [r1], #1 1482357939bSOlivier Houchard strb r3, [r0], #1 1496c5bc49cSAndrew Turner itt ge 150a215cdfdSAndrew Turner ldrbge r3, [r1], #1 151a215cdfdSAndrew Turner strbge r3, [r0], #1 1526c5bc49cSAndrew Turner itt gt 153a215cdfdSAndrew Turner ldrbgt r3, [r1], #1 154a215cdfdSAndrew Turner strbgt r3, [r0], #1 1552357939bSOlivier Houchard subs r2, r2, r12 1562357939bSOlivier Houchard blt .Lmemmove_fl4 /* less the 4 bytes */ 1572357939bSOlivier Houchard 1582357939bSOlivier Houchard ands r12, r1, #3 1592357939bSOlivier Houchard beq .Lmemmove_ft8 /* we have an aligned source */ 1602357939bSOlivier Houchard 1612357939bSOlivier Houchard /* erg - unaligned source */ 1622357939bSOlivier Houchard /* This is where it gets nasty ... */ 1632357939bSOlivier Houchard.Lmemmove_fsrcul: 1642357939bSOlivier Houchard bic r1, r1, #3 1652357939bSOlivier Houchard ldr lr, [r1], #4 1662357939bSOlivier Houchard cmp r12, #2 1672357939bSOlivier Houchard bgt .Lmemmove_fsrcul3 1682357939bSOlivier Houchard beq .Lmemmove_fsrcul2 1692357939bSOlivier Houchard cmp r2, #0x0c 1702357939bSOlivier Houchard blt .Lmemmove_fsrcul1loop4 1712357939bSOlivier Houchard sub r2, r2, #0x0c 1722357939bSOlivier Houchard stmdb sp!, {r4, r5} 1732357939bSOlivier Houchard 1742357939bSOlivier Houchard.Lmemmove_fsrcul1loop16: 1752357939bSOlivier Houchard mov r3, lr, lsr #8 1762357939bSOlivier Houchard ldmia r1!, {r4, r5, r12, lr} 1772357939bSOlivier Houchard orr r3, r3, r4, lsl #24 1782357939bSOlivier Houchard mov r4, r4, lsr #8 1792357939bSOlivier Houchard orr r4, r4, r5, lsl #24 1802357939bSOlivier Houchard mov r5, r5, lsr #8 1812357939bSOlivier Houchard orr r5, r5, r12, lsl #24 1822357939bSOlivier Houchard mov r12, r12, lsr #8 1832357939bSOlivier Houchard orr r12, r12, lr, lsl #24 1842357939bSOlivier Houchard stmia r0!, {r3-r5, r12} 1852357939bSOlivier Houchard subs r2, r2, #0x10 1862357939bSOlivier Houchard bge .Lmemmove_fsrcul1loop16 1872357939bSOlivier Houchard ldmia sp!, {r4, r5} 1882357939bSOlivier Houchard adds r2, r2, #0x0c 1892357939bSOlivier Houchard blt .Lmemmove_fsrcul1l4 1902357939bSOlivier Houchard 1912357939bSOlivier Houchard.Lmemmove_fsrcul1loop4: 1922357939bSOlivier Houchard mov r12, lr, lsr #8 1932357939bSOlivier Houchard ldr lr, [r1], #4 1942357939bSOlivier Houchard orr r12, r12, lr, lsl #24 1952357939bSOlivier Houchard str r12, [r0], #4 1962357939bSOlivier Houchard subs r2, r2, #4 1972357939bSOlivier Houchard bge .Lmemmove_fsrcul1loop4 1982357939bSOlivier Houchard 1992357939bSOlivier Houchard.Lmemmove_fsrcul1l4: 2002357939bSOlivier Houchard sub r1, r1, #3 2012357939bSOlivier Houchard b .Lmemmove_fl4 2022357939bSOlivier Houchard 2032357939bSOlivier Houchard.Lmemmove_fsrcul2: 2042357939bSOlivier Houchard cmp r2, #0x0c 2052357939bSOlivier Houchard blt .Lmemmove_fsrcul2loop4 2062357939bSOlivier Houchard sub r2, r2, #0x0c 2072357939bSOlivier Houchard stmdb sp!, {r4, r5} 2082357939bSOlivier Houchard 2092357939bSOlivier Houchard.Lmemmove_fsrcul2loop16: 2102357939bSOlivier Houchard mov r3, lr, lsr #16 2112357939bSOlivier Houchard ldmia r1!, {r4, r5, r12, lr} 2122357939bSOlivier Houchard orr r3, r3, r4, lsl #16 2132357939bSOlivier Houchard mov r4, r4, lsr #16 2142357939bSOlivier Houchard orr r4, r4, r5, lsl #16 2152357939bSOlivier Houchard mov r5, r5, lsr #16 2162357939bSOlivier Houchard orr r5, r5, r12, lsl #16 2172357939bSOlivier Houchard mov r12, r12, lsr #16 2182357939bSOlivier Houchard orr r12, r12, lr, lsl #16 2192357939bSOlivier Houchard stmia r0!, {r3-r5, r12} 2202357939bSOlivier Houchard subs r2, r2, #0x10 2212357939bSOlivier Houchard bge .Lmemmove_fsrcul2loop16 2222357939bSOlivier Houchard ldmia sp!, {r4, r5} 2232357939bSOlivier Houchard adds r2, r2, #0x0c 2242357939bSOlivier Houchard blt .Lmemmove_fsrcul2l4 2252357939bSOlivier Houchard 2262357939bSOlivier Houchard.Lmemmove_fsrcul2loop4: 2272357939bSOlivier Houchard mov r12, lr, lsr #16 2282357939bSOlivier Houchard ldr lr, [r1], #4 2292357939bSOlivier Houchard orr r12, r12, lr, lsl #16 2302357939bSOlivier Houchard str r12, [r0], #4 2312357939bSOlivier Houchard subs r2, r2, #4 2322357939bSOlivier Houchard bge .Lmemmove_fsrcul2loop4 2332357939bSOlivier Houchard 2342357939bSOlivier Houchard.Lmemmove_fsrcul2l4: 2352357939bSOlivier Houchard sub r1, r1, #2 2362357939bSOlivier Houchard b .Lmemmove_fl4 2372357939bSOlivier Houchard 2382357939bSOlivier Houchard.Lmemmove_fsrcul3: 2392357939bSOlivier Houchard cmp r2, #0x0c 2402357939bSOlivier Houchard blt .Lmemmove_fsrcul3loop4 2412357939bSOlivier Houchard sub r2, r2, #0x0c 2422357939bSOlivier Houchard stmdb sp!, {r4, r5} 2432357939bSOlivier Houchard 2442357939bSOlivier Houchard.Lmemmove_fsrcul3loop16: 2452357939bSOlivier Houchard mov r3, lr, lsr #24 2462357939bSOlivier Houchard ldmia r1!, {r4, r5, r12, lr} 2472357939bSOlivier Houchard orr r3, r3, r4, lsl #8 2482357939bSOlivier Houchard mov r4, r4, lsr #24 2492357939bSOlivier Houchard orr r4, r4, r5, lsl #8 2502357939bSOlivier Houchard mov r5, r5, lsr #24 2512357939bSOlivier Houchard orr r5, r5, r12, lsl #8 2522357939bSOlivier Houchard mov r12, r12, lsr #24 2532357939bSOlivier Houchard orr r12, r12, lr, lsl #8 2542357939bSOlivier Houchard stmia r0!, {r3-r5, r12} 2552357939bSOlivier Houchard subs r2, r2, #0x10 2562357939bSOlivier Houchard bge .Lmemmove_fsrcul3loop16 2572357939bSOlivier Houchard ldmia sp!, {r4, r5} 2582357939bSOlivier Houchard adds r2, r2, #0x0c 2592357939bSOlivier Houchard blt .Lmemmove_fsrcul3l4 2602357939bSOlivier Houchard 2612357939bSOlivier Houchard.Lmemmove_fsrcul3loop4: 2622357939bSOlivier Houchard mov r12, lr, lsr #24 2632357939bSOlivier Houchard ldr lr, [r1], #4 2642357939bSOlivier Houchard orr r12, r12, lr, lsl #8 2652357939bSOlivier Houchard str r12, [r0], #4 2662357939bSOlivier Houchard subs r2, r2, #4 2672357939bSOlivier Houchard bge .Lmemmove_fsrcul3loop4 2682357939bSOlivier Houchard 2692357939bSOlivier Houchard.Lmemmove_fsrcul3l4: 2702357939bSOlivier Houchard sub r1, r1, #1 2712357939bSOlivier Houchard b .Lmemmove_fl4 2722357939bSOlivier Houchard 2732357939bSOlivier Houchard.Lmemmove_backwards: 2742357939bSOlivier Houchard add r1, r1, r2 2752357939bSOlivier Houchard add r0, r0, r2 2762357939bSOlivier Houchard subs r2, r2, #4 2772357939bSOlivier Houchard blt .Lmemmove_bl4 /* less than 4 bytes */ 2782357939bSOlivier Houchard ands r12, r0, #3 2792357939bSOlivier Houchard bne .Lmemmove_bdestul /* oh unaligned destination addr */ 2802357939bSOlivier Houchard ands r12, r1, #3 2812357939bSOlivier Houchard bne .Lmemmove_bsrcul /* oh unaligned source addr */ 2822357939bSOlivier Houchard 2832357939bSOlivier Houchard.Lmemmove_bt8: 2842357939bSOlivier Houchard /* We have aligned source and destination */ 2852357939bSOlivier Houchard subs r2, r2, #8 2862357939bSOlivier Houchard blt .Lmemmove_bl12 /* less than 12 bytes (4 from above) */ 2872357939bSOlivier Houchard stmdb sp!, {r4, lr} 2882357939bSOlivier Houchard subs r2, r2, #0x14 /* less than 32 bytes (12 from above) */ 2892357939bSOlivier Houchard blt .Lmemmove_bl32 2902357939bSOlivier Houchard 2912357939bSOlivier Houchard /* blat 32 bytes at a time */ 2922357939bSOlivier Houchard /* XXX for really big copies perhaps we should use more registers */ 2932357939bSOlivier Houchard.Lmemmove_bloop32: 2942357939bSOlivier Houchard ldmdb r1!, {r3, r4, r12, lr} 2952357939bSOlivier Houchard stmdb r0!, {r3, r4, r12, lr} 2962357939bSOlivier Houchard ldmdb r1!, {r3, r4, r12, lr} 2972357939bSOlivier Houchard stmdb r0!, {r3, r4, r12, lr} 2982357939bSOlivier Houchard subs r2, r2, #0x20 2992357939bSOlivier Houchard bge .Lmemmove_bloop32 3002357939bSOlivier Houchard 3012357939bSOlivier Houchard.Lmemmove_bl32: 3022357939bSOlivier Houchard cmn r2, #0x10 3036c5bc49cSAndrew Turner ittt ge 304a215cdfdSAndrew Turner ldmdbge r1!, {r3, r4, r12, lr} /* blat a remaining 16 bytes */ 305a215cdfdSAndrew Turner stmdbge r0!, {r3, r4, r12, lr} 3062357939bSOlivier Houchard subge r2, r2, #0x10 3072357939bSOlivier Houchard adds r2, r2, #0x14 3086c5bc49cSAndrew Turner ittt ge 309a215cdfdSAndrew Turner ldmdbge r1!, {r3, r12, lr} /* blat a remaining 12 bytes */ 310a215cdfdSAndrew Turner stmdbge r0!, {r3, r12, lr} 3112357939bSOlivier Houchard subge r2, r2, #0x0c 3122357939bSOlivier Houchard ldmia sp!, {r4, lr} 3132357939bSOlivier Houchard 3142357939bSOlivier Houchard.Lmemmove_bl12: 3152357939bSOlivier Houchard adds r2, r2, #8 3162357939bSOlivier Houchard blt .Lmemmove_bl4 3172357939bSOlivier Houchard subs r2, r2, #4 3186c5bc49cSAndrew Turner itt lt 3192357939bSOlivier Houchard ldrlt r3, [r1, #-4]! 3202357939bSOlivier Houchard strlt r3, [r0, #-4]! 3216c5bc49cSAndrew Turner ittt ge 322a215cdfdSAndrew Turner ldmdbge r1!, {r3, r12} 323a215cdfdSAndrew Turner stmdbge r0!, {r3, r12} 3242357939bSOlivier Houchard subge r2, r2, #4 3252357939bSOlivier Houchard 3262357939bSOlivier Houchard.Lmemmove_bl4: 3272357939bSOlivier Houchard /* less than 4 bytes to go */ 3282357939bSOlivier Houchard adds r2, r2, #4 3296c5bc49cSAndrew Turner it eq 33031489a9aSOlivier Houchard RETeq /* done */ 3312357939bSOlivier Houchard 3322357939bSOlivier Houchard /* copy the crud byte at a time */ 3332357939bSOlivier Houchard cmp r2, #2 3342357939bSOlivier Houchard ldrb r3, [r1, #-1]! 3352357939bSOlivier Houchard strb r3, [r0, #-1]! 3366c5bc49cSAndrew Turner itt ge 337a215cdfdSAndrew Turner ldrbge r3, [r1, #-1]! 338a215cdfdSAndrew Turner strbge r3, [r0, #-1]! 3396c5bc49cSAndrew Turner itt gt 340a215cdfdSAndrew Turner ldrbgt r3, [r1, #-1]! 341a215cdfdSAndrew Turner strbgt r3, [r0, #-1]! 34231489a9aSOlivier Houchard RET 3432357939bSOlivier Houchard 3442357939bSOlivier Houchard /* erg - unaligned destination */ 3452357939bSOlivier Houchard.Lmemmove_bdestul: 3462357939bSOlivier Houchard cmp r12, #2 3472357939bSOlivier Houchard 3482357939bSOlivier Houchard /* align destination with byte copies */ 3492357939bSOlivier Houchard ldrb r3, [r1, #-1]! 3502357939bSOlivier Houchard strb r3, [r0, #-1]! 3516c5bc49cSAndrew Turner itt ge 352a215cdfdSAndrew Turner ldrbge r3, [r1, #-1]! 353a215cdfdSAndrew Turner strbge r3, [r0, #-1]! 3546c5bc49cSAndrew Turner itt gt 355a215cdfdSAndrew Turner ldrbgt r3, [r1, #-1]! 356a215cdfdSAndrew Turner strbgt r3, [r0, #-1]! 3572357939bSOlivier Houchard subs r2, r2, r12 3582357939bSOlivier Houchard blt .Lmemmove_bl4 /* less than 4 bytes to go */ 3592357939bSOlivier Houchard ands r12, r1, #3 3602357939bSOlivier Houchard beq .Lmemmove_bt8 /* we have an aligned source */ 3612357939bSOlivier Houchard 3622357939bSOlivier Houchard /* erg - unaligned source */ 3632357939bSOlivier Houchard /* This is where it gets nasty ... */ 3642357939bSOlivier Houchard.Lmemmove_bsrcul: 3652357939bSOlivier Houchard bic r1, r1, #3 3662357939bSOlivier Houchard ldr r3, [r1, #0] 3672357939bSOlivier Houchard cmp r12, #2 3682357939bSOlivier Houchard blt .Lmemmove_bsrcul1 3692357939bSOlivier Houchard beq .Lmemmove_bsrcul2 3702357939bSOlivier Houchard cmp r2, #0x0c 3712357939bSOlivier Houchard blt .Lmemmove_bsrcul3loop4 3722357939bSOlivier Houchard sub r2, r2, #0x0c 3732357939bSOlivier Houchard stmdb sp!, {r4, r5, lr} 3742357939bSOlivier Houchard 3752357939bSOlivier Houchard.Lmemmove_bsrcul3loop16: 3762357939bSOlivier Houchard mov lr, r3, lsl #8 3772357939bSOlivier Houchard ldmdb r1!, {r3-r5, r12} 3782357939bSOlivier Houchard orr lr, lr, r12, lsr #24 3792357939bSOlivier Houchard mov r12, r12, lsl #8 3802357939bSOlivier Houchard orr r12, r12, r5, lsr #24 3812357939bSOlivier Houchard mov r5, r5, lsl #8 3822357939bSOlivier Houchard orr r5, r5, r4, lsr #24 3832357939bSOlivier Houchard mov r4, r4, lsl #8 3842357939bSOlivier Houchard orr r4, r4, r3, lsr #24 3852357939bSOlivier Houchard stmdb r0!, {r4, r5, r12, lr} 3862357939bSOlivier Houchard subs r2, r2, #0x10 3872357939bSOlivier Houchard bge .Lmemmove_bsrcul3loop16 3882357939bSOlivier Houchard ldmia sp!, {r4, r5, lr} 3892357939bSOlivier Houchard adds r2, r2, #0x0c 3902357939bSOlivier Houchard blt .Lmemmove_bsrcul3l4 3912357939bSOlivier Houchard 3922357939bSOlivier Houchard.Lmemmove_bsrcul3loop4: 3932357939bSOlivier Houchard mov r12, r3, lsl #8 3942357939bSOlivier Houchard ldr r3, [r1, #-4]! 3952357939bSOlivier Houchard orr r12, r12, r3, lsr #24 3962357939bSOlivier Houchard str r12, [r0, #-4]! 3972357939bSOlivier Houchard subs r2, r2, #4 3982357939bSOlivier Houchard bge .Lmemmove_bsrcul3loop4 3992357939bSOlivier Houchard 4002357939bSOlivier Houchard.Lmemmove_bsrcul3l4: 4012357939bSOlivier Houchard add r1, r1, #3 4022357939bSOlivier Houchard b .Lmemmove_bl4 4032357939bSOlivier Houchard 4042357939bSOlivier Houchard.Lmemmove_bsrcul2: 4052357939bSOlivier Houchard cmp r2, #0x0c 4062357939bSOlivier Houchard blt .Lmemmove_bsrcul2loop4 4072357939bSOlivier Houchard sub r2, r2, #0x0c 4082357939bSOlivier Houchard stmdb sp!, {r4, r5, lr} 4092357939bSOlivier Houchard 4102357939bSOlivier Houchard.Lmemmove_bsrcul2loop16: 4112357939bSOlivier Houchard mov lr, r3, lsl #16 4122357939bSOlivier Houchard ldmdb r1!, {r3-r5, r12} 4132357939bSOlivier Houchard orr lr, lr, r12, lsr #16 4142357939bSOlivier Houchard mov r12, r12, lsl #16 4152357939bSOlivier Houchard orr r12, r12, r5, lsr #16 4162357939bSOlivier Houchard mov r5, r5, lsl #16 4172357939bSOlivier Houchard orr r5, r5, r4, lsr #16 4182357939bSOlivier Houchard mov r4, r4, lsl #16 4192357939bSOlivier Houchard orr r4, r4, r3, lsr #16 4202357939bSOlivier Houchard stmdb r0!, {r4, r5, r12, lr} 4212357939bSOlivier Houchard subs r2, r2, #0x10 4222357939bSOlivier Houchard bge .Lmemmove_bsrcul2loop16 4232357939bSOlivier Houchard ldmia sp!, {r4, r5, lr} 4242357939bSOlivier Houchard adds r2, r2, #0x0c 4252357939bSOlivier Houchard blt .Lmemmove_bsrcul2l4 4262357939bSOlivier Houchard 4272357939bSOlivier Houchard.Lmemmove_bsrcul2loop4: 4282357939bSOlivier Houchard mov r12, r3, lsl #16 4292357939bSOlivier Houchard ldr r3, [r1, #-4]! 4302357939bSOlivier Houchard orr r12, r12, r3, lsr #16 4312357939bSOlivier Houchard str r12, [r0, #-4]! 4322357939bSOlivier Houchard subs r2, r2, #4 4332357939bSOlivier Houchard bge .Lmemmove_bsrcul2loop4 4342357939bSOlivier Houchard 4352357939bSOlivier Houchard.Lmemmove_bsrcul2l4: 4362357939bSOlivier Houchard add r1, r1, #2 4372357939bSOlivier Houchard b .Lmemmove_bl4 4382357939bSOlivier Houchard 4392357939bSOlivier Houchard.Lmemmove_bsrcul1: 4402357939bSOlivier Houchard cmp r2, #0x0c 4412357939bSOlivier Houchard blt .Lmemmove_bsrcul1loop4 4422357939bSOlivier Houchard sub r2, r2, #0x0c 4432357939bSOlivier Houchard stmdb sp!, {r4, r5, lr} 4442357939bSOlivier Houchard 4452357939bSOlivier Houchard.Lmemmove_bsrcul1loop32: 4462357939bSOlivier Houchard mov lr, r3, lsl #24 4472357939bSOlivier Houchard ldmdb r1!, {r3-r5, r12} 4482357939bSOlivier Houchard orr lr, lr, r12, lsr #8 4492357939bSOlivier Houchard mov r12, r12, lsl #24 4502357939bSOlivier Houchard orr r12, r12, r5, lsr #8 4512357939bSOlivier Houchard mov r5, r5, lsl #24 4522357939bSOlivier Houchard orr r5, r5, r4, lsr #8 4532357939bSOlivier Houchard mov r4, r4, lsl #24 4542357939bSOlivier Houchard orr r4, r4, r3, lsr #8 4552357939bSOlivier Houchard stmdb r0!, {r4, r5, r12, lr} 4562357939bSOlivier Houchard subs r2, r2, #0x10 4572357939bSOlivier Houchard bge .Lmemmove_bsrcul1loop32 4582357939bSOlivier Houchard ldmia sp!, {r4, r5, lr} 4592357939bSOlivier Houchard adds r2, r2, #0x0c 4602357939bSOlivier Houchard blt .Lmemmove_bsrcul1l4 4612357939bSOlivier Houchard 4622357939bSOlivier Houchard.Lmemmove_bsrcul1loop4: 4632357939bSOlivier Houchard mov r12, r3, lsl #24 4642357939bSOlivier Houchard ldr r3, [r1, #-4]! 4652357939bSOlivier Houchard orr r12, r12, r3, lsr #8 4662357939bSOlivier Houchard str r12, [r0, #-4]! 4672357939bSOlivier Houchard subs r2, r2, #4 4682357939bSOlivier Houchard bge .Lmemmove_bsrcul1loop4 4692357939bSOlivier Houchard 4702357939bSOlivier Houchard.Lmemmove_bsrcul1l4: 4712357939bSOlivier Houchard add r1, r1, #1 4722357939bSOlivier Houchard b .Lmemmove_bl4 473f2e71517SIan Lepore#ifndef _BCOPY 474f2e71517SIan LeporeEND(memmove) 475f2e71517SIan Lepore#else 476f2e71517SIan LeporeEND(bcopy) 477f2e71517SIan Lepore#endif 478*96cdb0abSKonstantin Belousov 479*96cdb0abSKonstantin Belousov .section .note.GNU-stack,"",%progbits 480