1 /*
2  * include/asm-sparc64/xor.h
3  *
4  * High speed xor_block operation for RAID4/5 utilizing the
5  * UltraSparc Visual Instruction Set.
6  *
7  * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2, or (at your option)
12  * any later version.
13  *
14  * You should have received a copy of the GNU General Public License
15  * (for example /usr/src/linux/COPYING); if not, write to the Free
16  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17  */
18 
19 /*
20  *	Requirements:
21  *	!(((long)dest | (long)sourceN) & (64 - 1)) &&
22  *	!(len & 127) && len >= 256
23  *
24  * It is done in pure assembly, as otherwise gcc makes it a non-leaf
25  * function, which is not what we want.
26  */
27 
28 #include <asm/pstate.h>
29 #include <asm/asi.h>
30 
31 extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
32 extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
33 		      unsigned long *);
34 extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
35 		      unsigned long *, unsigned long *);
36 extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
37 		      unsigned long *, unsigned long *, unsigned long *);
38 
39 #define _S(x) __S(x)
40 #define __S(x) #x
41 #define DEF(x) __asm__(#x " = " _S(x))
42 
43 DEF(FPRS_FEF);
44 DEF(FPRS_DU);
45 DEF(ASI_BLK_P);
46 
47 /* ??? We set and use %asi instead of using ASI_BLK_P directly because gas
48    currently does not accept symbolic constants for the ASI specifier.  */
49 
50 __asm__ ("\n\
51 	.text\n\
52 	.globl xor_vis_2\n\
53 	.type xor_vis_2,@function\n\
54 xor_vis_2:\n\
55 	rd	%fprs, %o5\n\
56 	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
57 	be,pt	%icc, 0f\n\
58 	 sethi	%hi(VISenter), %g1\n\
59 	jmpl	%g1 + %lo(VISenter), %g7\n\
60 	 add	%g7, 8, %g7\n\
61 0:	wr	%g0, FPRS_FEF, %fprs\n\
62 	rd	%asi, %g1\n\
63 	wr	%g0, ASI_BLK_P, %asi\n\
64 	membar	#LoadStore|#StoreLoad|#StoreStore\n\
65 	sub	%o0, 128, %o0\n\
66 	ldda	[%o1] %asi, %f0\n\
67 	ldda	[%o2] %asi, %f16\n\
68 \n\
69 2:	ldda	[%o1 + 64] %asi, %f32\n\
70 	fxor	%f0, %f16, %f16\n\
71 	fxor	%f2, %f18, %f18\n\
72 	fxor	%f4, %f20, %f20\n\
73 	fxor	%f6, %f22, %f22\n\
74 	fxor	%f8, %f24, %f24\n\
75 	fxor	%f10, %f26, %f26\n\
76 	fxor	%f12, %f28, %f28\n\
77 	fxor	%f14, %f30, %f30\n\
78 	stda	%f16, [%o1] %asi\n\
79 	ldda	[%o2 + 64] %asi, %f48\n\
80 	ldda	[%o1 + 128] %asi, %f0\n\
81 	fxor	%f32, %f48, %f48\n\
82 	fxor	%f34, %f50, %f50\n\
83 	add	%o1, 128, %o1\n\
84 	fxor	%f36, %f52, %f52\n\
85 	add	%o2, 128, %o2\n\
86 	fxor	%f38, %f54, %f54\n\
87 	subcc	%o0, 128, %o0\n\
88 	fxor	%f40, %f56, %f56\n\
89 	fxor	%f42, %f58, %f58\n\
90 	fxor	%f44, %f60, %f60\n\
91 	fxor	%f46, %f62, %f62\n\
92 	stda	%f48, [%o1 - 64] %asi\n\
93 	bne,pt	%xcc, 2b\n\
94 	 ldda	[%o2] %asi, %f16\n\
95 \n\
96 	ldda	[%o1 + 64] %asi, %f32\n\
97 	fxor	%f0, %f16, %f16\n\
98 	fxor	%f2, %f18, %f18\n\
99 	fxor	%f4, %f20, %f20\n\
100 	fxor	%f6, %f22, %f22\n\
101 	fxor	%f8, %f24, %f24\n\
102 	fxor	%f10, %f26, %f26\n\
103 	fxor	%f12, %f28, %f28\n\
104 	fxor	%f14, %f30, %f30\n\
105 	stda	%f16, [%o1] %asi\n\
106 	ldda	[%o2 + 64] %asi, %f48\n\
107 	membar	#Sync\n\
108 	fxor	%f32, %f48, %f48\n\
109 	fxor	%f34, %f50, %f50\n\
110 	fxor	%f36, %f52, %f52\n\
111 	fxor	%f38, %f54, %f54\n\
112 	fxor	%f40, %f56, %f56\n\
113 	fxor	%f42, %f58, %f58\n\
114 	fxor	%f44, %f60, %f60\n\
115 	fxor	%f46, %f62, %f62\n\
116 	stda	%f48, [%o1 + 64] %asi\n\
117 	membar	#Sync|#StoreStore|#StoreLoad\n\
118 	wr	%g1, %g0, %asi\n\
119 	retl\n\
120 	  wr	%g0, 0, %fprs\n\
121 	.size xor_vis_2, .-xor_vis_2\n\
122 \n\
123 \n\
124 	.globl xor_vis_3\n\
125 	.type xor_vis_3,@function\n\
126 xor_vis_3:\n\
127 	rd	%fprs, %o5\n\
128 	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
129 	be,pt	%icc, 0f\n\
130 	 sethi	%hi(VISenter), %g1\n\
131 	jmpl	%g1 + %lo(VISenter), %g7\n\
132 	 add	%g7, 8, %g7\n\
133 0:	wr	%g0, FPRS_FEF, %fprs\n\
134 	rd	%asi, %g1\n\
135 	wr	%g0, ASI_BLK_P, %asi\n\
136 	membar	#LoadStore|#StoreLoad|#StoreStore\n\
137 	sub	%o0, 64, %o0\n\
138 	ldda	[%o1] %asi, %f0\n\
139 	ldda	[%o2] %asi, %f16\n\
140 \n\
141 3:	ldda	[%o3] %asi, %f32\n\
142 	fxor	%f0, %f16, %f48\n\
143 	fxor	%f2, %f18, %f50\n\
144 	add	%o1, 64, %o1\n\
145 	fxor	%f4, %f20, %f52\n\
146 	fxor	%f6, %f22, %f54\n\
147 	add	%o2, 64, %o2\n\
148 	fxor	%f8, %f24, %f56\n\
149 	fxor	%f10, %f26, %f58\n\
150 	fxor	%f12, %f28, %f60\n\
151 	fxor	%f14, %f30, %f62\n\
152 	ldda	[%o1] %asi, %f0\n\
153 	fxor	%f48, %f32, %f48\n\
154 	fxor	%f50, %f34, %f50\n\
155 	fxor	%f52, %f36, %f52\n\
156 	fxor	%f54, %f38, %f54\n\
157 	add	%o3, 64, %o3\n\
158 	fxor	%f56, %f40, %f56\n\
159 	fxor	%f58, %f42, %f58\n\
160 	subcc	%o0, 64, %o0\n\
161 	fxor	%f60, %f44, %f60\n\
162 	fxor	%f62, %f46, %f62\n\
163 	stda	%f48, [%o1 - 64] %asi\n\
164 	bne,pt	%xcc, 3b\n\
165 	 ldda	[%o2] %asi, %f16\n\
166 \n\
167 	ldda	[%o3] %asi, %f32\n\
168 	fxor	%f0, %f16, %f48\n\
169 	fxor	%f2, %f18, %f50\n\
170 	fxor	%f4, %f20, %f52\n\
171 	fxor	%f6, %f22, %f54\n\
172 	fxor	%f8, %f24, %f56\n\
173 	fxor	%f10, %f26, %f58\n\
174 	fxor	%f12, %f28, %f60\n\
175 	fxor	%f14, %f30, %f62\n\
176 	membar	#Sync\n\
177 	fxor	%f48, %f32, %f48\n\
178 	fxor	%f50, %f34, %f50\n\
179 	fxor	%f52, %f36, %f52\n\
180 	fxor	%f54, %f38, %f54\n\
181 	fxor	%f56, %f40, %f56\n\
182 	fxor	%f58, %f42, %f58\n\
183 	fxor	%f60, %f44, %f60\n\
184 	fxor	%f62, %f46, %f62\n\
185 	stda	%f48, [%o1] %asi\n\
186 	membar	#Sync|#StoreStore|#StoreLoad\n\
187 	wr	%g1, %g0, %asi\n\
188 	retl\n\
189 	 wr	%g0, 0, %fprs\n\
190 	.size xor_vis_3, .-xor_vis_3\n\
191 \n\
192 \n\
193 	.globl xor_vis_4\n\
194 	.type xor_vis_4,@function\n\
195 xor_vis_4:\n\
196 	rd	%fprs, %o5\n\
197 	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
198 	be,pt	%icc, 0f\n\
199 	 sethi	%hi(VISenter), %g1\n\
200 	jmpl	%g1 + %lo(VISenter), %g7\n\
201 	 add	%g7, 8, %g7\n\
202 0:	wr	%g0, FPRS_FEF, %fprs\n\
203 	rd	%asi, %g1\n\
204 	wr	%g0, ASI_BLK_P, %asi\n\
205 	membar	#LoadStore|#StoreLoad|#StoreStore\n\
206 	sub	%o0, 64, %o0\n\
207 	ldda	[%o1] %asi, %f0\n\
208 	ldda	[%o2] %asi, %f16\n\
209 \n\
210 4:	ldda	[%o3] %asi, %f32\n\
211 	fxor	%f0, %f16, %f16\n\
212 	fxor	%f2, %f18, %f18\n\
213 	add	%o1, 64, %o1\n\
214 	fxor	%f4, %f20, %f20\n\
215 	fxor	%f6, %f22, %f22\n\
216 	add	%o2, 64, %o2\n\
217 	fxor	%f8, %f24, %f24\n\
218 	fxor	%f10, %f26, %f26\n\
219 	fxor	%f12, %f28, %f28\n\
220 	fxor	%f14, %f30, %f30\n\
221 	ldda	[%o4] %asi, %f48\n\
222 	fxor	%f16, %f32, %f32\n\
223 	fxor	%f18, %f34, %f34\n\
224 	fxor	%f20, %f36, %f36\n\
225 	fxor	%f22, %f38, %f38\n\
226 	add	%o3, 64, %o3\n\
227 	fxor	%f24, %f40, %f40\n\
228 	fxor	%f26, %f42, %f42\n\
229 	fxor	%f28, %f44, %f44\n\
230 	fxor	%f30, %f46, %f46\n\
231 	ldda	[%o1] %asi, %f0\n\
232 	fxor	%f32, %f48, %f48\n\
233 	fxor	%f34, %f50, %f50\n\
234 	fxor	%f36, %f52, %f52\n\
235 	add	%o4, 64, %o4\n\
236 	fxor	%f38, %f54, %f54\n\
237 	fxor	%f40, %f56, %f56\n\
238 	fxor	%f42, %f58, %f58\n\
239 	subcc	%o0, 64, %o0\n\
240 	fxor	%f44, %f60, %f60\n\
241 	fxor	%f46, %f62, %f62\n\
242 	stda	%f48, [%o1 - 64] %asi\n\
243 	bne,pt	%xcc, 4b\n\
244 	 ldda	[%o2] %asi, %f16\n\
245 \n\
246 	ldda	[%o3] %asi, %f32\n\
247 	fxor	%f0, %f16, %f16\n\
248 	fxor	%f2, %f18, %f18\n\
249 	fxor	%f4, %f20, %f20\n\
250 	fxor	%f6, %f22, %f22\n\
251 	fxor	%f8, %f24, %f24\n\
252 	fxor	%f10, %f26, %f26\n\
253 	fxor	%f12, %f28, %f28\n\
254 	fxor	%f14, %f30, %f30\n\
255 	ldda	[%o4] %asi, %f48\n\
256 	fxor	%f16, %f32, %f32\n\
257 	fxor	%f18, %f34, %f34\n\
258 	fxor	%f20, %f36, %f36\n\
259 	fxor	%f22, %f38, %f38\n\
260 	fxor	%f24, %f40, %f40\n\
261 	fxor	%f26, %f42, %f42\n\
262 	fxor	%f28, %f44, %f44\n\
263 	fxor	%f30, %f46, %f46\n\
264 	membar	#Sync\n\
265 	fxor	%f32, %f48, %f48\n\
266 	fxor	%f34, %f50, %f50\n\
267 	fxor	%f36, %f52, %f52\n\
268 	fxor	%f38, %f54, %f54\n\
269 	fxor	%f40, %f56, %f56\n\
270 	fxor	%f42, %f58, %f58\n\
271 	fxor	%f44, %f60, %f60\n\
272 	fxor	%f46, %f62, %f62\n\
273 	stda	%f48, [%o1] %asi\n\
274 	membar	#Sync|#StoreStore|#StoreLoad\n\
275 	wr	%g1, %g0, %asi\n\
276 	retl\n\
277 	 wr	%g0, 0, %fprs\n\
278 	.size xor_vis_4, .-xor_vis_4\n\
279 \n\
280 \n\
281 	.globl xor_vis_5\n\
282 	.type xor_vis_5,@function\n\
283 xor_vis_5:\n\
284 	mov	%o5, %g5\n\
285 	rd	%fprs, %o5\n\
286 	andcc	%o5, FPRS_FEF|FPRS_DU, %g0\n\
287 	be,pt	%icc, 0f\n\
288 	 sethi	%hi(VISenter), %g1\n\
289 	jmpl	%g1 + %lo(VISenter), %g7\n\
290 	 add	%g7, 8, %g7\n\
291 0:	wr	%g0, FPRS_FEF, %fprs\n\
292 	mov	%g5, %o5\n\
293 	rd	%asi, %g1\n\
294 	wr	%g0, ASI_BLK_P, %asi\n\
295 	membar	#LoadStore|#StoreLoad|#StoreStore\n\
296 	sub	%o0, 64, %o0\n\
297 	ldda	[%o1] %asi, %f0\n\
298 	ldda	[%o2] %asi, %f16\n\
299 \n\
300 5:	ldda	[%o3] %asi, %f32\n\
301 	fxor	%f0, %f16, %f48\n\
302 	fxor	%f2, %f18, %f50\n\
303 	add	%o1, 64, %o1\n\
304 	fxor	%f4, %f20, %f52\n\
305 	fxor	%f6, %f22, %f54\n\
306 	add	%o2, 64, %o2\n\
307 	fxor	%f8, %f24, %f56\n\
308 	fxor	%f10, %f26, %f58\n\
309 	fxor	%f12, %f28, %f60\n\
310 	fxor	%f14, %f30, %f62\n\
311 	ldda	[%o4] %asi, %f16\n\
312 	fxor	%f48, %f32, %f48\n\
313 	fxor	%f50, %f34, %f50\n\
314 	fxor	%f52, %f36, %f52\n\
315 	fxor	%f54, %f38, %f54\n\
316 	add	%o3, 64, %o3\n\
317 	fxor	%f56, %f40, %f56\n\
318 	fxor	%f58, %f42, %f58\n\
319 	fxor	%f60, %f44, %f60\n\
320 	fxor	%f62, %f46, %f62\n\
321 	ldda	[%o5] %asi, %f32\n\
322 	fxor	%f48, %f16, %f48\n\
323 	fxor	%f50, %f18, %f50\n\
324 	add	%o4, 64, %o4\n\
325 	fxor	%f52, %f20, %f52\n\
326 	fxor	%f54, %f22, %f54\n\
327 	add	%o5, 64, %o5\n\
328 	fxor	%f56, %f24, %f56\n\
329 	fxor	%f58, %f26, %f58\n\
330 	fxor	%f60, %f28, %f60\n\
331 	fxor	%f62, %f30, %f62\n\
332 	ldda	[%o1] %asi, %f0\n\
333 	fxor	%f48, %f32, %f48\n\
334 	fxor	%f50, %f34, %f50\n\
335 	fxor	%f52, %f36, %f52\n\
336 	fxor	%f54, %f38, %f54\n\
337 	fxor	%f56, %f40, %f56\n\
338 	fxor	%f58, %f42, %f58\n\
339 	subcc	%o0, 64, %o0\n\
340 	fxor	%f60, %f44, %f60\n\
341 	fxor	%f62, %f46, %f62\n\
342 	stda	%f48, [%o1 - 64] %asi\n\
343 	bne,pt	%xcc, 5b\n\
344 	 ldda	[%o2] %asi, %f16\n\
345 \n\
346 	ldda	[%o3] %asi, %f32\n\
347 	fxor	%f0, %f16, %f48\n\
348 	fxor	%f2, %f18, %f50\n\
349 	fxor	%f4, %f20, %f52\n\
350 	fxor	%f6, %f22, %f54\n\
351 	fxor	%f8, %f24, %f56\n\
352 	fxor	%f10, %f26, %f58\n\
353 	fxor	%f12, %f28, %f60\n\
354 	fxor	%f14, %f30, %f62\n\
355 	ldda	[%o4] %asi, %f16\n\
356 	fxor	%f48, %f32, %f48\n\
357 	fxor	%f50, %f34, %f50\n\
358 	fxor	%f52, %f36, %f52\n\
359 	fxor	%f54, %f38, %f54\n\
360 	fxor	%f56, %f40, %f56\n\
361 	fxor	%f58, %f42, %f58\n\
362 	fxor	%f60, %f44, %f60\n\
363 	fxor	%f62, %f46, %f62\n\
364 	ldda	[%o5] %asi, %f32\n\
365 	fxor	%f48, %f16, %f48\n\
366 	fxor	%f50, %f18, %f50\n\
367 	fxor	%f52, %f20, %f52\n\
368 	fxor	%f54, %f22, %f54\n\
369 	fxor	%f56, %f24, %f56\n\
370 	fxor	%f58, %f26, %f58\n\
371 	fxor	%f60, %f28, %f60\n\
372 	fxor	%f62, %f30, %f62\n\
373 	membar	#Sync\n\
374 	fxor	%f48, %f32, %f48\n\
375 	fxor	%f50, %f34, %f50\n\
376 	fxor	%f52, %f36, %f52\n\
377 	fxor	%f54, %f38, %f54\n\
378 	fxor	%f56, %f40, %f56\n\
379 	fxor	%f58, %f42, %f58\n\
380 	fxor	%f60, %f44, %f60\n\
381 	fxor	%f62, %f46, %f62\n\
382 	stda	%f48, [%o1] %asi\n\
383 	membar	#Sync|#StoreStore|#StoreLoad\n\
384 	wr	%g1, %g0, %asi\n\
385 	retl\n\
386 	 wr	%g0, 0, %fprs\n\
387 	.size xor_vis_5, .-xor_vis_5\n\
388 ");
389 
390 static struct xor_block_template xor_block_VIS = {
391         name: "VIS",
392         do_2: xor_vis_2,
393         do_3: xor_vis_3,
394         do_4: xor_vis_4,
395         do_5: xor_vis_5,
396 };
397 
398 #define XOR_TRY_TEMPLATES       xor_speed(&xor_block_VIS)
399