Branch data Line data Source code
1 : : /* -*- linux-c -*- ------------------------------------------------------- *
2 : : *
3 : : * Copyright 2002-2004 H. Peter Anvin - All Rights Reserved
4 : : *
5 : : * This program is free software; you can redistribute it and/or modify
6 : : * it under the terms of the GNU General Public License as published by
7 : : * the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 : : * Boston MA 02111-1307, USA; either version 2 of the License, or
9 : : * (at your option) any later version; incorporated herein by reference.
10 : : *
11 : : * ----------------------------------------------------------------------- */
12 : :
13 : : /*
14 : : * int8.c
15 : : *
16 : : * 8-way unrolled portable integer math RAID-6 instruction set
17 : : *
18 : : * This file is postprocessed using unroll.awk
19 : : */
20 : :
21 : : #include <linux/raid/pq.h>
22 : :
23 : : /*
24 : : * This is the C data type to use
25 : : */
26 : :
27 : : /* Change this from BITS_PER_LONG if there is something better... */
28 : : #if BITS_PER_LONG == 64
29 : : # define NBYTES(x) ((x) * 0x0101010101010101UL)
30 : : # define NSIZE 8
31 : : # define NSHIFT 3
32 : : # define NSTRING "64"
33 : : typedef u64 unative_t;
34 : : #else
35 : : # define NBYTES(x) ((x) * 0x01010101U)
36 : : # define NSIZE 4
37 : : # define NSHIFT 2
38 : : # define NSTRING "32"
39 : : typedef u32 unative_t;
40 : : #endif
41 : :
42 : :
43 : :
44 : : /*
45 : : * IA-64 wants insane amounts of unrolling. On other architectures that
46 : : * is just a waste of space.
47 : : */
48 : : #if (8 <= 8) || defined(__ia64__)
49 : :
50 : :
51 : : /*
52 : : * These sub-operations are separate inlines since they can sometimes be
53 : : * specially optimized using architecture-specific hacks.
54 : : */
55 : :
56 : : /*
57 : : * The SHLBYTE() operation shifts each byte left by 1, *not*
58 : : * rolling over into the next byte
59 : : */
60 : : static inline __attribute_const__ unative_t SHLBYTE(unative_t v)
61 : : {
62 : : unative_t vv;
63 : :
64 : 0 : vv = (v << 1) & NBYTES(0xfe);
65 : : return vv;
66 : : }
67 : :
68 : : /*
69 : : * The MASK() operation returns 0xFF in any byte for which the high
70 : : * bit is 1, 0x00 for any byte for which the high bit is 0.
71 : : */
72 : : static inline __attribute_const__ unative_t MASK(unative_t v)
73 : : {
74 : : unative_t vv;
75 : :
76 : 0 : vv = v & NBYTES(0x80);
77 : 0 : vv = (vv << 1) - (vv >> 7); /* Overflow on the top bit is OK */
78 : : return vv;
79 : : }
80 : :
81 : :
82 : 0 : static void raid6_int8_gen_syndrome(int disks, size_t bytes, void **ptrs)
83 : : {
84 : : u8 **dptr = (u8 **)ptrs;
85 : : u8 *p, *q;
86 : : int d, z, z0;
87 : :
88 : : unative_t wd0, wq0, wp0, w10, w20;
89 : : unative_t wd1, wq1, wp1, w11, w21;
90 : : unative_t wd2, wq2, wp2, w12, w22;
91 : : unative_t wd3, wq3, wp3, w13, w23;
92 : : unative_t wd4, wq4, wp4, w14, w24;
93 : : unative_t wd5, wq5, wp5, w15, w25;
94 : : unative_t wd6, wq6, wp6, w16, w26;
95 : : unative_t wd7, wq7, wp7, w17, w27;
96 : :
97 : 0 : z0 = disks - 3; /* Highest data disk */
98 : 0 : p = dptr[z0+1]; /* XOR parity */
99 : 0 : q = dptr[z0+2]; /* RS syndrome */
100 : :
101 [ # # ]: 0 : for ( d = 0 ; d < bytes ; d += NSIZE*8 ) {
102 : 0 : wq0 = wp0 = *(unative_t *)&dptr[z0][d+0*NSIZE];
103 : 0 : wq1 = wp1 = *(unative_t *)&dptr[z0][d+1*NSIZE];
104 : 0 : wq2 = wp2 = *(unative_t *)&dptr[z0][d+2*NSIZE];
105 : 0 : wq3 = wp3 = *(unative_t *)&dptr[z0][d+3*NSIZE];
106 : 0 : wq4 = wp4 = *(unative_t *)&dptr[z0][d+4*NSIZE];
107 : 0 : wq5 = wp5 = *(unative_t *)&dptr[z0][d+5*NSIZE];
108 : 0 : wq6 = wp6 = *(unative_t *)&dptr[z0][d+6*NSIZE];
109 : 0 : wq7 = wp7 = *(unative_t *)&dptr[z0][d+7*NSIZE];
110 [ # # ]: 0 : for ( z = z0-1 ; z >= 0 ; z-- ) {
111 : 0 : wd0 = *(unative_t *)&dptr[z][d+0*NSIZE];
112 : 0 : wd1 = *(unative_t *)&dptr[z][d+1*NSIZE];
113 : 0 : wd2 = *(unative_t *)&dptr[z][d+2*NSIZE];
114 : 0 : wd3 = *(unative_t *)&dptr[z][d+3*NSIZE];
115 : 0 : wd4 = *(unative_t *)&dptr[z][d+4*NSIZE];
116 : 0 : wd5 = *(unative_t *)&dptr[z][d+5*NSIZE];
117 : 0 : wd6 = *(unative_t *)&dptr[z][d+6*NSIZE];
118 : 0 : wd7 = *(unative_t *)&dptr[z][d+7*NSIZE];
119 : 0 : wp0 ^= wd0;
120 : 0 : wp1 ^= wd1;
121 : 0 : wp2 ^= wd2;
122 : 0 : wp3 ^= wd3;
123 : 0 : wp4 ^= wd4;
124 : 0 : wp5 ^= wd5;
125 : 0 : wp6 ^= wd6;
126 : 0 : wp7 ^= wd7;
127 : : w20 = MASK(wq0);
128 : : w21 = MASK(wq1);
129 : : w22 = MASK(wq2);
130 : : w23 = MASK(wq3);
131 : : w24 = MASK(wq4);
132 : : w25 = MASK(wq5);
133 : : w26 = MASK(wq6);
134 : : w27 = MASK(wq7);
135 : : w10 = SHLBYTE(wq0);
136 : : w11 = SHLBYTE(wq1);
137 : : w12 = SHLBYTE(wq2);
138 : : w13 = SHLBYTE(wq3);
139 : : w14 = SHLBYTE(wq4);
140 : : w15 = SHLBYTE(wq5);
141 : : w16 = SHLBYTE(wq6);
142 : : w17 = SHLBYTE(wq7);
143 : 0 : w20 &= NBYTES(0x1d);
144 : 0 : w21 &= NBYTES(0x1d);
145 : 0 : w22 &= NBYTES(0x1d);
146 : 0 : w23 &= NBYTES(0x1d);
147 : 0 : w24 &= NBYTES(0x1d);
148 : 0 : w25 &= NBYTES(0x1d);
149 : 0 : w26 &= NBYTES(0x1d);
150 : 0 : w27 &= NBYTES(0x1d);
151 : 0 : w10 ^= w20;
152 : 0 : w11 ^= w21;
153 : 0 : w12 ^= w22;
154 : 0 : w13 ^= w23;
155 : 0 : w14 ^= w24;
156 : 0 : w15 ^= w25;
157 : 0 : w16 ^= w26;
158 : 0 : w17 ^= w27;
159 : 0 : wq0 = w10 ^ wd0;
160 : 0 : wq1 = w11 ^ wd1;
161 : 0 : wq2 = w12 ^ wd2;
162 : 0 : wq3 = w13 ^ wd3;
163 : 0 : wq4 = w14 ^ wd4;
164 : 0 : wq5 = w15 ^ wd5;
165 : 0 : wq6 = w16 ^ wd6;
166 : 0 : wq7 = w17 ^ wd7;
167 : : }
168 : 0 : *(unative_t *)&p[d+NSIZE*0] = wp0;
169 : 0 : *(unative_t *)&p[d+NSIZE*1] = wp1;
170 : 0 : *(unative_t *)&p[d+NSIZE*2] = wp2;
171 : 0 : *(unative_t *)&p[d+NSIZE*3] = wp3;
172 : 0 : *(unative_t *)&p[d+NSIZE*4] = wp4;
173 : 0 : *(unative_t *)&p[d+NSIZE*5] = wp5;
174 : 0 : *(unative_t *)&p[d+NSIZE*6] = wp6;
175 : 0 : *(unative_t *)&p[d+NSIZE*7] = wp7;
176 : 0 : *(unative_t *)&q[d+NSIZE*0] = wq0;
177 : 0 : *(unative_t *)&q[d+NSIZE*1] = wq1;
178 : 0 : *(unative_t *)&q[d+NSIZE*2] = wq2;
179 : 0 : *(unative_t *)&q[d+NSIZE*3] = wq3;
180 : 0 : *(unative_t *)&q[d+NSIZE*4] = wq4;
181 : 0 : *(unative_t *)&q[d+NSIZE*5] = wq5;
182 : 0 : *(unative_t *)&q[d+NSIZE*6] = wq6;
183 : 0 : *(unative_t *)&q[d+NSIZE*7] = wq7;
184 : : }
185 : 0 : }
186 : :
187 : : const struct raid6_calls raid6_intx8 = {
188 : : raid6_int8_gen_syndrome,
189 : : NULL, /* always valid */
190 : : "int" NSTRING "x8",
191 : : 0
192 : : };
193 : :
194 : : #endif
|