1 /* XzCrc64.c -- CRC64 calculation 2 2015-03-01 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 #include "XzCrc64.h" 7 #include "CpuArch.h" 8 9 #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42) 10 11 #ifdef MY_CPU_LE 12 #define CRC_NUM_TABLES 4 13 #else 14 #define CRC_NUM_TABLES 5 15 #define CRC_UINT64_SWAP(v) \ 16 ((v >> 56) \ 17 | ((v >> 40) & ((UInt64)0xFF << 8)) \ 18 | ((v >> 24) & ((UInt64)0xFF << 16)) \ 19 | ((v >> 8) & ((UInt64)0xFF << 24)) \ 20 | ((v << 8) & ((UInt64)0xFF << 32)) \ 21 | ((v << 24) & ((UInt64)0xFF << 40)) \ 22 | ((v << 40) & ((UInt64)0xFF << 48)) \ 23 | ((v << 56))) 24 25 UInt64 MY_FAST_CALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table); 26 #endif 27 28 #ifndef MY_CPU_BE 29 UInt64 MY_FAST_CALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table); 30 #endif 31 32 typedef UInt64 (MY_FAST_CALL *CRC_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table); 33 34 static CRC_FUNC g_Crc64Update; 35 UInt64 g_Crc64Table[256 * CRC_NUM_TABLES]; 36 37 UInt64 MY_FAST_CALL Crc64Update(UInt64 v, const void *data, size_t size) 38 { 39 return g_Crc64Update(v, data, size, g_Crc64Table); 40 } 41 42 UInt64 MY_FAST_CALL Crc64Calc(const void *data, size_t size) 43 { 44 return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL; 45 } 46 47 void MY_FAST_CALL Crc64GenerateTable() 48 { 49 UInt32 i; 50 for (i = 0; i < 256; i++) 51 { 52 UInt64 r = i; 53 unsigned j; 54 for (j = 0; j < 8; j++) 55 r = (r >> 1) ^ (kCrc64Poly & ~((r & 1) - 1)); 56 g_Crc64Table[i] = r; 57 } 58 for (; i < 256 * CRC_NUM_TABLES; i++) 59 { 60 UInt64 r = g_Crc64Table[i - 256]; 61 g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8); 62 } 63 64 #ifdef MY_CPU_LE 65 66 g_Crc64Update = XzCrc64UpdateT4; 67 68 #else 69 { 70 #ifndef MY_CPU_BE 71 UInt32 k = 1; 72 if (*(const Byte *)&k == 1) 73 g_Crc64Update = XzCrc64UpdateT4; 74 else 75 #endif 76 { 77 for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) 78 { 79 UInt64 x = g_Crc64Table[i - 256]; 80 g_Crc64Table[i] = CRC_UINT64_SWAP(x); 81 } 82 g_Crc64Update = XzCrc64UpdateT1_BeT4; 83 } 84 } 85 #endif 86 } 87