Import Upstream version 12.4

This commit is contained in:
geos_one
2025-08-12 21:36:56 +02:00
parent 1aa8d4d499
commit 345149210e
52 changed files with 1545 additions and 16196 deletions

View File

@@ -1,12 +1,12 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
@@ -15,7 +15,7 @@ software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
@@ -55,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
@@ -110,7 +110,7 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@@ -168,7 +168,7 @@ access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@@ -225,7 +225,7 @@ impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@@ -255,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
@@ -277,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
@@ -291,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -303,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
@@ -335,5 +335,6 @@ necessary. Here is a sample; alter the names:
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

428
raid/mktables.c Normal file
View File

@@ -0,0 +1,428 @@
/*
* Copyright (C) 2013 Andrea Mazzoleni
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <stdio.h>
#include <stdint.h>
/**
* Multiplication a*b in GF(2^8).
*/
static uint8_t gfmul(uint8_t a, uint8_t b)
{
uint8_t v;
v = 0;
while (b) {
if ((b & 1) != 0)
v ^= a;
if ((a & 0x80) != 0) {
a <<= 1;
a ^= 0x1d;
} else {
a <<= 1;
}
b >>= 1;
}
return v;
}
/**
* Inversion (1/a) in GF(2^8).
*/
uint8_t gfinv[256];
/**
* Number of parities.
* This is the number of rows of the generator matrix.
*/
#define PARITY 6
/**
* Number of disks.
* This is the number of columns of the generator matrix.
*/
#define DISK (257 - PARITY)
/**
* Setup the Cauchy matrix used to generate the parity.
*/
static void set_cauchy(uint8_t *matrix)
{
int i, j;
uint8_t inv_x, y;
/*
* The first row of the generator matrix is formed by all 1.
*
* The generator matrix is an Extended Cauchy matrix built from
* a Cauchy matrix adding at the top a row of all 1.
*
* Extending a Cauchy matrix in this way maintains the MDS property
* of the matrix.
*
* For example, considering a generator matrix of 4x6 we have now:
*
* 1 1 1 1 1 1
* - - - - - -
* - - - - - -
* - - - - - -
*/
for (i = 0; i < DISK; ++i)
matrix[0 * DISK + i] = 1;
/*
* Second row is formed with powers 2^i, and it's the first
* row of the Cauchy matrix.
*
* Each element of the Cauchy matrix is in the form 1/(x_i + y_j)
* where all x_i and y_j must be different for any i and j.
*
* For the first row with j=0, we choose x_i = 2^-i and y_0 = 0
* and we obtain a first row formed as:
*
* 1/(x_i + y_0) = 1/(2^-i + 0) = 2^i
*
* with 2^-i != 0 for any i
*
* In the example we get:
*
* x_0 = 1
* x_1 = 142
* x_2 = 71
* x_3 = 173
* x_4 = 216
* x_5 = 108
* y_0 = 0
*
* with the matrix:
*
* 1 1 1 1 1 1
* 1 2 4 8 16 32
* - - - - - -
* - - - - - -
*/
inv_x = 1;
for (i = 0; i < DISK; ++i) {
matrix[1 * DISK + i] = inv_x;
inv_x = gfmul(2, inv_x);
}
/*
* The rest of the Cauchy matrix is formed choosing for each row j
* a new y_j = 2^j and reusing the x_i already assigned in the first
* row obtaining :
*
* 1/(x_i + y_j) = 1/(2^-i + 2^j)
*
* with 2^-i + 2^j != 0 for any i,j with i>=0,j>=1,i+j<255
*
* In the example we get:
*
* y_1 = 2
* y_2 = 4
*
* with the matrix:
*
* 1 1 1 1 1 1
* 1 2 4 8 16 32
* 244 83 78 183 118 47
* 167 39 213 59 153 82
*/
y = 2;
for (j = 0; j < PARITY - 2; ++j) {
inv_x = 1;
for (i = 0; i < DISK; ++i) {
uint8_t x = gfinv[inv_x];
matrix[(j + 2) * DISK + i] = gfinv[y ^ x];
inv_x = gfmul(2, inv_x);
}
y = gfmul(2, y);
}
/*
* Finally we adjust the matrix multiplying each row for
* the inverse of the first element in the row.
*
* Also this operation maintains the MDS property of the matrix.
*
* Resulting in:
*
* 1 1 1 1 1 1
* 1 2 4 8 16 32
* 1 245 210 196 154 113
* 1 187 166 215 7 106
*/
for (j = 0; j < PARITY - 2; ++j) {
uint8_t f = gfinv[matrix[(j + 2) * DISK]];
for (i = 0; i < DISK; ++i)
matrix[(j + 2) * DISK + i] = gfmul(matrix[(j + 2) * DISK + i], f);
}
}
/**
* Setup the Power matrix used to generate the parity.
*/
static void set_power(uint8_t *matrix)
{
unsigned i;
uint8_t v;
v = 1;
for (i = 0; i < DISK; ++i)
matrix[0 * DISK + i] = v;
v = 1;
for (i = 0; i < DISK; ++i) {
matrix[1 * DISK + i] = v;
v = gfmul(2, v);
}
v = 1;
for (i = 0; i < DISK; ++i) {
matrix[2 * DISK + i] = v;
v = gfmul(0x8e, v);
}
}
/**
* Next power of 2.
*/
static unsigned np(unsigned v)
{
--v;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
++v;
return v;
}
int main(void)
{
uint8_t v;
int i, j, k, p;
uint8_t matrix[PARITY * 256];
printf("/*\n");
printf(" * Copyright (C) 2013 Andrea Mazzoleni\n");
printf(" *\n");
printf(" * This program is free software: you can redistribute it and/or modify\n");
printf(" * it under the terms of the GNU General Public License as published by\n");
printf(" * the Free Software Foundation, either version 2 of the License, or\n");
printf(" * (at your option) any later version.\n");
printf(" *\n");
printf(" * This program is distributed in the hope that it will be useful,\n");
printf(" * but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
printf(" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
printf(" * GNU General Public License for more details.\n");
printf(" */\n");
printf("\n");
printf("#include \"internal.h\"\n");
printf("\n");
/* a*b */
printf("const uint8_t __aligned(256) raid_gfmul[256][256] =\n");
printf("{\n");
for (i = 0; i < 256; ++i) {
printf("\t{\n");
for (j = 0; j < 256; ++j) {
if (j % 8 == 0)
printf("\t\t");
v = gfmul(i, j);
if (v == 1)
gfinv[i] = j;
printf("0x%02x,", (unsigned)v);
if (j % 8 == 7)
printf("\n");
else
printf(" ");
}
printf("\t},\n");
}
printf("};\n\n");
/* 2^a */
printf("const uint8_t __aligned(256) raid_gfexp[256] =\n");
printf("{\n");
v = 1;
for (i = 0; i < 256; ++i) {
if (i % 8 == 0)
printf("\t");
printf("0x%02x,", v);
v = gfmul(v, 2);
if (i % 8 == 7)
printf("\n");
else
printf(" ");
}
printf("};\n\n");
/* 1/a */
printf("const uint8_t __aligned(256) raid_gfinv[256] =\n");
printf("{\n");
printf("\t/* note that the first element is not significative */\n");
for (i = 0; i < 256; ++i) {
if (i % 8 == 0)
printf("\t");
if (i == 0)
v = 0;
else
v = gfinv[i];
printf("0x%02x,", v);
if (i % 8 == 7)
printf("\n");
else
printf(" ");
}
printf("};\n\n");
/* power matrix */
set_power(matrix);
printf("/**\n");
printf(" * Power matrix used to generate parity.\n");
printf(" * This matrix is valid for up to %u parity with %u data disks.\n", 3, DISK);
printf(" *\n");
for (p = 0; p < 3; ++p) {
printf(" *");
for (i = 0; i < DISK; ++i)
printf(" %02x", matrix[p * DISK + i]);
printf("\n");
}
printf(" */\n");
printf("const uint8_t __aligned(256) raid_gfvandermonde[%u][256] =\n", 3);
printf("{\n");
for (p = 0; p < 3; ++p) {
printf("\t{\n");
for (i = 0; i < DISK; ++i) {
if (i % 8 == 0)
printf("\t\t");
printf("0x%02x,", matrix[p * DISK + i]);
if (i != DISK - 1) {
if (i % 8 == 7)
printf("\n");
else
printf(" ");
}
}
printf("\n\t},\n");
}
printf("};\n\n");
/* cauchy matrix */
set_cauchy(matrix);
printf("/**\n");
printf(" * Cauchy matrix used to generate parity.\n");
printf(" * This matrix is valid for up to %u parity with %u data disks.\n", PARITY, DISK);
printf(" *\n");
for (p = 0; p < PARITY; ++p) {
printf(" *");
for (i = 0; i < DISK; ++i)
printf(" %02x", matrix[p * DISK + i]);
printf("\n");
}
printf(" */\n");
printf("const uint8_t __aligned(256) raid_gfcauchy[%u][256] =\n", PARITY);
printf("{\n");
for (p = 0; p < PARITY; ++p) {
printf("\t{\n");
for (i = 0; i < DISK; ++i) {
if (i % 8 == 0)
printf("\t\t");
printf("0x%02x,", matrix[p * DISK + i]);
if (i != DISK - 1) {
if (i % 8 == 7)
printf("\n");
else
printf(" ");
}
}
printf("\n\t},\n");
}
printf("};\n\n");
printf("#ifdef CONFIG_X86\n");
printf("/**\n");
printf(" * PSHUFB tables for the Cauchy matrix.\n");
printf(" *\n");
printf(" * Indexes are [DISK][PARITY - 2][LH].\n");
printf(" * Where DISK is from 0 to %u, PARITY from 2 to %u, LH from 0 to 1.\n", DISK - 1, PARITY - 1);
printf(" */\n");
printf("const uint8_t __aligned(256) raid_gfcauchypshufb[%u][%u][2][16] =\n", DISK, np(PARITY - 2));
printf("{\n");
for (i = 0; i < DISK; ++i) {
printf("\t{\n");
for (p = 2; p < PARITY; ++p) {
printf("\t\t{\n");
for (j = 0; j < 2; ++j) {
printf("\t\t\t{ ");
for (k = 0; k < 16; ++k) {
v = gfmul(matrix[p * DISK + i], k);
if (j == 1)
v = gfmul(v, 16);
printf("0x%02x", (unsigned)v);
if (k != 15)
printf(", ");
}
printf(" },\n");
}
printf("\t\t},\n");
}
printf("\t},\n");
}
printf("};\n");
printf("#endif\n\n");
printf("#ifdef CONFIG_X86\n");
printf("/**\n");
printf(" * PSHUFB tables for generic multiplication.\n");
printf(" *\n");
printf(" * Indexes are [MULTIPLIER][LH].\n");
printf(" * Where MULTIPLIER is from 0 to 255, LH from 0 to 1.\n");
printf(" */\n");
printf("const uint8_t __aligned(256) raid_gfmulpshufb[256][2][16] =\n");
printf("{\n");
for (i = 0; i < 256; ++i) {
printf("\t{\n");
for (j = 0; j < 2; ++j) {
printf("\t\t{ ");
for (k = 0; k < 16; ++k) {
v = gfmul(i, k);
if (j == 1)
v = gfmul(v, 16);
printf("0x%02x", (unsigned)v);
if (k != 15)
printf(", ");
}
printf(" },\n");
}
printf("\t},\n");
}
printf("};\n");
printf("#endif\n\n");
return 0;
}

View File

@@ -20,50 +20,50 @@
* the primitive polynomial x^8 + x^4 + x^3 + x^2 + 1 (285 decimal), and
* supporting up to six parity levels.
*
* For RAID5 and RAID6 it works as as described in the H. Peter Anvin's
* For RAID5 and RAID6, it works as described in H. Peter Anvin's
* paper "The mathematics of RAID-6" [1]. Please refer to this paper for a
* complete explanation.
*
* To support triple parity, it was first evaluated and then dropped, an
* To support triple parity, it was first evaluated and then dropped; an
* extension of the same approach, with additional parity coefficients set
* as powers of 2^-1, with equations:
*
* P = sum(Di)
* Q = sum(2^i * Di)
* R = sum(2^-i * Di) with 0<=i<N
* R = sum(2^-i * Di) with 0 <= i < N
*
* This approach works well for triple parity and it's very efficient,
* This approach works well for triple parity and is very efficient
* because we can implement very fast parallel multiplications and
* divisions by 2 in GF(2^8).
*
* It's also similar at the approach used by ZFS RAIDZ3, with the
* It is also similar to the approach used by ZFS RAIDZ3, with the
* difference that ZFS uses powers of 4 instead of 2^-1.
*
* Unfortunately it doesn't work beyond triple parity, because whatever
* Unfortunately, it doesn't work beyond triple parity because whatever
* value we choose to generate the power coefficients to compute other
* parities, the resulting equations are not solvable for some
* combinations of missing disks.
*
* This is expected, because the Vandermonde matrix used to compute the
* This is expected because the Vandermonde matrix used to compute the
* parity has no guarantee to have all submatrices not singular
* [2, Chap 11, Problem 7] and this is a requirement to have
* a MDS (Maximum Distance Separable) code [2, Chap 11, Theorem 8].
* [2, Chap 11, Problem 7], and this is a requirement to have
* an MDS (Maximum Distance Separable) code [2, Chap 11, Theorem 8].
*
* To overcome this limitation, we use a Cauchy matrix [3][4] to compute
* the parity. A Cauchy matrix has the property to have all the square
* submatrices not singular, resulting in always solvable equations,
* the parity. A Cauchy matrix has the property of having all square
* submatrices not singular, resulting in always solvable equations
* for any combination of missing disks.
*
* The problem of this approach is that it requires the use of
* The problem with this approach is that it requires the use of
* generic multiplications, and not only by 2 or 2^-1, potentially
* affecting badly the performance.
* affecting performance negatively.
*
* Hopefully there is a method to implement parallel multiplications
* using SSSE3 or AVX2 instructions [1][5]. Method competitive with the
* Hopefully, there is a method to implement parallel multiplications
* using SSSE3 or AVX2 instructions [1][5], a method competitive with the
* computation of triple parity using power coefficients.
*
* Another important property of the Cauchy matrix is that we can setup
* the first two rows with coefficients equal at the RAID5 and RAID6 approach
* Another important property of the Cauchy matrix is that we can set up
* the first two rows with coefficients equal to the RAID5 and RAID6 approach
* described, resulting in a compatible extension, and requiring SSSE3
* or AVX2 instructions only if triple parity or beyond is used.
*
@@ -71,7 +71,7 @@
* to make the first column of all 1, to optimize the computation for
* the first disk.
*
* This results in the matrix A[row,col] defined as:
* This results in the matrix A[row, col] defined as:
*
* 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01...
* 01 02 04 08 10 20 40 80 1d 3a 74 e8 cd 87 13 26 4c 98 2d 5a b4 75...
@@ -80,25 +80,25 @@
* 01 97 7f 9c 7c 18 bd a2 58 1a da 74 70 a3 e5 47 29 07 f5 80 23 e9...
* 01 2b 3f cf 73 2c d6 ed cb 74 15 78 8a c1 17 c9 89 68 21 ab 76 3b...
*
* This matrix supports 6 level of parity, one for each row, for up to 251
* This matrix supports 6 levels of parity, one for each row, for up to 251
* data disks, one for each column, with all the 377,342,351,231 square
* submatrices not singular, verified also with brute-force.
* submatrices not singular, verified also with brute force.
*
* This matrix can be extended to support any number of parities, just
* adding additional rows, and removing one column for each new row.
* (see mktables.c for more details in how the matrix is generated)
* adding additional rows and removing one column for each new row.
* (see mktables.c for more details on how the matrix is generated)
*
* In details, parity is computed as:
* In detail, parity is computed as:
*
* P = sum(Di)
* Q = sum(2^i * Di)
* Q = sum(2^i * Di)
* R = sum(A[2,i] * Di)
* S = sum(A[3,i] * Di)
* T = sum(A[4,i] * Di)
* U = sum(A[5,i] * Di) with 0<=i<N
* U = sum(A[5,i] * Di) with 0 <= i < N
*
* To recover from a failure of six disks at indexes x,y,z,h,v,w,
* with 0<=x<y<z<h<v<w<N, we compute the parity of the available N-6
* To recover from a failure of six disks at indexes x, y, z, h, v, w,
* with 0 <= x < y < z < h < v < w < N, we compute the parity of the available N-6
* disks as:
*
* Pa = sum(Di)
@@ -106,7 +106,7 @@
* Ra = sum(A[2,i] * Di)
* Sa = sum(A[3,i] * Di)
* Ta = sum(A[4,i] * Di)
* Ua = sum(A[5,i] * Di) with 0<=i<N,i!=x,i!=y,i!=z,i!=h,i!=v,i!=w.
* Ua = sum(A[5,i] * Di) with 0 <= i < N, i != x, i != y, i != z, i != h, i != v, i != w.
*
* And if we define:
*
@@ -126,13 +126,13 @@
* Td = A[4,x] * Dx + A[4,y] * Dy + A[4,z] * Dz + A[4,h] * Dh + A[4,v] * Dv + A[4,w] * Dw
* Ud = A[5,x] * Dx + A[5,y] * Dy + A[5,z] * Dz + A[5,h] * Dh + A[5,v] * Dv + A[5,w] * Dw
*
* A linear system always solvable because the coefficients matrix is
* always not singular due the properties of the matrix A[].
* A linear system is always solvable because the coefficients matrix is
* always not singular due to the properties of the matrix A[].
*
* Resulting speed in x64, with 8 data disks, using a stripe of 256 KiB,
* The resulting speed in x64, with 8 data disks, using a stripe of 256 KiB,
* for a Core i5-4670K Haswell Quad-Core 3.4GHz is:
*
* int8 int32 int64 sse2 ssse3 avx2
* int8 int32 int64 sse2 ssse3 avx2
* gen1 13339 25438 45438 50588
* gen2 4115 6514 21840 32201
* gen3 814 10154 18613
@@ -143,18 +143,18 @@
* Values are in MiB/s of data processed by a single thread, not counting
* generated parity.
*
* You can replicate these results in your machine using the
* You can replicate these results on your machine using the
* "raid/test/speedtest.c" program.
*
* For comparison, the triple parity computation using the power
* coefficients "1,2,2^-1" is only a little faster than the one based on
* the Cauchy matrix if SSSE3 or AVX2 is present.
*
* int8 int32 int64 sse2 ssse3 avx2
* int8 int32 int64 sse2 ssse3 avx2
* genz 2337 2874 10920 18944
*
* In conclusion, the use of power coefficients, and specifically powers
* of 1,2,2^-1, is the best option to implement triple parity in CPUs
* of 1, 2, 2^-1, is the best option to implement triple parity in CPUs
* without SSSE3 and AVX2.
* But if a modern CPU with SSSE3 or AVX2 is available, the Cauchy
* matrix is the best option because it provides a fast and general

View File

@@ -14,76 +14,78 @@
#include "internal.h"
typedef void (void_f)(void);
static struct raid_func {
const char *name;
void (*p)();
void_f* func;
} RAID_FUNC[] = {
{ "int8", raid_gen3_int8 },
{ "int8", raid_gen4_int8 },
{ "int8", raid_gen5_int8 },
{ "int8", raid_gen6_int8 },
{ "int32", raid_gen1_int32 },
{ "int64", raid_gen1_int64 },
{ "int32", raid_gen2_int32 },
{ "int64", raid_gen2_int64 },
{ "int32", raid_genz_int32 },
{ "int64", raid_genz_int64 },
{ "int8", raid_rec1_int8 },
{ "int8", raid_rec2_int8 },
{ "int8", raid_recX_int8 },
{ "int8", (void_f*)raid_gen3_int8 },
{ "int8", (void_f*)raid_gen4_int8 },
{ "int8", (void_f*)raid_gen5_int8 },
{ "int8", (void_f*)raid_gen6_int8 },
{ "int32", (void_f*)raid_gen1_int32 },
{ "int64", (void_f*)raid_gen1_int64 },
{ "int32", (void_f*)raid_gen2_int32 },
{ "int64", (void_f*)raid_gen2_int64 },
{ "int32", (void_f*)raid_genz_int32 },
{ "int64", (void_f*)raid_genz_int64 },
{ "int8", (void_f*)raid_rec1_int8 },
{ "int8", (void_f*)raid_rec2_int8 },
{ "int8", (void_f*)raid_recX_int8 },
#ifdef CONFIG_X86
#ifdef CONFIG_SSE2
{ "sse2", raid_gen1_sse2 },
{ "sse2", raid_gen2_sse2 },
{ "sse2", raid_genz_sse2 },
{ "sse2", (void_f*)raid_gen1_sse2 },
{ "sse2", (void_f*)raid_gen2_sse2 },
{ "sse2", (void_f*)raid_genz_sse2 },
#endif
#ifdef CONFIG_SSSE3
{ "ssse3", raid_gen3_ssse3 },
{ "ssse3", raid_gen4_ssse3 },
{ "ssse3", raid_gen5_ssse3 },
{ "ssse3", raid_gen6_ssse3 },
{ "ssse3", raid_rec1_ssse3 },
{ "ssse3", raid_rec2_ssse3 },
{ "ssse3", raid_recX_ssse3 },
{ "ssse3", (void_f*)raid_gen3_ssse3 },
{ "ssse3", (void_f*)raid_gen4_ssse3 },
{ "ssse3", (void_f*)raid_gen5_ssse3 },
{ "ssse3", (void_f*)raid_gen6_ssse3 },
{ "ssse3", (void_f*)raid_rec1_ssse3 },
{ "ssse3", (void_f*)raid_rec2_ssse3 },
{ "ssse3", (void_f*)raid_recX_ssse3 },
#endif
#ifdef CONFIG_AVX2
{ "avx2", raid_gen1_avx2 },
{ "avx2", raid_gen2_avx2 },
{ "avx2", raid_rec1_avx2 },
{ "avx2", raid_rec2_avx2 },
{ "avx2", raid_recX_avx2 },
{ "avx2", (void_f*)raid_gen1_avx2 },
{ "avx2", (void_f*)raid_gen2_avx2 },
{ "avx2", (void_f*)raid_rec1_avx2 },
{ "avx2", (void_f*)raid_rec2_avx2 },
{ "avx2", (void_f*)raid_recX_avx2 },
#endif
#endif
#ifdef CONFIG_X86_64
#ifdef CONFIG_SSE2
{ "sse2e", raid_gen2_sse2ext },
{ "sse2e", raid_genz_sse2ext },
{ "sse2e", (void_f*)raid_gen2_sse2ext },
{ "sse2e", (void_f*)raid_genz_sse2ext },
#endif
#ifdef CONFIG_SSSE3
{ "ssse3e", raid_gen3_ssse3ext },
{ "ssse3e", raid_gen4_ssse3ext },
{ "ssse3e", raid_gen5_ssse3ext },
{ "ssse3e", raid_gen6_ssse3ext },
{ "ssse3e", (void_f*)raid_gen3_ssse3ext },
{ "ssse3e", (void_f*)raid_gen4_ssse3ext },
{ "ssse3e", (void_f*)raid_gen5_ssse3ext },
{ "ssse3e", (void_f*)raid_gen6_ssse3ext },
#endif
#ifdef CONFIG_AVX2
{ "avx2e", raid_gen3_avx2ext },
{ "avx2e", raid_genz_avx2ext },
{ "avx2e", raid_gen4_avx2ext },
{ "avx2e", raid_gen5_avx2ext },
{ "avx2e", raid_gen6_avx2ext },
{ "avx2e", (void_f*)raid_gen3_avx2ext },
{ "avx2e", (void_f*)raid_genz_avx2ext },
{ "avx2e", (void_f*)raid_gen4_avx2ext },
{ "avx2e", (void_f*)raid_gen5_avx2ext },
{ "avx2e", (void_f*)raid_gen6_avx2ext },
#endif
#endif
{ 0, 0 }
};
static const char *raid_tag(void (*func)())
static const char *raid_tag(void_f* func)
{
struct raid_func *i = RAID_FUNC;
while (i->name != 0) {
if (i->p == func)
if (i->func == func)
return i->name;
++i;
}
@@ -95,51 +97,51 @@ static const char *raid_tag(void (*func)())
const char *raid_gen1_tag(void)
{
return raid_tag(raid_gen_ptr[0]);
return raid_tag((void_f*)raid_gen_ptr[0]);
}
const char *raid_gen2_tag(void)
{
return raid_tag(raid_gen_ptr[1]);
return raid_tag((void_f*)raid_gen_ptr[1]);
}
const char *raid_genz_tag(void)
{
return raid_tag(raid_genz_ptr);
return raid_tag((void_f*)raid_genz_ptr);
}
const char *raid_gen3_tag(void)
{
return raid_tag(raid_gen_ptr[2]);
return raid_tag((void_f*)raid_gen_ptr[2]);
}
const char *raid_gen4_tag(void)
{
return raid_tag(raid_gen_ptr[3]);
return raid_tag((void_f*)raid_gen_ptr[3]);
}
const char *raid_gen5_tag(void)
{
return raid_tag(raid_gen_ptr[4]);
return raid_tag((void_f*)raid_gen_ptr[4]);
}
const char *raid_gen6_tag(void)
{
return raid_tag(raid_gen_ptr[5]);
return raid_tag((void_f*)raid_gen_ptr[5]);
}
const char *raid_rec1_tag(void)
{
return raid_tag(raid_rec_ptr[0]);
return raid_tag((void_f*)raid_rec_ptr[0]);
}
const char *raid_rec2_tag(void)
{
return raid_tag(raid_rec_ptr[1]);
return raid_tag((void_f*)raid_rec_ptr[1]);
}
const char *raid_recX_tag(void)
{
return raid_tag(raid_rec_ptr[2]);
return raid_tag((void_f*)raid_rec_ptr[2]);
}