1/* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
2 *
3 * "memcpy" implementation of SuperH
4 *
5 * Copyright (C) 1999  Niibe Yutaka
6 *
7 */
8
9/*
10 * void *memcpy(void *dst, const void *src, size_t n);
11 * No overlap between the memory of DST and of SRC are assumed.
12 */
13
14#include <linux/linkage.h>
15ENTRY(memcpy)
16	tst	r6,r6
17	bt/s	9f		! if n=0, do nothing
18	 mov	r4,r0
19	sub	r4,r5		! From here, r5 has the distance to r0
20	add	r6,r0		! From here, r0 points the end of copying point
21	mov	#12,r1
22	cmp/gt	r6,r1
23	bt/s	7f		! if it's too small, copy a byte at once
24	 add	#-1,r5
25	add	#1,r5
26	!			From here, r6 is free
27	!
28	!      r4   -->  [ ...  ] DST             [ ...  ] SRC
29	!	         [ ...  ]                 [ ...  ]
30	!	           :                        :
31	!      r0   -->  [ ...  ]       r0+r5 --> [ ...  ]
32	!
33	!
34	mov	r5,r1
35	mov	#3,r2
36	and	r2,r1
37	shll2	r1
38	mov	r0,r3		! Save the value on R0 to R3
39	mova	jmptable,r0
40	add	r1,r0
41	mov.l	@r0,r1
42	jmp	@r1
43	 mov	r3,r0		! and back to R0
44	.balign	4
45jmptable:
46	.long	case0
47	.long	case1
48	.long	case2
49	.long	case3
50
51	! copy a byte at once
527:	mov	r4,r2
53	add	#1,r2
548:
55	cmp/hi	r2,r0
56	mov.b	@(r0,r5),r1
57	bt/s	8b			! while (r0>r2)
58	 mov.b	r1,@-r0
599:
60	rts
61	 nop
62
63case0:
64	!
65	!	GHIJ KLMN OPQR -->  GHIJ KLMN OPQR
66	!
67	! First, align to long word boundary
68	mov	r0,r3
69	and	r2,r3
70	tst	r3,r3
71	bt/s	2f
72	 add	#-4,r5
73	add	#3,r5
741:	dt	r3
75	mov.b	@(r0,r5),r1
76	bf/s	1b
77	 mov.b	r1,@-r0
78	!
79	add	#-3,r5
802:	! Second, copy a long word at once
81	mov	r4,r2
82	add	#7,r2
833:	mov.l	@(r0,r5),r1
84	cmp/hi	r2,r0
85	bt/s	3b
86	 mov.l	r1,@-r0
87	!
88	! Third, copy a byte at once, if necessary
89	cmp/eq	r4,r0
90	bt/s	9b
91	 add	#3,r5
92	bra	8b
93	 add	#-6,r2
94
95case1:
96	!
97	!	GHIJ KLMN OPQR -->  ...G HIJK LMNO PQR.
98	!
99	! First, align to long word boundary
100	mov	r0,r3
101	and	r2,r3
102	tst	r3,r3
103	bt/s	2f
104	 add	#-1,r5
1051:	dt	r3
106	mov.b	@(r0,r5),r1
107	bf/s	1b
108	 mov.b	r1,@-r0
109	!
1102:	! Second, read a long word and write a long word at once
111	mov.l	@(r0,r5),r1
112	add	#-4,r5
113	mov	r4,r2
114	add	#7,r2
115	!
116#ifdef __LITTLE_ENDIAN__
1173:	mov	r1,r3		! RQPO
118	shll16	r3
119	shll8	r3		! Oxxx
120	mov.l	@(r0,r5),r1	! NMLK
121	mov	r1,r6
122	shlr8	r6		! xNML
123	or	r6,r3		! ONML
124	cmp/hi	r2,r0
125	bt/s	3b
126	 mov.l	r3,@-r0
127#else
1283:	mov	r1,r3		! OPQR
129	shlr16	r3
130	shlr8	r3		! xxxO
131	mov.l	@(r0,r5),r1	! KLMN
132	mov	r1,r6
133	shll8	r6		! LMNx
134	or	r6,r3		! LMNO
135	cmp/hi	r2,r0
136	bt/s	3b
137	 mov.l	r3,@-r0
138#endif
139	!
140	! Third, copy a byte at once, if necessary
141	cmp/eq	r4,r0
142	bt/s	9b
143	 add	#4,r5
144	bra	8b
145	 add	#-6,r2
146
147case2:
148	!
149	!	GHIJ KLMN OPQR -->  ..GH IJKL MNOP QR..
150	!
151	! First, align to word boundary
152	tst	#1,r0
153	bt/s	2f
154	 add	#-1,r5
155	mov.b	@(r0,r5),r1
156	mov.b	r1,@-r0
157	!
1582:	! Second, read a word and write a word at once
159	add	#-1,r5
160	mov	r4,r2
161	add	#3,r2
162	!
1633:	mov.w	@(r0,r5),r1
164	cmp/hi	r2,r0
165	bt/s	3b
166	 mov.w	r1,@-r0
167	!
168	! Third, copy a byte at once, if necessary
169	cmp/eq	r4,r0
170	bt/s	9b
171	 add	#1,r5
172	mov.b	@(r0,r5),r1
173	rts
174	 mov.b	r1,@-r0
175
176case3:
177	!
178	!	GHIJ KLMN OPQR -->  .GHI JKLM NOPQ R...
179	!
180	! First, align to long word boundary
181	mov	r0,r3
182	and	r2,r3
183	tst	r3,r3
184	bt/s	2f
185	 add	#-1,r5
1861:	dt	r3
187	mov.b	@(r0,r5),r1
188	bf/s	1b
189	 mov.b	r1,@-r0
190	!
1912:	! Second, read a long word and write a long word at once
192	add	#-2,r5
193	mov.l	@(r0,r5),r1
194	add	#-4,r5
195	mov	r4,r2
196	add	#7,r2
197	!
198#ifdef __LITTLE_ENDIAN__
1993:	mov	r1,r3		! RQPO
200	shll8	r3		! QPOx
201	mov.l	@(r0,r5),r1	! NMLK
202	mov	r1,r6
203	shlr16	r6
204	shlr8	r6		! xxxN
205	or	r6,r3		! QPON
206	cmp/hi	r2,r0
207	bt/s	3b
208	 mov.l	r3,@-r0
209#else
2103:	mov	r1,r3		! OPQR
211	shlr8	r3		! xOPQ
212	mov.l	@(r0,r5),r1	! KLMN
213	mov	r1,r6
214	shll16	r6
215	shll8	r6		! Nxxx
216	or	r6,r3		! NOPQ
217	cmp/hi	r2,r0
218	bt/s	3b
219	 mov.l	r3,@-r0
220#endif
221	!
222	! Third, copy a byte at once, if necessary
223	cmp/eq	r4,r0
224	bt/s	9b
225	 add	#6,r5
226	bra	8b
227	 add	#-6,r2
228