xref: /OK3568_Linux_fs/kernel/arch/s390/lib/xor.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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