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