1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * include/asm/xor.h
4  *
5  * Optimized RAID-5 checksumming functions for 32-bit Sparc.
6  */
7 
8 /*
9  * High speed xor_block operation for RAID4/5 utilizing the
10  * ldd/std SPARC instructions.
11  *
12  * Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
13  */
14 
15 static void
sparc_2(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2)16 sparc_2(unsigned long bytes, unsigned long * __restrict p1,
17 	const unsigned long * __restrict p2)
18 {
19 	int lines = bytes / (sizeof (long)) / 8;
20 
21 	do {
22 		__asm__ __volatile__(
23 		  "ldd [%0 + 0x00], %%g2\n\t"
24 		  "ldd [%0 + 0x08], %%g4\n\t"
25 		  "ldd [%0 + 0x10], %%o0\n\t"
26 		  "ldd [%0 + 0x18], %%o2\n\t"
27 		  "ldd [%1 + 0x00], %%o4\n\t"
28 		  "ldd [%1 + 0x08], %%l0\n\t"
29 		  "ldd [%1 + 0x10], %%l2\n\t"
30 		  "ldd [%1 + 0x18], %%l4\n\t"
31 		  "xor %%g2, %%o4, %%g2\n\t"
32 		  "xor %%g3, %%o5, %%g3\n\t"
33 		  "xor %%g4, %%l0, %%g4\n\t"
34 		  "xor %%g5, %%l1, %%g5\n\t"
35 		  "xor %%o0, %%l2, %%o0\n\t"
36 		  "xor %%o1, %%l3, %%o1\n\t"
37 		  "xor %%o2, %%l4, %%o2\n\t"
38 		  "xor %%o3, %%l5, %%o3\n\t"
39 		  "std %%g2, [%0 + 0x00]\n\t"
40 		  "std %%g4, [%0 + 0x08]\n\t"
41 		  "std %%o0, [%0 + 0x10]\n\t"
42 		  "std %%o2, [%0 + 0x18]\n"
43 		:
44 		: "r" (p1), "r" (p2)
45 		: "g2", "g3", "g4", "g5",
46 		  "o0", "o1", "o2", "o3", "o4", "o5",
47 		  "l0", "l1", "l2", "l3", "l4", "l5");
48 		p1 += 8;
49 		p2 += 8;
50 	} while (--lines > 0);
51 }
52 
53 static void
sparc_3(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2,const unsigned long * __restrict p3)54 sparc_3(unsigned long bytes, unsigned long * __restrict p1,
55 	const unsigned long * __restrict p2,
56 	const unsigned long * __restrict p3)
57 {
58 	int lines = bytes / (sizeof (long)) / 8;
59 
60 	do {
61 		__asm__ __volatile__(
62 		  "ldd [%0 + 0x00], %%g2\n\t"
63 		  "ldd [%0 + 0x08], %%g4\n\t"
64 		  "ldd [%0 + 0x10], %%o0\n\t"
65 		  "ldd [%0 + 0x18], %%o2\n\t"
66 		  "ldd [%1 + 0x00], %%o4\n\t"
67 		  "ldd [%1 + 0x08], %%l0\n\t"
68 		  "ldd [%1 + 0x10], %%l2\n\t"
69 		  "ldd [%1 + 0x18], %%l4\n\t"
70 		  "xor %%g2, %%o4, %%g2\n\t"
71 		  "xor %%g3, %%o5, %%g3\n\t"
72 		  "ldd [%2 + 0x00], %%o4\n\t"
73 		  "xor %%g4, %%l0, %%g4\n\t"
74 		  "xor %%g5, %%l1, %%g5\n\t"
75 		  "ldd [%2 + 0x08], %%l0\n\t"
76 		  "xor %%o0, %%l2, %%o0\n\t"
77 		  "xor %%o1, %%l3, %%o1\n\t"
78 		  "ldd [%2 + 0x10], %%l2\n\t"
79 		  "xor %%o2, %%l4, %%o2\n\t"
80 		  "xor %%o3, %%l5, %%o3\n\t"
81 		  "ldd [%2 + 0x18], %%l4\n\t"
82 		  "xor %%g2, %%o4, %%g2\n\t"
83 		  "xor %%g3, %%o5, %%g3\n\t"
84 		  "xor %%g4, %%l0, %%g4\n\t"
85 		  "xor %%g5, %%l1, %%g5\n\t"
86 		  "xor %%o0, %%l2, %%o0\n\t"
87 		  "xor %%o1, %%l3, %%o1\n\t"
88 		  "xor %%o2, %%l4, %%o2\n\t"
89 		  "xor %%o3, %%l5, %%o3\n\t"
90 		  "std %%g2, [%0 + 0x00]\n\t"
91 		  "std %%g4, [%0 + 0x08]\n\t"
92 		  "std %%o0, [%0 + 0x10]\n\t"
93 		  "std %%o2, [%0 + 0x18]\n"
94 		:
95 		: "r" (p1), "r" (p2), "r" (p3)
96 		: "g2", "g3", "g4", "g5",
97 		  "o0", "o1", "o2", "o3", "o4", "o5",
98 		  "l0", "l1", "l2", "l3", "l4", "l5");
99 		p1 += 8;
100 		p2 += 8;
101 		p3 += 8;
102 	} while (--lines > 0);
103 }
104 
105 static void
sparc_4(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2,const unsigned long * __restrict p3,const unsigned long * __restrict p4)106 sparc_4(unsigned long bytes, unsigned long * __restrict p1,
107 	const unsigned long * __restrict p2,
108 	const unsigned long * __restrict p3,
109 	const unsigned long * __restrict p4)
110 {
111 	int lines = bytes / (sizeof (long)) / 8;
112 
113 	do {
114 		__asm__ __volatile__(
115 		  "ldd [%0 + 0x00], %%g2\n\t"
116 		  "ldd [%0 + 0x08], %%g4\n\t"
117 		  "ldd [%0 + 0x10], %%o0\n\t"
118 		  "ldd [%0 + 0x18], %%o2\n\t"
119 		  "ldd [%1 + 0x00], %%o4\n\t"
120 		  "ldd [%1 + 0x08], %%l0\n\t"
121 		  "ldd [%1 + 0x10], %%l2\n\t"
122 		  "ldd [%1 + 0x18], %%l4\n\t"
123 		  "xor %%g2, %%o4, %%g2\n\t"
124 		  "xor %%g3, %%o5, %%g3\n\t"
125 		  "ldd [%2 + 0x00], %%o4\n\t"
126 		  "xor %%g4, %%l0, %%g4\n\t"
127 		  "xor %%g5, %%l1, %%g5\n\t"
128 		  "ldd [%2 + 0x08], %%l0\n\t"
129 		  "xor %%o0, %%l2, %%o0\n\t"
130 		  "xor %%o1, %%l3, %%o1\n\t"
131 		  "ldd [%2 + 0x10], %%l2\n\t"
132 		  "xor %%o2, %%l4, %%o2\n\t"
133 		  "xor %%o3, %%l5, %%o3\n\t"
134 		  "ldd [%2 + 0x18], %%l4\n\t"
135 		  "xor %%g2, %%o4, %%g2\n\t"
136 		  "xor %%g3, %%o5, %%g3\n\t"
137 		  "ldd [%3 + 0x00], %%o4\n\t"
138 		  "xor %%g4, %%l0, %%g4\n\t"
139 		  "xor %%g5, %%l1, %%g5\n\t"
140 		  "ldd [%3 + 0x08], %%l0\n\t"
141 		  "xor %%o0, %%l2, %%o0\n\t"
142 		  "xor %%o1, %%l3, %%o1\n\t"
143 		  "ldd [%3 + 0x10], %%l2\n\t"
144 		  "xor %%o2, %%l4, %%o2\n\t"
145 		  "xor %%o3, %%l5, %%o3\n\t"
146 		  "ldd [%3 + 0x18], %%l4\n\t"
147 		  "xor %%g2, %%o4, %%g2\n\t"
148 		  "xor %%g3, %%o5, %%g3\n\t"
149 		  "xor %%g4, %%l0, %%g4\n\t"
150 		  "xor %%g5, %%l1, %%g5\n\t"
151 		  "xor %%o0, %%l2, %%o0\n\t"
152 		  "xor %%o1, %%l3, %%o1\n\t"
153 		  "xor %%o2, %%l4, %%o2\n\t"
154 		  "xor %%o3, %%l5, %%o3\n\t"
155 		  "std %%g2, [%0 + 0x00]\n\t"
156 		  "std %%g4, [%0 + 0x08]\n\t"
157 		  "std %%o0, [%0 + 0x10]\n\t"
158 		  "std %%o2, [%0 + 0x18]\n"
159 		:
160 		: "r" (p1), "r" (p2), "r" (p3), "r" (p4)
161 		: "g2", "g3", "g4", "g5",
162 		  "o0", "o1", "o2", "o3", "o4", "o5",
163 		  "l0", "l1", "l2", "l3", "l4", "l5");
164 		p1 += 8;
165 		p2 += 8;
166 		p3 += 8;
167 		p4 += 8;
168 	} while (--lines > 0);
169 }
170 
171 static void
sparc_5(unsigned long bytes,unsigned long * __restrict p1,const unsigned long * __restrict p2,const unsigned long * __restrict p3,const unsigned long * __restrict p4,const unsigned long * __restrict p5)172 sparc_5(unsigned long bytes, unsigned long * __restrict p1,
173 	const unsigned long * __restrict p2,
174 	const unsigned long * __restrict p3,
175 	const unsigned long * __restrict p4,
176 	const unsigned long * __restrict p5)
177 {
178 	int lines = bytes / (sizeof (long)) / 8;
179 
180 	do {
181 		__asm__ __volatile__(
182 		  "ldd [%0 + 0x00], %%g2\n\t"
183 		  "ldd [%0 + 0x08], %%g4\n\t"
184 		  "ldd [%0 + 0x10], %%o0\n\t"
185 		  "ldd [%0 + 0x18], %%o2\n\t"
186 		  "ldd [%1 + 0x00], %%o4\n\t"
187 		  "ldd [%1 + 0x08], %%l0\n\t"
188 		  "ldd [%1 + 0x10], %%l2\n\t"
189 		  "ldd [%1 + 0x18], %%l4\n\t"
190 		  "xor %%g2, %%o4, %%g2\n\t"
191 		  "xor %%g3, %%o5, %%g3\n\t"
192 		  "ldd [%2 + 0x00], %%o4\n\t"
193 		  "xor %%g4, %%l0, %%g4\n\t"
194 		  "xor %%g5, %%l1, %%g5\n\t"
195 		  "ldd [%2 + 0x08], %%l0\n\t"
196 		  "xor %%o0, %%l2, %%o0\n\t"
197 		  "xor %%o1, %%l3, %%o1\n\t"
198 		  "ldd [%2 + 0x10], %%l2\n\t"
199 		  "xor %%o2, %%l4, %%o2\n\t"
200 		  "xor %%o3, %%l5, %%o3\n\t"
201 		  "ldd [%2 + 0x18], %%l4\n\t"
202 		  "xor %%g2, %%o4, %%g2\n\t"
203 		  "xor %%g3, %%o5, %%g3\n\t"
204 		  "ldd [%3 + 0x00], %%o4\n\t"
205 		  "xor %%g4, %%l0, %%g4\n\t"
206 		  "xor %%g5, %%l1, %%g5\n\t"
207 		  "ldd [%3 + 0x08], %%l0\n\t"
208 		  "xor %%o0, %%l2, %%o0\n\t"
209 		  "xor %%o1, %%l3, %%o1\n\t"
210 		  "ldd [%3 + 0x10], %%l2\n\t"
211 		  "xor %%o2, %%l4, %%o2\n\t"
212 		  "xor %%o3, %%l5, %%o3\n\t"
213 		  "ldd [%3 + 0x18], %%l4\n\t"
214 		  "xor %%g2, %%o4, %%g2\n\t"
215 		  "xor %%g3, %%o5, %%g3\n\t"
216 		  "ldd [%4 + 0x00], %%o4\n\t"
217 		  "xor %%g4, %%l0, %%g4\n\t"
218 		  "xor %%g5, %%l1, %%g5\n\t"
219 		  "ldd [%4 + 0x08], %%l0\n\t"
220 		  "xor %%o0, %%l2, %%o0\n\t"
221 		  "xor %%o1, %%l3, %%o1\n\t"
222 		  "ldd [%4 + 0x10], %%l2\n\t"
223 		  "xor %%o2, %%l4, %%o2\n\t"
224 		  "xor %%o3, %%l5, %%o3\n\t"
225 		  "ldd [%4 + 0x18], %%l4\n\t"
226 		  "xor %%g2, %%o4, %%g2\n\t"
227 		  "xor %%g3, %%o5, %%g3\n\t"
228 		  "xor %%g4, %%l0, %%g4\n\t"
229 		  "xor %%g5, %%l1, %%g5\n\t"
230 		  "xor %%o0, %%l2, %%o0\n\t"
231 		  "xor %%o1, %%l3, %%o1\n\t"
232 		  "xor %%o2, %%l4, %%o2\n\t"
233 		  "xor %%o3, %%l5, %%o3\n\t"
234 		  "std %%g2, [%0 + 0x00]\n\t"
235 		  "std %%g4, [%0 + 0x08]\n\t"
236 		  "std %%o0, [%0 + 0x10]\n\t"
237 		  "std %%o2, [%0 + 0x18]\n"
238 		:
239 		: "r" (p1), "r" (p2), "r" (p3), "r" (p4), "r" (p5)
240 		: "g2", "g3", "g4", "g5",
241 		  "o0", "o1", "o2", "o3", "o4", "o5",
242 		  "l0", "l1", "l2", "l3", "l4", "l5");
243 		p1 += 8;
244 		p2 += 8;
245 		p3 += 8;
246 		p4 += 8;
247 		p5 += 8;
248 	} while (--lines > 0);
249 }
250 
251 static struct xor_block_template xor_block_SPARC = {
252 	.name	= "SPARC",
253 	.do_2	= sparc_2,
254 	.do_3	= sparc_3,
255 	.do_4	= sparc_4,
256 	.do_5	= sparc_5,
257 };
258 
259 /* For grins, also test the generic routines.  */
260 #include <asm-generic/xor.h>
261 
262 #undef XOR_TRY_TEMPLATES
263 #define XOR_TRY_TEMPLATES				\
264 	do {						\
265 		xor_speed(&xor_block_8regs);		\
266 		xor_speed(&xor_block_32regs);		\
267 		xor_speed(&xor_block_SPARC);		\
268 	} while (0)
269