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