2 * arch/sparc64/lib/xor.S
4 * High speed xor_block operation for RAID4/5 utilizing the
5 * UltraSparc Visual Instruction Set and Niagara store-init/twin-load.
7 * Copyright (C) 1997, 1999 Jakub Jelinek (jj@ultra.linux.cz)
8 * Copyright (C) 2006 David S. Miller <davem@davemloft.net>
11 #include <linux/linkage.h>
12 #include <asm/visasm.h>
15 #include <asm/spitfire.h>
16 #include <asm/export.h>
20 * !(((long)dest | (long)sourceN) & (64 - 1)) &&
21 * !(len & 127) && len >= 256
28 andcc %o5, FPRS_FEF|FPRS_DU, %g0
30 sethi %hi(VISenter), %g1
31 jmpl %g1 + %lo(VISenter), %g7
33 0: wr %g0, FPRS_FEF, %fprs
35 wr %g0, ASI_BLK_P, %asi
36 membar #LoadStore|#StoreLoad|#StoreStore
41 2: ldda [%o1 + 64] %asi, %f32
51 ldda [%o2 + 64] %asi, %f48
52 ldda [%o1 + 128] %asi, %f0
64 stda %f48, [%o1 - 64] %asi
68 ldda [%o1 + 64] %asi, %f32
78 ldda [%o2 + 64] %asi, %f48
88 stda %f48, [%o1 + 64] %asi
89 membar #Sync|#StoreStore|#StoreLoad
94 EXPORT_SYMBOL(xor_vis_2)
98 andcc %o5, FPRS_FEF|FPRS_DU, %g0
100 sethi %hi(VISenter), %g1
101 jmpl %g1 + %lo(VISenter), %g7
103 0: wr %g0, FPRS_FEF, %fprs
105 wr %g0, ASI_BLK_P, %asi
106 membar #LoadStore|#StoreLoad|#StoreStore
109 ldda [%o2] %asi, %f16
111 3: ldda [%o3] %asi, %f32
119 fxor %f10, %f26, %f58
120 fxor %f12, %f28, %f60
121 fxor %f14, %f30, %f62
123 fxor %f48, %f32, %f48
124 fxor %f50, %f34, %f50
125 fxor %f52, %f36, %f52
126 fxor %f54, %f38, %f54
128 fxor %f56, %f40, %f56
129 fxor %f58, %f42, %f58
131 fxor %f60, %f44, %f60
132 fxor %f62, %f46, %f62
133 stda %f48, [%o1 - 64] %asi
135 ldda [%o2] %asi, %f16
137 ldda [%o3] %asi, %f32
143 fxor %f10, %f26, %f58
144 fxor %f12, %f28, %f60
145 fxor %f14, %f30, %f62
147 fxor %f48, %f32, %f48
148 fxor %f50, %f34, %f50
149 fxor %f52, %f36, %f52
150 fxor %f54, %f38, %f54
151 fxor %f56, %f40, %f56
152 fxor %f58, %f42, %f58
153 fxor %f60, %f44, %f60
154 fxor %f62, %f46, %f62
155 stda %f48, [%o1] %asi
156 membar #Sync|#StoreStore|#StoreLoad
161 EXPORT_SYMBOL(xor_vis_3)
165 andcc %o5, FPRS_FEF|FPRS_DU, %g0
167 sethi %hi(VISenter), %g1
168 jmpl %g1 + %lo(VISenter), %g7
170 0: wr %g0, FPRS_FEF, %fprs
172 wr %g0, ASI_BLK_P, %asi
173 membar #LoadStore|#StoreLoad|#StoreStore
176 ldda [%o2] %asi, %f16
178 4: ldda [%o3] %asi, %f32
186 fxor %f10, %f26, %f26
187 fxor %f12, %f28, %f28
188 fxor %f14, %f30, %f30
189 ldda [%o4] %asi, %f48
190 fxor %f16, %f32, %f32
191 fxor %f18, %f34, %f34
192 fxor %f20, %f36, %f36
193 fxor %f22, %f38, %f38
195 fxor %f24, %f40, %f40
196 fxor %f26, %f42, %f42
197 fxor %f28, %f44, %f44
198 fxor %f30, %f46, %f46
200 fxor %f32, %f48, %f48
201 fxor %f34, %f50, %f50
202 fxor %f36, %f52, %f52
204 fxor %f38, %f54, %f54
205 fxor %f40, %f56, %f56
206 fxor %f42, %f58, %f58
208 fxor %f44, %f60, %f60
209 fxor %f46, %f62, %f62
210 stda %f48, [%o1 - 64] %asi
212 ldda [%o2] %asi, %f16
214 ldda [%o3] %asi, %f32
220 fxor %f10, %f26, %f26
221 fxor %f12, %f28, %f28
222 fxor %f14, %f30, %f30
223 ldda [%o4] %asi, %f48
224 fxor %f16, %f32, %f32
225 fxor %f18, %f34, %f34
226 fxor %f20, %f36, %f36
227 fxor %f22, %f38, %f38
228 fxor %f24, %f40, %f40
229 fxor %f26, %f42, %f42
230 fxor %f28, %f44, %f44
231 fxor %f30, %f46, %f46
233 fxor %f32, %f48, %f48
234 fxor %f34, %f50, %f50
235 fxor %f36, %f52, %f52
236 fxor %f38, %f54, %f54
237 fxor %f40, %f56, %f56
238 fxor %f42, %f58, %f58
239 fxor %f44, %f60, %f60
240 fxor %f46, %f62, %f62
241 stda %f48, [%o1] %asi
242 membar #Sync|#StoreStore|#StoreLoad
247 EXPORT_SYMBOL(xor_vis_4)
252 andcc %o5, FPRS_FEF|FPRS_DU, %g0
254 sethi %hi(VISenter), %g1
255 jmpl %g1 + %lo(VISenter), %g7
257 0: wr %g0, FPRS_FEF, %fprs
259 wr %g0, ASI_BLK_P, %asi
260 membar #LoadStore|#StoreLoad|#StoreStore
263 ldda [%i2] %asi, %f16
265 5: ldda [%i3] %asi, %f32
273 fxor %f10, %f26, %f58
274 fxor %f12, %f28, %f60
275 fxor %f14, %f30, %f62
276 ldda [%i4] %asi, %f16
277 fxor %f48, %f32, %f48
278 fxor %f50, %f34, %f50
279 fxor %f52, %f36, %f52
280 fxor %f54, %f38, %f54
282 fxor %f56, %f40, %f56
283 fxor %f58, %f42, %f58
284 fxor %f60, %f44, %f60
285 fxor %f62, %f46, %f62
286 ldda [%i5] %asi, %f32
287 fxor %f48, %f16, %f48
288 fxor %f50, %f18, %f50
290 fxor %f52, %f20, %f52
291 fxor %f54, %f22, %f54
293 fxor %f56, %f24, %f56
294 fxor %f58, %f26, %f58
295 fxor %f60, %f28, %f60
296 fxor %f62, %f30, %f62
298 fxor %f48, %f32, %f48
299 fxor %f50, %f34, %f50
300 fxor %f52, %f36, %f52
301 fxor %f54, %f38, %f54
302 fxor %f56, %f40, %f56
303 fxor %f58, %f42, %f58
305 fxor %f60, %f44, %f60
306 fxor %f62, %f46, %f62
307 stda %f48, [%i1 - 64] %asi
309 ldda [%i2] %asi, %f16
311 ldda [%i3] %asi, %f32
317 fxor %f10, %f26, %f58
318 fxor %f12, %f28, %f60
319 fxor %f14, %f30, %f62
320 ldda [%i4] %asi, %f16
321 fxor %f48, %f32, %f48
322 fxor %f50, %f34, %f50
323 fxor %f52, %f36, %f52
324 fxor %f54, %f38, %f54
325 fxor %f56, %f40, %f56
326 fxor %f58, %f42, %f58
327 fxor %f60, %f44, %f60
328 fxor %f62, %f46, %f62
329 ldda [%i5] %asi, %f32
330 fxor %f48, %f16, %f48
331 fxor %f50, %f18, %f50
332 fxor %f52, %f20, %f52
333 fxor %f54, %f22, %f54
334 fxor %f56, %f24, %f56
335 fxor %f58, %f26, %f58
336 fxor %f60, %f28, %f60
337 fxor %f62, %f30, %f62
339 fxor %f48, %f32, %f48
340 fxor %f50, %f34, %f50
341 fxor %f52, %f36, %f52
342 fxor %f54, %f38, %f54
343 fxor %f56, %f40, %f56
344 fxor %f58, %f42, %f58
345 fxor %f60, %f44, %f60
346 fxor %f62, %f46, %f62
347 stda %f48, [%i1] %asi
348 membar #Sync|#StoreStore|#StoreLoad
354 EXPORT_SYMBOL(xor_vis_5)
356 /* Niagara versions. */
357 ENTRY(xor_niagara_2) /* %o0=bytes, %o1=dest, %o2=src */
359 prefetch [%i1], #n_writes
360 prefetch [%i2], #one_read
362 wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
366 1: ldda [%i1 + 0x00] %asi, %i2 /* %i2/%i3 = src + 0x00 */
367 ldda [%i1 + 0x10] %asi, %i4 /* %i4/%i5 = src + 0x10 */
368 ldda [%i1 + 0x20] %asi, %g2 /* %g2/%g3 = src + 0x20 */
369 ldda [%i1 + 0x30] %asi, %l0 /* %l0/%l1 = src + 0x30 */
370 prefetch [%i1 + 0x40], #one_read
371 ldda [%i0 + 0x00] %asi, %o0 /* %o0/%o1 = dest + 0x00 */
372 ldda [%i0 + 0x10] %asi, %o2 /* %o2/%o3 = dest + 0x10 */
373 ldda [%i0 + 0x20] %asi, %o4 /* %o4/%o5 = dest + 0x20 */
374 ldda [%i0 + 0x30] %asi, %l2 /* %l2/%l3 = dest + 0x30 */
375 prefetch [%i0 + 0x40], #n_writes
378 stxa %o0, [%i0 + 0x00] %asi
379 stxa %o1, [%i0 + 0x08] %asi
382 stxa %o2, [%i0 + 0x10] %asi
383 stxa %o3, [%i0 + 0x18] %asi
386 stxa %o4, [%i0 + 0x20] %asi
387 stxa %o5, [%i0 + 0x28] %asi
390 stxa %l2, [%i0 + 0x30] %asi
391 stxa %l3, [%i0 + 0x38] %asi
400 ENDPROC(xor_niagara_2)
401 EXPORT_SYMBOL(xor_niagara_2)
403 ENTRY(xor_niagara_3) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2 */
405 prefetch [%i1], #n_writes
406 prefetch [%i2], #one_read
407 prefetch [%i3], #one_read
409 wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
414 1: ldda [%i1 + 0x00] %asi, %i2 /* %i2/%i3 = src1 + 0x00 */
415 ldda [%i1 + 0x10] %asi, %i4 /* %i4/%i5 = src1 + 0x10 */
416 ldda [%l7 + 0x00] %asi, %g2 /* %g2/%g3 = src2 + 0x00 */
417 ldda [%l7 + 0x10] %asi, %l0 /* %l0/%l1 = src2 + 0x10 */
418 ldda [%i0 + 0x00] %asi, %o0 /* %o0/%o1 = dest + 0x00 */
419 ldda [%i0 + 0x10] %asi, %o2 /* %o2/%o3 = dest + 0x10 */
424 stxa %o0, [%i0 + 0x00] %asi
425 stxa %o1, [%i0 + 0x08] %asi
426 ldda [%i1 + 0x20] %asi, %i2 /* %i2/%i3 = src1 + 0x20 */
427 ldda [%l7 + 0x20] %asi, %g2 /* %g2/%g3 = src2 + 0x20 */
428 ldda [%i0 + 0x20] %asi, %o0 /* %o0/%o1 = dest + 0x20 */
433 stxa %o2, [%i0 + 0x10] %asi
434 stxa %o3, [%i0 + 0x18] %asi
435 ldda [%i1 + 0x30] %asi, %i4 /* %i4/%i5 = src1 + 0x30 */
436 ldda [%l7 + 0x30] %asi, %l0 /* %l0/%l1 = src2 + 0x30 */
437 ldda [%i0 + 0x30] %asi, %o2 /* %o2/%o3 = dest + 0x30 */
438 prefetch [%i1 + 0x40], #one_read
439 prefetch [%l7 + 0x40], #one_read
440 prefetch [%i0 + 0x40], #n_writes
445 stxa %o0, [%i0 + 0x20] %asi
446 stxa %o1, [%i0 + 0x28] %asi
451 stxa %o2, [%i0 + 0x30] %asi
452 stxa %o3, [%i0 + 0x38] %asi
462 ENDPROC(xor_niagara_3)
463 EXPORT_SYMBOL(xor_niagara_3)
465 ENTRY(xor_niagara_4) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3 */
467 prefetch [%i1], #n_writes
468 prefetch [%i2], #one_read
469 prefetch [%i3], #one_read
470 prefetch [%i4], #one_read
472 wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
478 1: ldda [%i1 + 0x00] %asi, %i2 /* %i2/%i3 = src1 + 0x00 */
479 ldda [%l7 + 0x00] %asi, %i4 /* %i4/%i5 = src2 + 0x00 */
480 ldda [%l6 + 0x00] %asi, %g2 /* %g2/%g3 = src3 + 0x00 */
481 ldda [%i0 + 0x00] %asi, %l0 /* %l0/%l1 = dest + 0x00 */
484 ldda [%i1 + 0x10] %asi, %i2 /* %i2/%i3 = src1 + 0x10 */
487 ldda [%l7 + 0x10] %asi, %i4 /* %i4/%i5 = src2 + 0x10 */
490 stxa %l0, [%i0 + 0x00] %asi
491 stxa %l1, [%i0 + 0x08] %asi
492 ldda [%l6 + 0x10] %asi, %g2 /* %g2/%g3 = src3 + 0x10 */
493 ldda [%i0 + 0x10] %asi, %l0 /* %l0/%l1 = dest + 0x10 */
497 ldda [%i1 + 0x20] %asi, %i2 /* %i2/%i3 = src1 + 0x20 */
500 ldda [%l7 + 0x20] %asi, %i4 /* %i4/%i5 = src2 + 0x20 */
503 stxa %l0, [%i0 + 0x10] %asi
504 stxa %l1, [%i0 + 0x18] %asi
505 ldda [%l6 + 0x20] %asi, %g2 /* %g2/%g3 = src3 + 0x20 */
506 ldda [%i0 + 0x20] %asi, %l0 /* %l0/%l1 = dest + 0x20 */
510 ldda [%i1 + 0x30] %asi, %i2 /* %i2/%i3 = src1 + 0x30 */
513 ldda [%l7 + 0x30] %asi, %i4 /* %i4/%i5 = src2 + 0x30 */
516 stxa %l0, [%i0 + 0x20] %asi
517 stxa %l1, [%i0 + 0x28] %asi
518 ldda [%l6 + 0x30] %asi, %g2 /* %g2/%g3 = src3 + 0x30 */
519 ldda [%i0 + 0x30] %asi, %l0 /* %l0/%l1 = dest + 0x30 */
521 prefetch [%i1 + 0x40], #one_read
522 prefetch [%l7 + 0x40], #one_read
523 prefetch [%l6 + 0x40], #one_read
524 prefetch [%i0 + 0x40], #n_writes
532 stxa %l0, [%i0 + 0x30] %asi
533 stxa %l1, [%i0 + 0x38] %asi
545 ENDPROC(xor_niagara_4)
546 EXPORT_SYMBOL(xor_niagara_4)
548 ENTRY(xor_niagara_5) /* %o0=bytes, %o1=dest, %o2=src1, %o3=src2, %o4=src3, %o5=src4 */
550 prefetch [%i1], #n_writes
551 prefetch [%i2], #one_read
552 prefetch [%i3], #one_read
553 prefetch [%i4], #one_read
554 prefetch [%i5], #one_read
556 wr %g0, ASI_BLK_INIT_QUAD_LDD_P, %asi
563 1: ldda [%i1 + 0x00] %asi, %i2 /* %i2/%i3 = src1 + 0x00 */
564 ldda [%l7 + 0x00] %asi, %i4 /* %i4/%i5 = src2 + 0x00 */
565 ldda [%l6 + 0x00] %asi, %g2 /* %g2/%g3 = src3 + 0x00 */
566 ldda [%l5 + 0x00] %asi, %l0 /* %l0/%l1 = src4 + 0x00 */
567 ldda [%i0 + 0x00] %asi, %l2 /* %l2/%l3 = dest + 0x00 */
570 ldda [%i1 + 0x10] %asi, %i2 /* %i2/%i3 = src1 + 0x10 */
573 ldda [%l7 + 0x10] %asi, %i4 /* %i4/%i5 = src2 + 0x10 */
576 ldda [%l6 + 0x10] %asi, %g2 /* %g2/%g3 = src3 + 0x10 */
579 stxa %l2, [%i0 + 0x00] %asi
580 stxa %l3, [%i0 + 0x08] %asi
581 ldda [%l5 + 0x10] %asi, %l0 /* %l0/%l1 = src4 + 0x10 */
582 ldda [%i0 + 0x10] %asi, %l2 /* %l2/%l3 = dest + 0x10 */
586 ldda [%i1 + 0x20] %asi, %i2 /* %i2/%i3 = src1 + 0x20 */
589 ldda [%l7 + 0x20] %asi, %i4 /* %i4/%i5 = src2 + 0x20 */
592 ldda [%l6 + 0x20] %asi, %g2 /* %g2/%g3 = src3 + 0x20 */
595 stxa %l2, [%i0 + 0x10] %asi
596 stxa %l3, [%i0 + 0x18] %asi
597 ldda [%l5 + 0x20] %asi, %l0 /* %l0/%l1 = src4 + 0x20 */
598 ldda [%i0 + 0x20] %asi, %l2 /* %l2/%l3 = dest + 0x20 */
602 ldda [%i1 + 0x30] %asi, %i2 /* %i2/%i3 = src1 + 0x30 */
605 ldda [%l7 + 0x30] %asi, %i4 /* %i4/%i5 = src2 + 0x30 */
608 ldda [%l6 + 0x30] %asi, %g2 /* %g2/%g3 = src3 + 0x30 */
611 stxa %l2, [%i0 + 0x20] %asi
612 stxa %l3, [%i0 + 0x28] %asi
613 ldda [%l5 + 0x30] %asi, %l0 /* %l0/%l1 = src4 + 0x30 */
614 ldda [%i0 + 0x30] %asi, %l2 /* %l2/%l3 = dest + 0x30 */
616 prefetch [%i1 + 0x40], #one_read
617 prefetch [%l7 + 0x40], #one_read
618 prefetch [%l6 + 0x40], #one_read
619 prefetch [%l5 + 0x40], #one_read
620 prefetch [%i0 + 0x40], #n_writes
630 stxa %l2, [%i0 + 0x30] %asi
631 stxa %l3, [%i0 + 0x38] %asi
644 ENDPROC(xor_niagara_5)
645 EXPORT_SYMBOL(xor_niagara_5)