1/*
2 * Copyright (C) 2004-2007 Atmel Corporation
3 *
4 * This file is subject to the terms and conditions of the GNU Lesser General
5 * Public License.  See the file "COPYING.LIB" in the main directory of this
6 * archive for more details.
7 */
8
9#define dst r12
10#define src r11
11#define len r10
12
13	.text
14	.global memmove
15	.type	memmove, @function
16memmove:
17	cp.w	src, dst
18	brge	HIDDEN_JUMPTARGET(memcpy)
19
20	add	dst, len
21	add	src, len
22	pref	src[-1]
23
24	/*
25	 * The rest is basically the same as in memcpy.S except that
26	 * the direction is reversed.
27	 */
28	cp.w	len, 32
29	brge	.Lmore_than_31
30
31	sub	len, 1
32	retlt	r12
331:	ld.ub	r8, --src
34	st.b	--dst, r8
35	sub	len, 1
36	brge	1b
37	retal	r12
38
39.Lmore_than_31:
40	pushm	r0-r7, lr
41
42	/* Check alignment */
43	mov	r8, src
44	andl	r8, 31, COH
45	brne	.Lunaligned_src
46	mov	r8, r12
47	andl	r8, 3, COH
48	brne	.Lunaligned_dst
49
50.Laligned_copy:
51	sub	len, 32
52	brlt	.Lless_than_32
53
541:	/* Copy 32 bytes at a time */
55	sub	src, 32
56	ldm	src, r0-r7
57	sub	dst, 32
58	sub	len, 32
59	stm	dst, r0-r7
60	brge	1b
61
62.Lless_than_32:
63	/* Copy 16 more bytes if possible */
64	sub	len, -16
65	brlt	.Lless_than_16
66	sub	src, 16
67	ldm	src, r0-r3
68	sub	dst, 16
69	sub	len, 16
70	stm	dst, r0-r3
71
72.Lless_than_16:
73	/* Do the remaining as byte copies */
74	sub	len, -16
75	breq	2f
761:	ld.ub	r0, --src
77	st.b	--dst, r0
78	sub	len, 1
79	brne	1b
80
812:	popm	r0-r7, pc
82
83.Lunaligned_src:
84	/* Make src cacheline-aligned. r8 = (src & 31) */
85	sub	len, r8
861:	ld.ub	r0, --src
87	st.b	--dst, r0
88	sub	r8, 1
89	brne	1b
90
91	/* If dst is word-aligned, we're ready to go */
92	pref	src[-4]
93	mov	r8, 3
94	tst	dst, r8
95	breq	.Laligned_copy
96
97.Lunaligned_dst:
98	/* src is aligned, but dst is not. Expect bad performance */
99	sub	len, 4
100	brlt	2f
1011:	ld.w	r0, --src
102	st.w	--dst, r0
103	sub	len, 4
104	brge	1b
105
1062:	neg	len
107	add	pc, pc, len << 2
108	.rept	3
109	ld.ub	r0, --src
110	st.b	--dst, r0
111	.endr
112
113	popm	r0-r7, pc
114	.size	memmove, . - memmove
115
116libc_hidden_def(memmove)
117