diff options
Diffstat (limited to 'C/7zCrc.c')
-rw-r--r-- | C/7zCrc.c | 130 |
1 files changed, 74 insertions, 56 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* 7zCrc.c -- CRC32 init | 1 | /* 7zCrc.c -- CRC32 calculation and init |
2 | 2021-04-01 : Igor Pavlov : Public domain */ | 2 | 2023-04-02 : Igor Pavlov : Public domain */ |
3 | 3 | ||
4 | #include "Precomp.h" | 4 | #include "Precomp.h" |
5 | 5 | ||
@@ -13,22 +13,20 @@ | |||
13 | #else | 13 | #else |
14 | #define CRC_NUM_TABLES 9 | 14 | #define CRC_NUM_TABLES 9 |
15 | 15 | ||
16 | #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24)) | 16 | UInt32 Z7_FASTCALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); |
17 | 17 | UInt32 Z7_FASTCALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); | |
18 | UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table); | ||
19 | UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table); | ||
20 | #endif | 18 | #endif |
21 | 19 | ||
22 | #ifndef MY_CPU_BE | 20 | #ifndef MY_CPU_BE |
23 | UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); | 21 | UInt32 Z7_FASTCALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table); |
24 | UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); | 22 | UInt32 Z7_FASTCALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table); |
25 | #endif | 23 | #endif |
26 | 24 | ||
27 | typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table); | 25 | /* |
28 | |||
29 | extern | 26 | extern |
30 | CRC_FUNC g_CrcUpdateT4; | 27 | CRC_FUNC g_CrcUpdateT4; |
31 | CRC_FUNC g_CrcUpdateT4; | 28 | CRC_FUNC g_CrcUpdateT4; |
29 | */ | ||
32 | extern | 30 | extern |
33 | CRC_FUNC g_CrcUpdateT8; | 31 | CRC_FUNC g_CrcUpdateT8; |
34 | CRC_FUNC g_CrcUpdateT8; | 32 | CRC_FUNC g_CrcUpdateT8; |
@@ -44,20 +42,22 @@ CRC_FUNC g_CrcUpdate; | |||
44 | 42 | ||
45 | UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; | 43 | UInt32 g_CrcTable[256 * CRC_NUM_TABLES]; |
46 | 44 | ||
47 | UInt32 MY_FAST_CALL CrcUpdate(UInt32 v, const void *data, size_t size) | 45 | UInt32 Z7_FASTCALL CrcUpdate(UInt32 v, const void *data, size_t size) |
48 | { | 46 | { |
49 | return g_CrcUpdate(v, data, size, g_CrcTable); | 47 | return g_CrcUpdate(v, data, size, g_CrcTable); |
50 | } | 48 | } |
51 | 49 | ||
52 | UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size) | 50 | UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size) |
53 | { | 51 | { |
54 | return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; | 52 | return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; |
55 | } | 53 | } |
56 | 54 | ||
55 | #if CRC_NUM_TABLES < 4 \ | ||
56 | || (CRC_NUM_TABLES == 4 && defined(MY_CPU_BE)) \ | ||
57 | || (!defined(MY_CPU_LE) && !defined(MY_CPU_BE)) | ||
57 | #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) | 58 | #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) |
58 | 59 | UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); | |
59 | UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table); | 60 | UInt32 Z7_FASTCALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) |
60 | UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table) | ||
61 | { | 61 | { |
62 | const Byte *p = (const Byte *)data; | 62 | const Byte *p = (const Byte *)data; |
63 | const Byte *pEnd = p + size; | 63 | const Byte *pEnd = p + size; |
@@ -65,7 +65,7 @@ UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const U | |||
65 | v = CRC_UPDATE_BYTE_2(v, *p); | 65 | v = CRC_UPDATE_BYTE_2(v, *p); |
66 | return v; | 66 | return v; |
67 | } | 67 | } |
68 | 68 | #endif | |
69 | 69 | ||
70 | /* ---------- hardware CRC ---------- */ | 70 | /* ---------- hardware CRC ---------- */ |
71 | 71 | ||
@@ -78,16 +78,29 @@ UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const U | |||
78 | #if defined(_MSC_VER) | 78 | #if defined(_MSC_VER) |
79 | #if defined(MY_CPU_ARM64) | 79 | #if defined(MY_CPU_ARM64) |
80 | #if (_MSC_VER >= 1910) | 80 | #if (_MSC_VER >= 1910) |
81 | #ifndef __clang__ | ||
81 | #define USE_ARM64_CRC | 82 | #define USE_ARM64_CRC |
83 | #include <intrin.h> | ||
84 | #endif | ||
82 | #endif | 85 | #endif |
83 | #endif | 86 | #endif |
84 | #elif (defined(__clang__) && (__clang_major__ >= 3)) \ | 87 | #elif (defined(__clang__) && (__clang_major__ >= 3)) \ |
85 | || (defined(__GNUC__) && (__GNUC__ > 4)) | 88 | || (defined(__GNUC__) && (__GNUC__ > 4)) |
86 | #if !defined(__ARM_FEATURE_CRC32) | 89 | #if !defined(__ARM_FEATURE_CRC32) |
87 | #define __ARM_FEATURE_CRC32 1 | 90 | #define __ARM_FEATURE_CRC32 1 |
88 | #if (!defined(__clang__) || (__clang_major__ > 3)) // fix these numbers | 91 | #if defined(__clang__) |
92 | #if defined(MY_CPU_ARM64) | ||
93 | #define ATTRIB_CRC __attribute__((__target__("crc"))) | ||
94 | #else | ||
95 | #define ATTRIB_CRC __attribute__((__target__("armv8-a,crc"))) | ||
96 | #endif | ||
97 | #else | ||
98 | #if defined(MY_CPU_ARM64) | ||
99 | #define ATTRIB_CRC __attribute__((__target__("+crc"))) | ||
100 | #else | ||
89 | #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc"))) | 101 | #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc"))) |
90 | #endif | 102 | #endif |
103 | #endif | ||
91 | #endif | 104 | #endif |
92 | #if defined(__ARM_FEATURE_CRC32) | 105 | #if defined(__ARM_FEATURE_CRC32) |
93 | #define USE_ARM64_CRC | 106 | #define USE_ARM64_CRC |
@@ -105,7 +118,7 @@ UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const U | |||
105 | 118 | ||
106 | #pragma message("ARM64 CRC emulation") | 119 | #pragma message("ARM64 CRC emulation") |
107 | 120 | ||
108 | MY_FORCE_INLINE | 121 | Z7_FORCE_INLINE |
109 | UInt32 __crc32b(UInt32 v, UInt32 data) | 122 | UInt32 __crc32b(UInt32 v, UInt32 data) |
110 | { | 123 | { |
111 | const UInt32 *table = g_CrcTable; | 124 | const UInt32 *table = g_CrcTable; |
@@ -113,7 +126,7 @@ UInt32 __crc32b(UInt32 v, UInt32 data) | |||
113 | return v; | 126 | return v; |
114 | } | 127 | } |
115 | 128 | ||
116 | MY_FORCE_INLINE | 129 | Z7_FORCE_INLINE |
117 | UInt32 __crc32w(UInt32 v, UInt32 data) | 130 | UInt32 __crc32w(UInt32 v, UInt32 data) |
118 | { | 131 | { |
119 | const UInt32 *table = g_CrcTable; | 132 | const UInt32 *table = g_CrcTable; |
@@ -124,7 +137,7 @@ UInt32 __crc32w(UInt32 v, UInt32 data) | |||
124 | return v; | 137 | return v; |
125 | } | 138 | } |
126 | 139 | ||
127 | MY_FORCE_INLINE | 140 | Z7_FORCE_INLINE |
128 | UInt32 __crc32d(UInt32 v, UInt64 data) | 141 | UInt32 __crc32d(UInt32 v, UInt64 data) |
129 | { | 142 | { |
130 | const UInt32 *table = g_CrcTable; | 143 | const UInt32 *table = g_CrcTable; |
@@ -156,9 +169,9 @@ UInt32 __crc32d(UInt32 v, UInt64 data) | |||
156 | // #pragma message("USE ARM HW CRC") | 169 | // #pragma message("USE ARM HW CRC") |
157 | 170 | ||
158 | ATTRIB_CRC | 171 | ATTRIB_CRC |
159 | UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table); | 172 | UInt32 Z7_FASTCALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table); |
160 | ATTRIB_CRC | 173 | ATTRIB_CRC |
161 | UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table) | 174 | UInt32 Z7_FASTCALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, const UInt32 *table) |
162 | { | 175 | { |
163 | const Byte *p = (const Byte *)data; | 176 | const Byte *p = (const Byte *)data; |
164 | UNUSED_VAR(table); | 177 | UNUSED_VAR(table); |
@@ -188,9 +201,9 @@ UInt32 MY_FAST_CALL CrcUpdateT0_32(UInt32 v, const void *data, size_t size, cons | |||
188 | } | 201 | } |
189 | 202 | ||
190 | ATTRIB_CRC | 203 | ATTRIB_CRC |
191 | UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table); | 204 | UInt32 Z7_FASTCALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table); |
192 | ATTRIB_CRC | 205 | ATTRIB_CRC |
193 | UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table) | 206 | UInt32 Z7_FASTCALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, const UInt32 *table) |
194 | { | 207 | { |
195 | const Byte *p = (const Byte *)data; | 208 | const Byte *p = (const Byte *)data; |
196 | UNUSED_VAR(table); | 209 | UNUSED_VAR(table); |
@@ -219,6 +232,9 @@ UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, cons | |||
219 | return v; | 232 | return v; |
220 | } | 233 | } |
221 | 234 | ||
235 | #undef T0_32_UNROLL_BYTES | ||
236 | #undef T0_64_UNROLL_BYTES | ||
237 | |||
222 | #endif // defined(USE_ARM64_CRC) || defined(USE_CRC_EMU) | 238 | #endif // defined(USE_ARM64_CRC) || defined(USE_CRC_EMU) |
223 | 239 | ||
224 | #endif // MY_CPU_LE | 240 | #endif // MY_CPU_LE |
@@ -226,7 +242,7 @@ UInt32 MY_FAST_CALL CrcUpdateT0_64(UInt32 v, const void *data, size_t size, cons | |||
226 | 242 | ||
227 | 243 | ||
228 | 244 | ||
229 | void MY_FAST_CALL CrcGenerateTable() | 245 | void Z7_FASTCALL CrcGenerateTable(void) |
230 | { | 246 | { |
231 | UInt32 i; | 247 | UInt32 i; |
232 | for (i = 0; i < 256; i++) | 248 | for (i = 0; i < 256; i++) |
@@ -239,64 +255,62 @@ void MY_FAST_CALL CrcGenerateTable() | |||
239 | } | 255 | } |
240 | for (i = 256; i < 256 * CRC_NUM_TABLES; i++) | 256 | for (i = 256; i < 256 * CRC_NUM_TABLES; i++) |
241 | { | 257 | { |
242 | UInt32 r = g_CrcTable[(size_t)i - 256]; | 258 | const UInt32 r = g_CrcTable[(size_t)i - 256]; |
243 | g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); | 259 | g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); |
244 | } | 260 | } |
245 | 261 | ||
246 | #if CRC_NUM_TABLES < 4 | 262 | #if CRC_NUM_TABLES < 4 |
247 | 263 | g_CrcUpdate = CrcUpdateT1; | |
248 | g_CrcUpdate = CrcUpdateT1; | 264 | #elif defined(MY_CPU_LE) |
249 | 265 | // g_CrcUpdateT4 = CrcUpdateT4; | |
250 | #else | 266 | #if CRC_NUM_TABLES < 8 |
251 | 267 | g_CrcUpdate = CrcUpdateT4; | |
252 | #ifdef MY_CPU_LE | 268 | #else // CRC_NUM_TABLES >= 8 |
253 | |||
254 | g_CrcUpdateT4 = CrcUpdateT4; | ||
255 | g_CrcUpdate = CrcUpdateT4; | ||
256 | |||
257 | #if CRC_NUM_TABLES >= 8 | ||
258 | g_CrcUpdateT8 = CrcUpdateT8; | 269 | g_CrcUpdateT8 = CrcUpdateT8; |
259 | 270 | /* | |
260 | #ifdef MY_CPU_X86_OR_AMD64 | 271 | #ifdef MY_CPU_X86_OR_AMD64 |
261 | if (!CPU_Is_InOrder()) | 272 | if (!CPU_Is_InOrder()) |
262 | #endif | 273 | #endif |
263 | g_CrcUpdate = CrcUpdateT8; | 274 | */ |
275 | g_CrcUpdate = CrcUpdateT8; | ||
264 | #endif | 276 | #endif |
265 | |||
266 | #else | 277 | #else |
267 | { | 278 | { |
268 | #ifndef MY_CPU_BE | 279 | #ifndef MY_CPU_BE |
269 | UInt32 k = 0x01020304; | 280 | UInt32 k = 0x01020304; |
270 | const Byte *p = (const Byte *)&k; | 281 | const Byte *p = (const Byte *)&k; |
271 | if (p[0] == 4 && p[1] == 3) | 282 | if (p[0] == 4 && p[1] == 3) |
272 | { | 283 | { |
273 | g_CrcUpdateT4 = CrcUpdateT4; | 284 | #if CRC_NUM_TABLES < 8 |
274 | g_CrcUpdate = CrcUpdateT4; | 285 | // g_CrcUpdateT4 = CrcUpdateT4; |
275 | #if CRC_NUM_TABLES >= 8 | 286 | g_CrcUpdate = CrcUpdateT4; |
276 | g_CrcUpdateT8 = CrcUpdateT8; | 287 | #else // CRC_NUM_TABLES >= 8 |
277 | g_CrcUpdate = CrcUpdateT8; | 288 | g_CrcUpdateT8 = CrcUpdateT8; |
289 | g_CrcUpdate = CrcUpdateT8; | ||
278 | #endif | 290 | #endif |
279 | } | 291 | } |
280 | else if (p[0] != 1 || p[1] != 2) | 292 | else if (p[0] != 1 || p[1] != 2) |
281 | g_CrcUpdate = CrcUpdateT1; | 293 | g_CrcUpdate = CrcUpdateT1; |
282 | else | 294 | else |
283 | #endif | 295 | #endif // MY_CPU_BE |
284 | { | 296 | { |
285 | for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) | 297 | for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--) |
286 | { | 298 | { |
287 | UInt32 x = g_CrcTable[(size_t)i - 256]; | 299 | const UInt32 x = g_CrcTable[(size_t)i - 256]; |
288 | g_CrcTable[i] = CRC_UINT32_SWAP(x); | 300 | g_CrcTable[i] = Z7_BSWAP32(x); |
289 | } | 301 | } |
290 | g_CrcUpdateT4 = CrcUpdateT1_BeT4; | 302 | #if CRC_NUM_TABLES <= 4 |
291 | g_CrcUpdate = CrcUpdateT1_BeT4; | 303 | g_CrcUpdate = CrcUpdateT1; |
292 | #if CRC_NUM_TABLES >= 8 | 304 | #elif CRC_NUM_TABLES <= 8 |
293 | g_CrcUpdateT8 = CrcUpdateT1_BeT8; | 305 | // g_CrcUpdateT4 = CrcUpdateT1_BeT4; |
294 | g_CrcUpdate = CrcUpdateT1_BeT8; | 306 | g_CrcUpdate = CrcUpdateT1_BeT4; |
307 | #else // CRC_NUM_TABLES > 8 | ||
308 | g_CrcUpdateT8 = CrcUpdateT1_BeT8; | ||
309 | g_CrcUpdate = CrcUpdateT1_BeT8; | ||
295 | #endif | 310 | #endif |
296 | } | 311 | } |
297 | } | 312 | } |
298 | #endif | 313 | #endif // CRC_NUM_TABLES < 4 |
299 | #endif | ||
300 | 314 | ||
301 | #ifdef MY_CPU_LE | 315 | #ifdef MY_CPU_LE |
302 | #ifdef USE_ARM64_CRC | 316 | #ifdef USE_ARM64_CRC |
@@ -320,3 +334,7 @@ void MY_FAST_CALL CrcGenerateTable() | |||
320 | #endif | 334 | #endif |
321 | #endif | 335 | #endif |
322 | } | 336 | } |
337 | |||
338 | #undef kCrcPoly | ||
339 | #undef CRC64_NUM_TABLES | ||
340 | #undef CRC_UPDATE_BYTE_2 | ||