ce188d4d |
1 | /* 7zCrc.c -- CRC32 init\r |
2 | 2015-03-10 : Igor Pavlov : Public domain */\r |
3 | \r |
4 | #include "Precomp.h"\r |
5 | \r |
6 | #include "7zCrc.h"\r |
7 | #include "CpuArch.h"\r |
8 | \r |
9 | #define kCrcPoly 0xEDB88320\r |
10 | \r |
11 | #ifdef MY_CPU_LE\r |
12 | #define CRC_NUM_TABLES 8\r |
13 | #else\r |
14 | #define CRC_NUM_TABLES 9\r |
15 | \r |
16 | #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))\r |
17 | \r |
18 | UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);\r |
19 | UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);\r |
20 | #endif\r |
21 | \r |
22 | #ifndef MY_CPU_BE\r |
23 | UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);\r |
24 | UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);\r |
25 | #endif\r |
26 | \r |
27 | typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);\r |
28 | \r |
29 | CRC_FUNC g_CrcUpdateT4;\r |
30 | CRC_FUNC g_CrcUpdateT8;\r |
31 | CRC_FUNC g_CrcUpdate;\r |
32 | \r |
33 | UInt32 g_CrcTable[256 * CRC_NUM_TABLES];\r |
34 | \r |
35 | UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size)\r |
36 | {\r |
37 | return g_CrcUpdate(v, data, size, g_CrcTable);\r |
38 | }\r |
39 | \r |
40 | UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)\r |
41 | {\r |
42 | return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;\r |
43 | }\r |
44 | \r |
45 | #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))\r |
46 | \r |
47 | UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)\r |
48 | {\r |
49 | const Byte *p = (const Byte *)data;\r |
50 | const Byte *pEnd = p + size;\r |
51 | for (; p != pEnd; p++)\r |
52 | v = CRC_UPDATE_BYTE_2(v, *p);\r |
53 | return v;\r |
54 | }\r |
55 | \r |
56 | void MY_FAST_CALL CrcGenerateTable()\r |
57 | {\r |
58 | UInt32 i;\r |
59 | for (i = 0; i < 256; i++)\r |
60 | {\r |
61 | UInt32 r = i;\r |
62 | unsigned j;\r |
63 | for (j = 0; j < 8; j++)\r |
64 | r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));\r |
65 | g_CrcTable[i] = r;\r |
66 | }\r |
67 | for (; i < 256 * CRC_NUM_TABLES; i++)\r |
68 | {\r |
69 | UInt32 r = g_CrcTable[i - 256];\r |
70 | g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);\r |
71 | }\r |
72 | \r |
73 | #if CRC_NUM_TABLES < 4\r |
74 | \r |
75 | g_CrcUpdate = CrcUpdateT1;\r |
76 | \r |
77 | #else\r |
78 | \r |
79 | #ifdef MY_CPU_LE\r |
80 | \r |
81 | g_CrcUpdateT4 = CrcUpdateT4;\r |
82 | g_CrcUpdate = CrcUpdateT4;\r |
83 | \r |
84 | #if CRC_NUM_TABLES >= 8\r |
85 | g_CrcUpdateT8 = CrcUpdateT8;\r |
86 | \r |
87 | #ifdef MY_CPU_X86_OR_AMD64\r |
88 | if (!CPU_Is_InOrder())\r |
89 | g_CrcUpdate = CrcUpdateT8;\r |
90 | #endif\r |
91 | #endif\r |
92 | \r |
93 | #else\r |
94 | {\r |
95 | #ifndef MY_CPU_BE\r |
96 | UInt32 k = 0x01020304;\r |
97 | const Byte *p = (const Byte *)&k;\r |
98 | if (p[0] == 4 && p[1] == 3)\r |
99 | {\r |
100 | g_CrcUpdateT4 = CrcUpdateT4;\r |
101 | g_CrcUpdate = CrcUpdateT4;\r |
102 | #if CRC_NUM_TABLES >= 8\r |
103 | g_CrcUpdateT8 = CrcUpdateT8;\r |
104 | // g_CrcUpdate = CrcUpdateT8;\r |
105 | #endif\r |
106 | }\r |
107 | else if (p[0] != 1 || p[1] != 2)\r |
108 | g_CrcUpdate = CrcUpdateT1;\r |
109 | else\r |
110 | #endif\r |
111 | {\r |
112 | for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)\r |
113 | {\r |
114 | UInt32 x = g_CrcTable[i - 256];\r |
115 | g_CrcTable[i] = CRC_UINT32_SWAP(x);\r |
116 | }\r |
117 | g_CrcUpdateT4 = CrcUpdateT1_BeT4;\r |
118 | g_CrcUpdate = CrcUpdateT1_BeT4;\r |
119 | #if CRC_NUM_TABLES >= 8\r |
120 | g_CrcUpdateT8 = CrcUpdateT1_BeT8;\r |
121 | // g_CrcUpdate = CrcUpdateT1_BeT8;\r |
122 | #endif\r |
123 | }\r |
124 | }\r |
125 | #endif\r |
126 | \r |
127 | #endif\r |
128 | }\r |