xref: /openbmc/linux/arch/hexagon/lib/memset.S (revision 75bf465f0bc33e9b776a46d6a1b9b990f5fb7c37)
1*08dbd0f8SThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-only */
2c150290dSRichard Kuo/*
3e1858b2aSRichard Kuo * Copyright (c) 2011, The Linux Foundation. All rights reserved.
4c150290dSRichard Kuo */
5c150290dSRichard Kuo
6c150290dSRichard Kuo
7c150290dSRichard Kuo/* HEXAGON assembly optimized memset */
8c150290dSRichard Kuo/* Replaces the standard library function memset */
9c150290dSRichard Kuo
10c150290dSRichard Kuo
11c150290dSRichard Kuo        .macro HEXAGON_OPT_FUNC_BEGIN name
12c150290dSRichard Kuo	.text
13c150290dSRichard Kuo	.p2align 4
14c150290dSRichard Kuo	.globl \name
15c150290dSRichard Kuo	.type  \name, @function
16c150290dSRichard Kuo\name:
17c150290dSRichard Kuo	.endm
18c150290dSRichard Kuo
19c150290dSRichard Kuo	.macro HEXAGON_OPT_FUNC_FINISH name
20c150290dSRichard Kuo	.size  \name, . - \name
21c150290dSRichard Kuo	.endm
22c150290dSRichard Kuo
23c150290dSRichard Kuo/* FUNCTION: memset (v2 version) */
24c150290dSRichard Kuo#if __HEXAGON_ARCH__ < 3
25c150290dSRichard KuoHEXAGON_OPT_FUNC_BEGIN memset
26c150290dSRichard Kuo	{
27c150290dSRichard Kuo		r6 = #8
28c150290dSRichard Kuo		r7 = extractu(r0, #3 , #0)
29c150290dSRichard Kuo		p0 = cmp.eq(r2, #0)
30c150290dSRichard Kuo		p1 = cmp.gtu(r2, #7)
31c150290dSRichard Kuo	}
32c150290dSRichard Kuo	{
33c150290dSRichard Kuo		r4 = vsplatb(r1)
34c150290dSRichard Kuo		r8 = r0           /* leave r0 intact for return val  */
35c150290dSRichard Kuo		r9 = sub(r6, r7)  /* bytes until double alignment  */
36c150290dSRichard Kuo		if p0 jumpr r31   /* count == 0, so return  */
37c150290dSRichard Kuo	}
38c150290dSRichard Kuo	{
39c150290dSRichard Kuo		r3 = #0
40c150290dSRichard Kuo		r7 = #0
41c150290dSRichard Kuo		p0 = tstbit(r9, #0)
42c150290dSRichard Kuo		if p1 jump 2f /* skip byte loop */
43c150290dSRichard Kuo	}
44c150290dSRichard Kuo
45c150290dSRichard Kuo/* less than 8 bytes to set, so just set a byte at a time and return  */
46c150290dSRichard Kuo
47c150290dSRichard Kuo		loop0(1f, r2) /* byte loop */
48c150290dSRichard Kuo	.falign
49c150290dSRichard Kuo1: /* byte loop */
50c150290dSRichard Kuo	{
51c150290dSRichard Kuo		memb(r8++#1) = r4
52c150290dSRichard Kuo	}:endloop0
53c150290dSRichard Kuo		jumpr r31
54c150290dSRichard Kuo	.falign
55c150290dSRichard Kuo2: /* skip byte loop */
56c150290dSRichard Kuo	{
57c150290dSRichard Kuo		r6 = #1
58c150290dSRichard Kuo		p0 = tstbit(r9, #1)
59c150290dSRichard Kuo		p1 = cmp.eq(r2, #1)
60c150290dSRichard Kuo		if !p0 jump 3f /* skip initial byte store */
61c150290dSRichard Kuo	}
62c150290dSRichard Kuo	{
63c150290dSRichard Kuo		memb(r8++#1) = r4
64c150290dSRichard Kuo		r3:2 = sub(r3:2, r7:6)
65c150290dSRichard Kuo		if p1 jumpr r31
66c150290dSRichard Kuo	}
67c150290dSRichard Kuo	.falign
68c150290dSRichard Kuo3: /* skip initial byte store */
69c150290dSRichard Kuo	{
70c150290dSRichard Kuo		r6 = #2
71c150290dSRichard Kuo		p0 = tstbit(r9, #2)
72c150290dSRichard Kuo		p1 = cmp.eq(r2, #2)
73c150290dSRichard Kuo		if !p0 jump 4f /* skip initial half store */
74c150290dSRichard Kuo	}
75c150290dSRichard Kuo	{
76c150290dSRichard Kuo		memh(r8++#2) = r4
77c150290dSRichard Kuo		r3:2 = sub(r3:2, r7:6)
78c150290dSRichard Kuo		if p1 jumpr r31
79c150290dSRichard Kuo	}
80c150290dSRichard Kuo	.falign
81c150290dSRichard Kuo4: /* skip initial half store */
82c150290dSRichard Kuo	{
83c150290dSRichard Kuo		r6 = #4
84c150290dSRichard Kuo		p0 = cmp.gtu(r2, #7)
85c150290dSRichard Kuo		p1 = cmp.eq(r2, #4)
86c150290dSRichard Kuo		if !p0 jump 5f /* skip initial word store */
87c150290dSRichard Kuo	}
88c150290dSRichard Kuo	{
89c150290dSRichard Kuo		memw(r8++#4) = r4
90c150290dSRichard Kuo		r3:2 = sub(r3:2, r7:6)
91c150290dSRichard Kuo		p0 = cmp.gtu(r2, #11)
92c150290dSRichard Kuo		if p1 jumpr r31
93c150290dSRichard Kuo	}
94c150290dSRichard Kuo	.falign
95c150290dSRichard Kuo5: /* skip initial word store */
96c150290dSRichard Kuo	{
97c150290dSRichard Kuo		r10 = lsr(r2, #3)
98c150290dSRichard Kuo		p1 = cmp.eq(r3, #1)
99c150290dSRichard Kuo		if !p0 jump 7f /* skip double loop */
100c150290dSRichard Kuo	}
101c150290dSRichard Kuo	{
102c150290dSRichard Kuo		r5 = r4
103c150290dSRichard Kuo		r6 = #8
104c150290dSRichard Kuo		loop0(6f, r10) /* double loop */
105c150290dSRichard Kuo	}
106c150290dSRichard Kuo
107c150290dSRichard Kuo/* set bytes a double word at a time  */
108c150290dSRichard Kuo
109c150290dSRichard Kuo	.falign
110c150290dSRichard Kuo6: /* double loop */
111c150290dSRichard Kuo	{
112c150290dSRichard Kuo		memd(r8++#8) = r5:4
113c150290dSRichard Kuo		r3:2 = sub(r3:2, r7:6)
114c150290dSRichard Kuo		p1 = cmp.eq(r2, #8)
115c150290dSRichard Kuo	}:endloop0
116c150290dSRichard Kuo	.falign
117c150290dSRichard Kuo7: /* skip double loop */
118c150290dSRichard Kuo	{
119c150290dSRichard Kuo		p0 = tstbit(r2, #2)
120c150290dSRichard Kuo		if p1 jumpr r31
121c150290dSRichard Kuo	}
122c150290dSRichard Kuo	{
123c150290dSRichard Kuo		r6 = #4
124c150290dSRichard Kuo		p0 = tstbit(r2, #1)
125c150290dSRichard Kuo		p1 = cmp.eq(r2, #4)
126c150290dSRichard Kuo		if !p0 jump 8f /* skip final word store */
127c150290dSRichard Kuo	}
128c150290dSRichard Kuo	{
129c150290dSRichard Kuo		memw(r8++#4) = r4
130c150290dSRichard Kuo		r3:2 = sub(r3:2, r7:6)
131c150290dSRichard Kuo		if p1 jumpr r31
132c150290dSRichard Kuo	}
133c150290dSRichard Kuo	.falign
134c150290dSRichard Kuo8: /* skip final word store */
135c150290dSRichard Kuo	{
136c150290dSRichard Kuo		p1 = cmp.eq(r2, #2)
137c150290dSRichard Kuo		if !p0 jump 9f /* skip final half store */
138c150290dSRichard Kuo	}
139c150290dSRichard Kuo	{
140c150290dSRichard Kuo		memh(r8++#2) = r4
141c150290dSRichard Kuo		if p1 jumpr r31
142c150290dSRichard Kuo	}
143c150290dSRichard Kuo	.falign
144c150290dSRichard Kuo9: /* skip final half store */
145c150290dSRichard Kuo	{
146c150290dSRichard Kuo		memb(r8++#1) = r4
147c150290dSRichard Kuo		jumpr r31
148c150290dSRichard Kuo	}
149c150290dSRichard KuoHEXAGON_OPT_FUNC_FINISH memset
150c150290dSRichard Kuo#endif
151c150290dSRichard Kuo
152c150290dSRichard Kuo
153c150290dSRichard Kuo/*  FUNCTION: memset (v3 and higher version)  */
154c150290dSRichard Kuo#if __HEXAGON_ARCH__ >= 3
155c150290dSRichard KuoHEXAGON_OPT_FUNC_BEGIN memset
156c150290dSRichard Kuo	{
157c150290dSRichard Kuo		r7=vsplatb(r1)
158c150290dSRichard Kuo		r6 = r0
159c150290dSRichard Kuo		if (r2==#0) jump:nt .L1
160c150290dSRichard Kuo	}
161c150290dSRichard Kuo	{
162c150290dSRichard Kuo		r5:4=combine(r7,r7)
163c150290dSRichard Kuo		p0 = cmp.gtu(r2,#8)
164c150290dSRichard Kuo		if (p0.new) jump:nt .L3
165c150290dSRichard Kuo	}
166c150290dSRichard Kuo	{
167c150290dSRichard Kuo		r3 = r0
168c150290dSRichard Kuo		loop0(.L47,r2)
169c150290dSRichard Kuo	}
170c150290dSRichard Kuo	.falign
171c150290dSRichard Kuo.L47:
172c150290dSRichard Kuo	{
173c150290dSRichard Kuo		memb(r3++#1) = r1
174c150290dSRichard Kuo	}:endloop0 /* start=.L47 */
175c150290dSRichard Kuo		jumpr r31
176c150290dSRichard Kuo.L3:
177c150290dSRichard Kuo	{
178c150290dSRichard Kuo		p0 = tstbit(r0,#0)
179c150290dSRichard Kuo		if (!p0.new) jump:nt .L8
180c150290dSRichard Kuo		p1 = cmp.eq(r2, #1)
181c150290dSRichard Kuo	}
182c150290dSRichard Kuo	{
183c150290dSRichard Kuo		r6 = add(r0, #1)
184c150290dSRichard Kuo		r2 = add(r2,#-1)
185c150290dSRichard Kuo		memb(r0) = r1
186c150290dSRichard Kuo		if (p1) jump .L1
187c150290dSRichard Kuo	}
188c150290dSRichard Kuo.L8:
189c150290dSRichard Kuo	{
190c150290dSRichard Kuo		p0 = tstbit(r6,#1)
191c150290dSRichard Kuo		if (!p0.new) jump:nt .L10
192c150290dSRichard Kuo	}
193c150290dSRichard Kuo	{
194c150290dSRichard Kuo		r2 = add(r2,#-2)
195c150290dSRichard Kuo		memh(r6++#2) = r7
196c150290dSRichard Kuo		p0 = cmp.eq(r2, #2)
197c150290dSRichard Kuo		if (p0.new) jump:nt .L1
198c150290dSRichard Kuo	}
199c150290dSRichard Kuo.L10:
200c150290dSRichard Kuo	{
201c150290dSRichard Kuo		p0 = tstbit(r6,#2)
202c150290dSRichard Kuo		if (!p0.new) jump:nt .L12
203c150290dSRichard Kuo	}
204c150290dSRichard Kuo	{
205c150290dSRichard Kuo		r2 = add(r2,#-4)
206c150290dSRichard Kuo		memw(r6++#4) = r7
207c150290dSRichard Kuo		p0 = cmp.eq(r2, #4)
208c150290dSRichard Kuo		if (p0.new) jump:nt .L1
209c150290dSRichard Kuo	}
210c150290dSRichard Kuo.L12:
211c150290dSRichard Kuo	{
212c150290dSRichard Kuo		p0 = cmp.gtu(r2,#127)
213c150290dSRichard Kuo		if (!p0.new) jump:nt .L14
214c150290dSRichard Kuo	}
215c150290dSRichard Kuo		r3 = and(r6,#31)
216c150290dSRichard Kuo		if (r3==#0) jump:nt .L17
217c150290dSRichard Kuo	{
218c150290dSRichard Kuo		memd(r6++#8) = r5:4
219c150290dSRichard Kuo		r2 = add(r2,#-8)
220c150290dSRichard Kuo	}
221c150290dSRichard Kuo		r3 = and(r6,#31)
222c150290dSRichard Kuo		if (r3==#0) jump:nt .L17
223c150290dSRichard Kuo	{
224c150290dSRichard Kuo		memd(r6++#8) = r5:4
225c150290dSRichard Kuo		r2 = add(r2,#-8)
226c150290dSRichard Kuo	}
227c150290dSRichard Kuo		r3 = and(r6,#31)
228c150290dSRichard Kuo		if (r3==#0) jump:nt .L17
229c150290dSRichard Kuo	{
230c150290dSRichard Kuo		memd(r6++#8) = r5:4
231c150290dSRichard Kuo		r2 = add(r2,#-8)
232c150290dSRichard Kuo	}
233c150290dSRichard Kuo.L17:
234c150290dSRichard Kuo	{
235c150290dSRichard Kuo		r3 = lsr(r2,#5)
236c150290dSRichard Kuo		if (r1!=#0) jump:nt .L18
237c150290dSRichard Kuo	}
238c150290dSRichard Kuo	{
239c150290dSRichard Kuo		r8 = r3
240c150290dSRichard Kuo		r3 = r6
241c150290dSRichard Kuo		loop0(.L46,r3)
242c150290dSRichard Kuo	}
243c150290dSRichard Kuo	.falign
244c150290dSRichard Kuo.L46:
245c150290dSRichard Kuo	{
246c150290dSRichard Kuo		dczeroa(r6)
247c150290dSRichard Kuo		r6 = add(r6,#32)
248c150290dSRichard Kuo		r2 = add(r2,#-32)
249c150290dSRichard Kuo	}:endloop0 /* start=.L46 */
250c150290dSRichard Kuo.L14:
251c150290dSRichard Kuo	{
252c150290dSRichard Kuo		p0 = cmp.gtu(r2,#7)
253c150290dSRichard Kuo		if (!p0.new) jump:nt .L28
254c150290dSRichard Kuo		r8 = lsr(r2,#3)
255c150290dSRichard Kuo	}
256c150290dSRichard Kuo		loop0(.L44,r8)
257c150290dSRichard Kuo	.falign
258c150290dSRichard Kuo.L44:
259c150290dSRichard Kuo	{
260c150290dSRichard Kuo		memd(r6++#8) = r5:4
261c150290dSRichard Kuo		r2 = add(r2,#-8)
262c150290dSRichard Kuo	}:endloop0 /* start=.L44 */
263c150290dSRichard Kuo.L28:
264c150290dSRichard Kuo	{
265c150290dSRichard Kuo		p0 = tstbit(r2,#2)
266c150290dSRichard Kuo		if (!p0.new) jump:nt .L33
267c150290dSRichard Kuo	}
268c150290dSRichard Kuo	{
269c150290dSRichard Kuo		r2 = add(r2,#-4)
270c150290dSRichard Kuo		memw(r6++#4) = r7
271c150290dSRichard Kuo	}
272c150290dSRichard Kuo.L33:
273c150290dSRichard Kuo	{
274c150290dSRichard Kuo		p0 = tstbit(r2,#1)
275c150290dSRichard Kuo		if (!p0.new) jump:nt .L35
276c150290dSRichard Kuo	}
277c150290dSRichard Kuo	{
278c150290dSRichard Kuo		r2 = add(r2,#-2)
279c150290dSRichard Kuo		memh(r6++#2) = r7
280c150290dSRichard Kuo	}
281c150290dSRichard Kuo.L35:
282c150290dSRichard Kuo		p0 = cmp.eq(r2,#1)
283c150290dSRichard Kuo		if (p0) memb(r6) = r1
284c150290dSRichard Kuo.L1:
285c150290dSRichard Kuo		jumpr r31
286c150290dSRichard Kuo.L18:
287c150290dSRichard Kuo		loop0(.L45,r3)
288c150290dSRichard Kuo	.falign
289c150290dSRichard Kuo.L45:
290c150290dSRichard Kuo		dczeroa(r6)
291c150290dSRichard Kuo	{
292c150290dSRichard Kuo		memd(r6++#8) = r5:4
293c150290dSRichard Kuo		r2 = add(r2,#-32)
294c150290dSRichard Kuo	}
295c150290dSRichard Kuo		memd(r6++#8) = r5:4
296c150290dSRichard Kuo		memd(r6++#8) = r5:4
297c150290dSRichard Kuo	{
298c150290dSRichard Kuo		memd(r6++#8) = r5:4
299c150290dSRichard Kuo	}:endloop0 /* start=.L45  */
300c150290dSRichard Kuo		jump .L14
301c150290dSRichard KuoHEXAGON_OPT_FUNC_FINISH memset
302c150290dSRichard Kuo#endif
303