xref: /freebsd/lib/libc/arm/string/memmove.S (revision 1d386b48a555f61cb7325543adbbb5c3f3407a66)
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