xref: /linux/arch/sh/lib/memmove.S (revision ca55b2fef3a9373fcfc30f82fd26bc7fccbda732)
1/* $Id: memmove.S,v 1.2 2001/07/27 11:51:09 gniibe Exp $
2 *
3 * "memmove" implementation of SuperH
4 *
5 * Copyright (C) 1999  Niibe Yutaka
6 *
7 */
8
9/*
10 * void *memmove(void *dst, const void *src, size_t n);
11 * The memory areas may overlap.
12 */
13
14#include <linux/linkage.h>
15ENTRY(memmove)
16	! if dest > src, call memcpy (it copies in decreasing order)
17	cmp/hi	r5,r4
18	bf	1f
19	mov.l	2f,r0
20	jmp	@r0
21	 nop
22	.balign 4
232:	.long	memcpy
241:
25	sub	r5,r4		! From here, r4 has the distance to r0
26	tst	r6,r6
27	bt/s	9f		! if n=0, do nothing
28	 mov	r5,r0
29	add	r6,r5
30	mov	#12,r1
31	cmp/gt	r6,r1
32	bt/s	8f		! if it's too small, copy a byte at once
33	 add	#-1,r4
34	add	#1,r4
35	!
36	!                [ ...  ] DST             [ ...  ] SRC
37	!	         [ ...  ]                 [ ...  ]
38	!	           :                        :
39	!      r0+r4-->  [ ...  ]       r0    --> [ ...  ]
40	!	           :                        :
41	!	         [ ...  ]                 [ ...  ]
42	!			        r5    -->
43	!
44	mov	r4,r1
45	mov	#3,r2
46	and	r2,r1
47	shll2	r1
48	mov	r0,r3		! Save the value on R0 to R3
49	mova	jmptable,r0
50	add	r1,r0
51	mov.l	@r0,r1
52	jmp	@r1
53	 mov	r3,r0		! and back to R0
54	.balign	4
55jmptable:
56	.long	case0
57	.long	case1
58	.long	case2
59	.long	case3
60
61	! copy a byte at once
628:	mov.b	@r0+,r1
63	cmp/hs	r5,r0
64	bf/s	8b			! while (r0<r5)
65	 mov.b	r1,@(r0,r4)
66	add	#1,r4
679:
68	add	r4,r0
69	rts
70	 sub	r6,r0
71
72case_none:
73	bra	8b
74	 add	#-1,r4
75
76case0:
77	!
78	!	GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
79	!
80	! First, align to long word boundary
81	mov	r0,r3
82	and	r2,r3
83	tst	r3,r3
84	bt/s	2f
85	 add	#-1,r4
86	mov	#4,r2
87	sub	r3,r2
881:	dt	r2
89	mov.b	@r0+,r1
90	bf/s	1b
91	 mov.b	r1,@(r0,r4)
92	!
932:	! Second, copy a long word at once
94	add	#-3,r4
95	add	#-3,r5
963:	mov.l	@r0+,r1
97	cmp/hs	r5,r0
98	bf/s	3b
99	 mov.l	r1,@(r0,r4)
100	add	#3,r5
101	!
102	! Third, copy a byte at once, if necessary
103	cmp/eq	r5,r0
104	bt/s	9b
105	 add	#4,r4
106	bra	8b
107	 add	#-1,r4
108
109case3:
110	!
111	!	GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
112	!
113	! First, align to long word boundary
114	mov	r0,r3
115	and	r2,r3
116	tst	r3,r3
117	bt/s	2f
118	 add	#-1,r4
119	mov	#4,r2
120	sub	r3,r2
1211:	dt	r2
122	mov.b	@r0+,r1
123	bf/s	1b
124	 mov.b	r1,@(r0,r4)
125	!
1262:	! Second, read a long word and write a long word at once
127	add	#-2,r4
128	mov.l	@(r0,r4),r1
129	add	#-7,r5
130	add	#-4,r4
131	!
132#ifdef __LITTLE_ENDIAN__
133	shll8	r1
1343:	mov	r1,r3		! JIHG
135	shlr8	r3		! xJIH
136	mov.l	@r0+,r1		! NMLK
137	mov	r1,r2
138	shll16	r2
139	shll8	r2		! Kxxx
140	or	r2,r3		! KJIH
141	cmp/hs	r5,r0
142	bf/s	3b
143	 mov.l	r3,@(r0,r4)
144#else
145	shlr8	r1
1463:	mov	r1,r3		! GHIJ
147	shll8	r3		! HIJx
148	mov.l	@r0+,r1		! KLMN
149	mov	r1,r2
150	shlr16	r2
151	shlr8	r2		! xxxK
152	or	r2,r3		! HIJK
153	cmp/hs	r5,r0
154	bf/s	3b
155	 mov.l	r3,@(r0,r4)
156#endif
157	add	#7,r5
158	!
159	! Third, copy a byte at once, if necessary
160	cmp/eq	r5,r0
161	bt/s	9b
162	 add	#7,r4
163	add	#-3,r0
164	bra	8b
165	 add	#-1,r4
166
167case2:
168	!
169	!	GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
170	!
171	! First, align to word boundary
172	tst	#1,r0
173	bt/s	2f
174	 add	#-1,r4
175	mov.b	@r0+,r1
176	mov.b	r1,@(r0,r4)
177	!
1782:	! Second, read a word and write a word at once
179	add	#-1,r4
180	add	#-1,r5
181	!
1823:	mov.w	@r0+,r1
183	cmp/hs	r5,r0
184	bf/s	3b
185	 mov.w	r1,@(r0,r4)
186	add	#1,r5
187	!
188	! Third, copy a byte at once, if necessary
189	cmp/eq	r5,r0
190	bt/s	9b
191	 add	#2,r4
192	mov.b	@r0,r1
193	mov.b	r1,@(r0,r4)
194	bra	9b
195	 add	#1,r0
196
197case1:
198	!
199	!	GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
200	!
201	! First, align to long word boundary
202	mov	r0,r3
203	and	r2,r3
204	tst	r3,r3
205	bt/s	2f
206	 add	#-1,r4
207	mov	#4,r2
208	sub	r3,r2
2091:	dt	r2
210	mov.b	@r0+,r1
211	bf/s	1b
212	 mov.b	r1,@(r0,r4)
213	!
2142:	! Second, read a long word and write a long word at once
215	mov.l	@(r0,r4),r1
216	add	#-7,r5
217	add	#-4,r4
218	!
219#ifdef __LITTLE_ENDIAN__
220	shll16	r1
221	shll8	r1
2223:	mov	r1,r3		! JIHG
223	shlr16	r3
224	shlr8	r3		! xxxJ
225	mov.l	@r0+,r1		! NMLK
226	mov	r1,r2
227	shll8	r2		! MLKx
228	or	r2,r3		! MLKJ
229	cmp/hs	r5,r0
230	bf/s	3b
231	 mov.l	r3,@(r0,r4)
232#else
233	shlr16	r1
234	shlr8	r1
2353:	mov	r1,r3		! GHIJ
236	shll16	r3
237	shll8	r3		! Jxxx
238	mov.l	@r0+,r1		! KLMN
239	mov	r1,r2
240	shlr8	r2		! xKLM
241	or	r2,r3		! JKLM
242	cmp/hs	r5,r0
243	bf/s	3b		! while(r0<r5)
244	 mov.l	r3,@(r0,r4)
245#endif
246	add	#7,r5
247	!
248	! Third, copy a byte at once, if necessary
249	cmp/eq	r5,r0
250	bt/s	9b
251	 add	#5,r4
252	add	#-3,r0
253	bra	8b
254	 add	#-1,r4
255