1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
/* XzCrc64.c -- CRC64 calculation
2023-12-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "XzCrc64.h"
#include "CpuArch.h"
#define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
// for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu
// #define Z7_CRC64_DEBUG_BE
#ifdef Z7_CRC64_DEBUG_BE
#undef MY_CPU_LE
#define MY_CPU_BE
#endif
#ifdef Z7_CRC64_NUM_TABLES
#define Z7_CRC64_NUM_TABLES_USE Z7_CRC64_NUM_TABLES
#else
#define Z7_CRC64_NUM_TABLES_USE 12
#endif
#if Z7_CRC64_NUM_TABLES_USE < 1
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
#endif
#if Z7_CRC64_NUM_TABLES_USE != 1
#ifndef MY_CPU_BE
#define FUNC_NAME_LE_2(s) XzCrc64UpdateT ## s
#define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s)
#define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC64_NUM_TABLES_USE)
UInt64 Z7_FASTCALL FUNC_NAME_LE (UInt64 v, const void *data, size_t size, const UInt64 *table);
#endif
#ifndef MY_CPU_LE
#define FUNC_NAME_BE_2(s) XzCrc64UpdateBeT ## s
#define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s)
#define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC64_NUM_TABLES_USE)
UInt64 Z7_FASTCALL FUNC_NAME_BE (UInt64 v, const void *data, size_t size, const UInt64 *table);
#endif
#if defined(MY_CPU_LE)
#define FUNC_REF FUNC_NAME_LE
#elif defined(MY_CPU_BE)
#define FUNC_REF FUNC_NAME_BE
#else
#define FUNC_REF g_Crc64Update
static UInt64 (Z7_FASTCALL *FUNC_REF)(UInt64 v, const void *data, size_t size, const UInt64 *table);
#endif
#endif
MY_ALIGN(64)
static UInt64 g_Crc64Table[256 * Z7_CRC64_NUM_TABLES_USE];
UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size)
{
#if Z7_CRC64_NUM_TABLES_USE == 1
#define CRC64_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
const UInt64 *table = g_Crc64Table;
const Byte *p = (const Byte *)data;
const Byte *lim = p + size;
for (; p != lim; p++)
v = CRC64_UPDATE_BYTE_2(v, *p);
return v;
#undef CRC64_UPDATE_BYTE_2
#else
return FUNC_REF (v, data, size, g_Crc64Table);
#endif
}
Z7_NO_INLINE
void Z7_FASTCALL Crc64GenerateTable(void)
{
unsigned i;
for (i = 0; i < 256; i++)
{
UInt64 r = i;
unsigned j;
for (j = 0; j < 8; j++)
r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1)));
g_Crc64Table[i] = r;
}
#if Z7_CRC64_NUM_TABLES_USE != 1
#if 1 || 1 && defined(MY_CPU_X86) // low register count
for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i++)
{
const UInt64 r0 = g_Crc64Table[(size_t)i];
g_Crc64Table[(size_t)i + 256] = g_Crc64Table[(Byte)r0] ^ (r0 >> 8);
}
#else
for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i += 2)
{
UInt64 r0 = g_Crc64Table[(size_t)(i) ];
UInt64 r1 = g_Crc64Table[(size_t)(i) + 1];
r0 = g_Crc64Table[(Byte)r0] ^ (r0 >> 8);
r1 = g_Crc64Table[(Byte)r1] ^ (r1 >> 8);
g_Crc64Table[(size_t)i + 256 ] = r0;
g_Crc64Table[(size_t)i + 256 + 1] = r1;
}
#endif
#ifndef MY_CPU_LE
{
#ifndef MY_CPU_BE
UInt32 k = 1;
if (*(const Byte *)&k == 1)
FUNC_REF = FUNC_NAME_LE;
else
#endif
{
#ifndef MY_CPU_BE
FUNC_REF = FUNC_NAME_BE;
#endif
for (i = 0; i < 256 * Z7_CRC64_NUM_TABLES_USE; i++)
{
const UInt64 x = g_Crc64Table[i];
g_Crc64Table[i] = Z7_BSWAP64(x);
}
}
}
#endif // ndef MY_CPU_LE
#endif // Z7_CRC64_NUM_TABLES_USE != 1
}
#undef kCrc64Poly
#undef Z7_CRC64_NUM_TABLES_USE
#undef FUNC_REF
#undef FUNC_NAME_LE_2
#undef FUNC_NAME_LE_1
#undef FUNC_NAME_LE
#undef FUNC_NAME_BE_2
#undef FUNC_NAME_BE_1
#undef FUNC_NAME_BE
|