1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Optimized xor_block operation for RAID4/5
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Copyright IBM Corp. 2016
6*4882a593Smuzhiyun * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
7*4882a593Smuzhiyun */
8*4882a593Smuzhiyun
9*4882a593Smuzhiyun #include <linux/types.h>
10*4882a593Smuzhiyun #include <linux/export.h>
11*4882a593Smuzhiyun #include <linux/raid/xor.h>
12*4882a593Smuzhiyun #include <asm/xor.h>
13*4882a593Smuzhiyun
xor_xc_2(unsigned long bytes,unsigned long * p1,unsigned long * p2)14*4882a593Smuzhiyun static void xor_xc_2(unsigned long bytes, unsigned long *p1, unsigned long *p2)
15*4882a593Smuzhiyun {
16*4882a593Smuzhiyun asm volatile(
17*4882a593Smuzhiyun " larl 1,2f\n"
18*4882a593Smuzhiyun " aghi %0,-1\n"
19*4882a593Smuzhiyun " jm 3f\n"
20*4882a593Smuzhiyun " srlg 0,%0,8\n"
21*4882a593Smuzhiyun " ltgr 0,0\n"
22*4882a593Smuzhiyun " jz 1f\n"
23*4882a593Smuzhiyun "0: xc 0(256,%1),0(%2)\n"
24*4882a593Smuzhiyun " la %1,256(%1)\n"
25*4882a593Smuzhiyun " la %2,256(%2)\n"
26*4882a593Smuzhiyun " brctg 0,0b\n"
27*4882a593Smuzhiyun "1: ex %0,0(1)\n"
28*4882a593Smuzhiyun " j 3f\n"
29*4882a593Smuzhiyun "2: xc 0(1,%1),0(%2)\n"
30*4882a593Smuzhiyun "3:\n"
31*4882a593Smuzhiyun : : "d" (bytes), "a" (p1), "a" (p2)
32*4882a593Smuzhiyun : "0", "1", "cc", "memory");
33*4882a593Smuzhiyun }
34*4882a593Smuzhiyun
xor_xc_3(unsigned long bytes,unsigned long * p1,unsigned long * p2,unsigned long * p3)35*4882a593Smuzhiyun static void xor_xc_3(unsigned long bytes, unsigned long *p1, unsigned long *p2,
36*4882a593Smuzhiyun unsigned long *p3)
37*4882a593Smuzhiyun {
38*4882a593Smuzhiyun asm volatile(
39*4882a593Smuzhiyun " larl 1,2f\n"
40*4882a593Smuzhiyun " aghi %0,-1\n"
41*4882a593Smuzhiyun " jm 3f\n"
42*4882a593Smuzhiyun " srlg 0,%0,8\n"
43*4882a593Smuzhiyun " ltgr 0,0\n"
44*4882a593Smuzhiyun " jz 1f\n"
45*4882a593Smuzhiyun "0: xc 0(256,%1),0(%2)\n"
46*4882a593Smuzhiyun " xc 0(256,%1),0(%3)\n"
47*4882a593Smuzhiyun " la %1,256(%1)\n"
48*4882a593Smuzhiyun " la %2,256(%2)\n"
49*4882a593Smuzhiyun " la %3,256(%3)\n"
50*4882a593Smuzhiyun " brctg 0,0b\n"
51*4882a593Smuzhiyun "1: ex %0,0(1)\n"
52*4882a593Smuzhiyun " ex %0,6(1)\n"
53*4882a593Smuzhiyun " j 3f\n"
54*4882a593Smuzhiyun "2: xc 0(1,%1),0(%2)\n"
55*4882a593Smuzhiyun " xc 0(1,%1),0(%3)\n"
56*4882a593Smuzhiyun "3:\n"
57*4882a593Smuzhiyun : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3)
58*4882a593Smuzhiyun : : "0", "1", "cc", "memory");
59*4882a593Smuzhiyun }
60*4882a593Smuzhiyun
xor_xc_4(unsigned long bytes,unsigned long * p1,unsigned long * p2,unsigned long * p3,unsigned long * p4)61*4882a593Smuzhiyun static void xor_xc_4(unsigned long bytes, unsigned long *p1, unsigned long *p2,
62*4882a593Smuzhiyun unsigned long *p3, unsigned long *p4)
63*4882a593Smuzhiyun {
64*4882a593Smuzhiyun asm volatile(
65*4882a593Smuzhiyun " larl 1,2f\n"
66*4882a593Smuzhiyun " aghi %0,-1\n"
67*4882a593Smuzhiyun " jm 3f\n"
68*4882a593Smuzhiyun " srlg 0,%0,8\n"
69*4882a593Smuzhiyun " ltgr 0,0\n"
70*4882a593Smuzhiyun " jz 1f\n"
71*4882a593Smuzhiyun "0: xc 0(256,%1),0(%2)\n"
72*4882a593Smuzhiyun " xc 0(256,%1),0(%3)\n"
73*4882a593Smuzhiyun " xc 0(256,%1),0(%4)\n"
74*4882a593Smuzhiyun " la %1,256(%1)\n"
75*4882a593Smuzhiyun " la %2,256(%2)\n"
76*4882a593Smuzhiyun " la %3,256(%3)\n"
77*4882a593Smuzhiyun " la %4,256(%4)\n"
78*4882a593Smuzhiyun " brctg 0,0b\n"
79*4882a593Smuzhiyun "1: ex %0,0(1)\n"
80*4882a593Smuzhiyun " ex %0,6(1)\n"
81*4882a593Smuzhiyun " ex %0,12(1)\n"
82*4882a593Smuzhiyun " j 3f\n"
83*4882a593Smuzhiyun "2: xc 0(1,%1),0(%2)\n"
84*4882a593Smuzhiyun " xc 0(1,%1),0(%3)\n"
85*4882a593Smuzhiyun " xc 0(1,%1),0(%4)\n"
86*4882a593Smuzhiyun "3:\n"
87*4882a593Smuzhiyun : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4)
88*4882a593Smuzhiyun : : "0", "1", "cc", "memory");
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
xor_xc_5(unsigned long bytes,unsigned long * p1,unsigned long * p2,unsigned long * p3,unsigned long * p4,unsigned long * p5)91*4882a593Smuzhiyun static void xor_xc_5(unsigned long bytes, unsigned long *p1, unsigned long *p2,
92*4882a593Smuzhiyun unsigned long *p3, unsigned long *p4, unsigned long *p5)
93*4882a593Smuzhiyun {
94*4882a593Smuzhiyun /* Get around a gcc oddity */
95*4882a593Smuzhiyun register unsigned long *reg7 asm ("7") = p5;
96*4882a593Smuzhiyun
97*4882a593Smuzhiyun asm volatile(
98*4882a593Smuzhiyun " larl 1,2f\n"
99*4882a593Smuzhiyun " aghi %0,-1\n"
100*4882a593Smuzhiyun " jm 3f\n"
101*4882a593Smuzhiyun " srlg 0,%0,8\n"
102*4882a593Smuzhiyun " ltgr 0,0\n"
103*4882a593Smuzhiyun " jz 1f\n"
104*4882a593Smuzhiyun "0: xc 0(256,%1),0(%2)\n"
105*4882a593Smuzhiyun " xc 0(256,%1),0(%3)\n"
106*4882a593Smuzhiyun " xc 0(256,%1),0(%4)\n"
107*4882a593Smuzhiyun " xc 0(256,%1),0(%5)\n"
108*4882a593Smuzhiyun " la %1,256(%1)\n"
109*4882a593Smuzhiyun " la %2,256(%2)\n"
110*4882a593Smuzhiyun " la %3,256(%3)\n"
111*4882a593Smuzhiyun " la %4,256(%4)\n"
112*4882a593Smuzhiyun " la %5,256(%5)\n"
113*4882a593Smuzhiyun " brctg 0,0b\n"
114*4882a593Smuzhiyun "1: ex %0,0(1)\n"
115*4882a593Smuzhiyun " ex %0,6(1)\n"
116*4882a593Smuzhiyun " ex %0,12(1)\n"
117*4882a593Smuzhiyun " ex %0,18(1)\n"
118*4882a593Smuzhiyun " j 3f\n"
119*4882a593Smuzhiyun "2: xc 0(1,%1),0(%2)\n"
120*4882a593Smuzhiyun " xc 0(1,%1),0(%3)\n"
121*4882a593Smuzhiyun " xc 0(1,%1),0(%4)\n"
122*4882a593Smuzhiyun " xc 0(1,%1),0(%5)\n"
123*4882a593Smuzhiyun "3:\n"
124*4882a593Smuzhiyun : "+d" (bytes), "+a" (p1), "+a" (p2), "+a" (p3), "+a" (p4),
125*4882a593Smuzhiyun "+a" (reg7)
126*4882a593Smuzhiyun : : "0", "1", "cc", "memory");
127*4882a593Smuzhiyun }
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun struct xor_block_template xor_block_xc = {
130*4882a593Smuzhiyun .name = "xc",
131*4882a593Smuzhiyun .do_2 = xor_xc_2,
132*4882a593Smuzhiyun .do_3 = xor_xc_3,
133*4882a593Smuzhiyun .do_4 = xor_xc_4,
134*4882a593Smuzhiyun .do_5 = xor_xc_5,
135*4882a593Smuzhiyun };
136*4882a593Smuzhiyun EXPORT_SYMBOL(xor_block_xc);
137