1 /* 7zCrc.c -- CRC32 init 2 2013-11-12 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 #include "7zCrc.h" 7 #include "CpuArch.h" 8 9 #define kCrcPoly 0xEDB88320 10 11 #ifdef MY_CPU_X86_OR_AMD64 12 #define CRC_NUM_TABLES 8 13 UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); 14 #elif defined(MY_CPU_LE) 15 #define CRC_NUM_TABLES 4 16 #else 17 #define CRC_NUM_TABLES 5 18 #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) 19 UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); 20 #endif 21 22 #ifndef MY_CPU_BE 23 UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); 24 #endif 25 26 typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); 27 28 CRC_FUNC g_CrcUpdate; 29 UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; 30 31 UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) 32 { 33 return g_CrcUpdate(v, data, size, g_CrcTable); 34 } 35 36 UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) 37 { 38 return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; 39 } 40 41 void MY_FAST_CALL CrcGenerateTable() 42 { 43 UInt32 i; 44 for (i = 0; i < 256; i++) 45 { 46 UInt32 r = i; 47 unsigned j; 48 for (j = 0; j < 8; j++) 49 r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); 50 g_CrcTable[i] = r; 51 } 52 for (; i < 256 * CRC_NUM_TABLES; i++) 53 { 54 UInt32 r = g_CrcTable[i - 256]; 55 g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); 56 } 57 58 #ifdef MY_CPU_LE 59 60 g_CrcUpdate = CrcUpdateT4; 61 62 #if CRC_NUM_TABLES == 8 63 if (!CPU_Is_InOrder()) 64 g_CrcUpdate = CrcUpdateT8; 65 #endif 66 67 #else 68 { 69 #ifndef MY_CPU_BE 70 UInt32 k = 1; 71 if (*(const Byte *)&k == 1) 72 g_CrcUpdate = CrcUpdateT4; 73 else 74 #endif 75 { 76 for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) 77 { 78 UInt32 x = g_CrcTable[i - 256]; 79 g_CrcTable[i] = CRC_UINT32_SWAP(x); 80 } 81 g_CrcUpdate = CrcUpdateT1_BeT4; 82 } 83 } 84 #endif 85 } 86