Remove stream CRC and optimize CRC compute CRC32C using two lanes

This commit is contained in:
Andrea Mazzoleni 2026-09-10 07:39:21 +02:00
parent 581ec4e156
commit a01ec45f14
7 changed files with 196 additions and 129 deletions

View file

@ -398,8 +398,68 @@ uint32_t CRC32C_3[256] = {
0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842
};
#if CONFIG_X86
int crc_x86;
#if CONFIG_X86 || CONFIG_ARM_CRC
static uint32_t crc32c_shift_table[sizeof(size_t) * 8][32];
static uint32_t crc32c_matrix_times(const uint32_t* matrix, uint32_t vector)
{
uint32_t value = 0;
while (vector) {
if (vector & 1)
value ^= *matrix;
vector >>= 1;
++matrix;
}
return value;
}
static void crc32c_matrix_square(uint32_t* square, const uint32_t* matrix)
{
unsigned i;
for (i = 0; i < 32; ++i)
square[i] = crc32c_matrix_times(matrix, matrix[i]);
}
static void crc32c_shift_init(void)
{
uint32_t matrix[32];
uint32_t square[32];
uint32_t row;
unsigned i;
/* reflected Castagnoli polynomial, represented as one zero-bit operator. */
matrix[0] = 0x82f63b78;
row = 1;
for (i = 1; i < 32; ++i) {
matrix[i] = row;
row <<= 1;
}
/* square three times to obtain the operator for one zero byte. */
crc32c_matrix_square(square, matrix);
crc32c_matrix_square(matrix, square);
crc32c_matrix_square(crc32c_shift_table[0], matrix);
for (i = 1; i < sizeof(size_t) * 8; ++i)
crc32c_matrix_square(crc32c_shift_table[i], crc32c_shift_table[i - 1]);
}
uint32_t crc32c_shift(uint32_t crc, size_t size)
{
unsigned i = 0;
while (size) {
if (size & 1)
crc = crc32c_matrix_times(crc32c_shift_table[i], crc);
size >>= 1;
++i;
}
return crc;
}
#endif
uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, size_t size)
@ -446,10 +506,14 @@ void crc32c_init(void)
crc32c = crc32c_gen;
#if CONFIG_X86
if (raid_cpu_has_crc32()) {
crc_x86 = 1;
crc32c_shift_init();
crc32c = crc32c_x86;
}
#endif
#if CONFIG_ARM_CRC
crc32c_shift_init();
crc32c = crc32c_arm64;
#endif
}
/****************************************************************************/