• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1! SPDX-License-Identifier: GPL-2.0
2!   Copyright (C) 2008-2012 Imagination Technologies Ltd.
3
4	.text
5	.global	_memmove
6	.type	_memmove,function
7! D1Ar1 dst
8! D0Ar2 src
9! D1Ar3 cnt
10! D0Re0 dst
11_memmove:
12	CMP 	D1Ar3, #0
13	MOV 	D0Re0, D1Ar1
14	BZ 	$LEND2
15	MSETL 	[A0StP], D0.5, D0.6, D0.7
16	MOV 	D1Ar5, D0Ar2
17	CMP 	D1Ar1, D1Ar5
18	BLT 	$Lforwards_copy
19	SUB 	D0Ar4, D1Ar1, D1Ar3
20	ADD 	D0Ar4, D0Ar4, #1
21	CMP 	D0Ar2, D0Ar4
22	BLT 	$Lforwards_copy
23	! should copy backwards
24	MOV 	D1Re0, D0Ar2
25	! adjust pointer to the end of mem
26	ADD 	D0Ar2, D1Re0, D1Ar3
27	ADD 	D1Ar1, D1Ar1, D1Ar3
28
29	MOV 	A1.2, D0Ar2
30	MOV 	A0.2, D1Ar1
31	CMP 	D1Ar3, #8
32	BLT 	$Lbbyte_loop
33
34	MOV 	D0Ar4, D0Ar2
35	MOV 	D1Ar5, D1Ar1
36
37	! test 8 byte alignment
38	ANDS 	D1Ar5, D1Ar5, #7
39	BNE 	$Lbdest_unaligned
40
41	ANDS 	D0Ar4, D0Ar4, #7
42	BNE 	$Lbsrc_unaligned
43
44	LSR 	D1Ar5, D1Ar3, #3
45
46$Lbaligned_loop:
47	GETL 	D0Re0, D1Re0, [--A1.2]
48	SETL 	[--A0.2], D0Re0, D1Re0
49	SUBS 	D1Ar5, D1Ar5, #1
50	BNE 	$Lbaligned_loop
51
52	ANDS 	D1Ar3, D1Ar3, #7
53	BZ 	$Lbbyte_loop_exit
54$Lbbyte_loop:
55	GETB 	D1Re0, [--A1.2]
56	SETB 	[--A0.2], D1Re0
57	SUBS 	D1Ar3, D1Ar3, #1
58	BNE 	$Lbbyte_loop
59$Lbbyte_loop_exit:
60	MOV 	D0Re0, A0.2
61$LEND:
62	SUB 	A0.2, A0StP, #24
63	MGETL 	D0.5, D0.6, D0.7, [A0.2]
64	SUB 	A0StP, A0StP, #24
65$LEND2:
66	MOV 	PC, D1RtP
67
68$Lbdest_unaligned:
69	GETB 	D0Re0, [--A1.2]
70	SETB 	[--A0.2], D0Re0
71	SUBS 	D1Ar5, D1Ar5, #1
72	SUB 	D1Ar3, D1Ar3, #1
73	BNE 	$Lbdest_unaligned
74	CMP 	D1Ar3, #8
75	BLT 	$Lbbyte_loop
76$Lbsrc_unaligned:
77	LSR 	D1Ar5, D1Ar3, #3
78	! adjust A1.2
79	MOV 	D0Ar4, A1.2
80	! save original address
81	MOV 	D0Ar6, A1.2
82
83	ADD 	D0Ar4, D0Ar4, #7
84	ANDMB 	D0Ar4, D0Ar4, #0xfff8
85	! new address is the 8-byte aligned one above the original
86	MOV 	A1.2, D0Ar4
87
88	! A0.2 dst 64-bit is aligned
89	! measure the gap size
90	SUB 	D0Ar6, D0Ar4, D0Ar6
91	MOVS 	D0Ar4, D0Ar6
92	! keep this information for the later adjustment
93	! both aligned
94	BZ 	$Lbaligned_loop
95
96	! prefetch
97	GETL 	D0Re0, D1Re0, [--A1.2]
98
99	CMP 	D0Ar6, #4
100	BLT 	$Lbunaligned_1_2_3
101	! 32-bit aligned
102	BZ 	$Lbaligned_4
103
104	SUB 	D0Ar6, D0Ar6, #4
105	! D1.6 stores the gap size in bits
106	MULW 	D1.6, D0Ar6, #8
107	MOV 	D0.6, #32
108	! D0.6 stores the complement of the gap size
109	SUB 	D0.6, D0.6, D1.6
110
111$Lbunaligned_5_6_7:
112	GETL 	D0.7, D1.7, [--A1.2]
113	! form 64-bit data in D0Re0, D1Re0
114	MOV 	D1Re0, D0Re0
115	! D1Re0 << gap-size
116	LSL 	D1Re0, D1Re0, D1.6
117	MOV 	D0Re0, D1.7
118	! D0Re0 >> complement
119	LSR 	D0Re0, D0Re0, D0.6
120	MOV 	D1.5, D0Re0
121	! combine the both
122	ADD 	D1Re0, D1Re0, D1.5
123
124	MOV 	D1.5, D1.7
125	LSL 	D1.5, D1.5, D1.6
126	MOV 	D0Re0, D0.7
127	LSR 	D0Re0, D0Re0, D0.6
128	MOV 	D0.5, D1.5
129	ADD 	D0Re0, D0Re0, D0.5
130
131	SETL 	[--A0.2], D0Re0, D1Re0
132	MOV 	D0Re0, D0.7
133	MOV 	D1Re0, D1.7
134	SUBS 	D1Ar5, D1Ar5, #1
135	BNE 	$Lbunaligned_5_6_7
136
137	ANDS 	D1Ar3, D1Ar3, #7
138	BZ 	$Lbbyte_loop_exit
139	! Adjust A1.2
140	! A1.2 <- A1.2 +8 - gapsize
141	ADD 	A1.2, A1.2, #8
142	SUB 	A1.2, A1.2, D0Ar4
143	B 	$Lbbyte_loop
144
145$Lbunaligned_1_2_3:
146	MULW 	D1.6, D0Ar6, #8
147	MOV 	D0.6, #32
148	SUB 	D0.6, D0.6, D1.6
149
150$Lbunaligned_1_2_3_loop:
151	GETL 	D0.7, D1.7, [--A1.2]
152	! form 64-bit data in D0Re0, D1Re0
153	LSL 	D1Re0, D1Re0, D1.6
154	! save D0Re0 for later use
155	MOV 	D0.5, D0Re0
156	LSR 	D0Re0, D0Re0, D0.6
157	MOV 	D1.5, D0Re0
158	ADD 	D1Re0, D1Re0, D1.5
159
160	! orignal data in D0Re0
161	MOV 	D1.5, D0.5
162	LSL 	D1.5, D1.5, D1.6
163	MOV 	D0Re0, D1.7
164	LSR 	D0Re0, D0Re0, D0.6
165	MOV 	D0.5, D1.5
166	ADD 	D0Re0, D0Re0, D0.5
167
168	SETL 	[--A0.2], D0Re0, D1Re0
169	MOV 	D0Re0, D0.7
170	MOV 	D1Re0, D1.7
171	SUBS 	D1Ar5, D1Ar5, #1
172	BNE 	$Lbunaligned_1_2_3_loop
173
174	ANDS 	D1Ar3, D1Ar3, #7
175	BZ 	$Lbbyte_loop_exit
176	! Adjust A1.2
177	ADD 	A1.2, A1.2, #8
178	SUB 	A1.2, A1.2, D0Ar4
179	B 	$Lbbyte_loop
180
181$Lbaligned_4:
182	GETL 	D0.7, D1.7, [--A1.2]
183	MOV 	D1Re0, D0Re0
184	MOV 	D0Re0, D1.7
185	SETL 	[--A0.2], D0Re0, D1Re0
186	MOV 	D0Re0, D0.7
187	MOV 	D1Re0, D1.7
188	SUBS 	D1Ar5, D1Ar5, #1
189	BNE 	$Lbaligned_4
190	ANDS 	D1Ar3, D1Ar3, #7
191	BZ 	$Lbbyte_loop_exit
192	! Adjust A1.2
193	ADD 	A1.2, A1.2, #8
194	SUB 	A1.2, A1.2, D0Ar4
195	B 	$Lbbyte_loop
196
197$Lforwards_copy:
198	MOV 	A1.2, D0Ar2
199	MOV 	A0.2, D1Ar1
200	CMP 	D1Ar3, #8
201	BLT 	$Lfbyte_loop
202
203	MOV 	D0Ar4, D0Ar2
204	MOV 	D1Ar5, D1Ar1
205
206	ANDS 	D1Ar5, D1Ar5, #7
207	BNE 	$Lfdest_unaligned
208
209	ANDS 	D0Ar4, D0Ar4, #7
210	BNE 	$Lfsrc_unaligned
211
212	LSR 	D1Ar5, D1Ar3, #3
213
214$Lfaligned_loop:
215	GETL 	D0Re0, D1Re0, [A1.2++]
216	SUBS 	D1Ar5, D1Ar5, #1
217	SETL 	[A0.2++], D0Re0, D1Re0
218	BNE 	$Lfaligned_loop
219
220	ANDS 	D1Ar3, D1Ar3, #7
221	BZ 	$Lfbyte_loop_exit
222$Lfbyte_loop:
223	GETB 	D1Re0, [A1.2++]
224	SETB 	[A0.2++], D1Re0
225	SUBS 	D1Ar3, D1Ar3, #1
226	BNE 	$Lfbyte_loop
227$Lfbyte_loop_exit:
228	MOV 	D0Re0, D1Ar1
229	B 	$LEND
230
231$Lfdest_unaligned:
232	GETB 	D0Re0, [A1.2++]
233	ADD 	D1Ar5, D1Ar5, #1
234	SUB 	D1Ar3, D1Ar3, #1
235	SETB 	[A0.2++], D0Re0
236	CMP 	D1Ar5, #8
237	BNE 	$Lfdest_unaligned
238	CMP 	D1Ar3, #8
239	BLT 	$Lfbyte_loop
240$Lfsrc_unaligned:
241	! adjust A1.2
242	LSR 	D1Ar5, D1Ar3, #3
243
244	MOV 	D0Ar4, A1.2
245	MOV 	D0Ar6, A1.2
246	ANDMB 	D0Ar4, D0Ar4, #0xfff8
247	MOV 	A1.2, D0Ar4
248
249	! A0.2 dst 64-bit is aligned
250	SUB 	D0Ar6, D0Ar6, D0Ar4
251	! keep the information for the later adjustment
252	MOVS 	D0Ar4, D0Ar6
253
254	! both aligned
255	BZ 	$Lfaligned_loop
256
257	! prefetch
258	GETL 	D0Re0, D1Re0, [A1.2]
259
260	CMP 	D0Ar6, #4
261	BLT 	$Lfunaligned_1_2_3
262	BZ 	$Lfaligned_4
263
264	SUB 	D0Ar6, D0Ar6, #4
265	MULW 	D0.6, D0Ar6, #8
266	MOV 	D1.6, #32
267	SUB 	D1.6, D1.6, D0.6
268
269$Lfunaligned_5_6_7:
270	GETL 	D0.7, D1.7, [++A1.2]
271	! form 64-bit data in D0Re0, D1Re0
272	MOV 	D0Re0, D1Re0
273	LSR 	D0Re0, D0Re0, D0.6
274	MOV 	D1Re0, D0.7
275	LSL 	D1Re0, D1Re0, D1.6
276	MOV 	D0.5, D1Re0
277	ADD 	D0Re0, D0Re0, D0.5
278
279	MOV 	D0.5, D0.7
280	LSR 	D0.5, D0.5, D0.6
281	MOV 	D1Re0, D1.7
282	LSL 	D1Re0, D1Re0, D1.6
283	MOV 	D1.5, D0.5
284	ADD 	D1Re0, D1Re0, D1.5
285
286	SETL 	[A0.2++], D0Re0, D1Re0
287	MOV 	D0Re0, D0.7
288	MOV 	D1Re0, D1.7
289	SUBS 	D1Ar5, D1Ar5, #1
290	BNE 	$Lfunaligned_5_6_7
291
292	ANDS 	D1Ar3, D1Ar3, #7
293	BZ 	$Lfbyte_loop_exit
294	! Adjust A1.2
295	ADD	A1.2, A1.2, D0Ar4
296	B 	$Lfbyte_loop
297
298$Lfunaligned_1_2_3:
299	MULW 	D0.6, D0Ar6, #8
300	MOV 	D1.6, #32
301	SUB 	D1.6, D1.6, D0.6
302
303$Lfunaligned_1_2_3_loop:
304	GETL 	D0.7, D1.7, [++A1.2]
305	! form 64-bit data in D0Re0, D1Re0
306	LSR 	D0Re0, D0Re0, D0.6
307	MOV 	D1.5, D1Re0
308	LSL 	D1Re0, D1Re0, D1.6
309	MOV 	D0.5, D1Re0
310	ADD 	D0Re0, D0Re0, D0.5
311
312	MOV 	D0.5, D1.5
313	LSR 	D0.5, D0.5, D0.6
314	MOV 	D1Re0, D0.7
315	LSL 	D1Re0, D1Re0, D1.6
316	MOV 	D1.5, D0.5
317	ADD 	D1Re0, D1Re0, D1.5
318
319	SETL 	[A0.2++], D0Re0, D1Re0
320	MOV 	D0Re0, D0.7
321	MOV 	D1Re0, D1.7
322	SUBS 	D1Ar5, D1Ar5, #1
323	BNE 	$Lfunaligned_1_2_3_loop
324
325	ANDS 	D1Ar3, D1Ar3, #7
326	BZ 	$Lfbyte_loop_exit
327	! Adjust A1.2
328	ADD	A1.2, A1.2, D0Ar4
329	B 	$Lfbyte_loop
330
331$Lfaligned_4:
332	GETL 	D0.7, D1.7, [++A1.2]
333	MOV 	D0Re0, D1Re0
334	MOV 	D1Re0, D0.7
335	SETL 	[A0.2++], D0Re0, D1Re0
336	MOV 	D0Re0, D0.7
337	MOV 	D1Re0, D1.7
338	SUBS 	D1Ar5, D1Ar5, #1
339	BNE 	$Lfaligned_4
340	ANDS 	D1Ar3, D1Ar3, #7
341	BZ 	$Lfbyte_loop_exit
342	! Adjust A1.2
343	ADD	A1.2, A1.2, D0Ar4
344	B 	$Lfbyte_loop
345
346	.size _memmove,.-_memmove
347