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