1*f6dc9357SAndroid Build Coastguard Worker /* 7zCrc.c -- CRC32 calculation and init
2*f6dc9357SAndroid Build Coastguard Worker 2024-03-01 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker
6*f6dc9357SAndroid Build Coastguard Worker #include "7zCrc.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
8*f6dc9357SAndroid Build Coastguard Worker
9*f6dc9357SAndroid Build Coastguard Worker // for debug:
10*f6dc9357SAndroid Build Coastguard Worker // #define __ARM_FEATURE_CRC32 1
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #ifdef __ARM_FEATURE_CRC32
13*f6dc9357SAndroid Build Coastguard Worker // #pragma message("__ARM_FEATURE_CRC32")
14*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_HW_FORCE
15*f6dc9357SAndroid Build Coastguard Worker #endif
16*f6dc9357SAndroid Build Coastguard Worker
17*f6dc9357SAndroid Build Coastguard Worker // #define Z7_CRC_DEBUG_BE
18*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_DEBUG_BE
19*f6dc9357SAndroid Build Coastguard Worker #undef MY_CPU_LE
20*f6dc9357SAndroid Build Coastguard Worker #define MY_CPU_BE
21*f6dc9357SAndroid Build Coastguard Worker #endif
22*f6dc9357SAndroid Build Coastguard Worker
23*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_FORCE
24*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_NUM_TABLES_USE 1
25*f6dc9357SAndroid Build Coastguard Worker #else
26*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_NUM_TABLES
27*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES
28*f6dc9357SAndroid Build Coastguard Worker #else
29*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_NUM_TABLES_USE 12
30*f6dc9357SAndroid Build Coastguard Worker #endif
31*f6dc9357SAndroid Build Coastguard Worker #endif
32*f6dc9357SAndroid Build Coastguard Worker
33*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC_NUM_TABLES_USE < 1
34*f6dc9357SAndroid Build Coastguard Worker #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
35*f6dc9357SAndroid Build Coastguard Worker #endif
36*f6dc9357SAndroid Build Coastguard Worker
37*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_LE) || (Z7_CRC_NUM_TABLES_USE == 1)
38*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_NUM_TABLES_TOTAL Z7_CRC_NUM_TABLES_USE
39*f6dc9357SAndroid Build Coastguard Worker #else
40*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_NUM_TABLES_TOTAL (Z7_CRC_NUM_TABLES_USE + 1)
41*f6dc9357SAndroid Build Coastguard Worker #endif
42*f6dc9357SAndroid Build Coastguard Worker
43*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_CRC_HW_FORCE
44*f6dc9357SAndroid Build Coastguard Worker
45*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC_NUM_TABLES_USE == 1 \
46*f6dc9357SAndroid Build Coastguard Worker || (!defined(MY_CPU_LE) && !defined(MY_CPU_BE))
47*f6dc9357SAndroid Build Coastguard Worker #define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
48*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_UPDATE_T1_FUNC_NAME CrcUpdateGT1
Z7_CRC_UPDATE_T1_FUNC_NAME(UInt32 v,const void * data,size_t size)49*f6dc9357SAndroid Build Coastguard Worker static UInt32 Z7_FASTCALL Z7_CRC_UPDATE_T1_FUNC_NAME(UInt32 v, const void *data, size_t size)
50*f6dc9357SAndroid Build Coastguard Worker {
51*f6dc9357SAndroid Build Coastguard Worker const UInt32 *table = g_CrcTable;
52*f6dc9357SAndroid Build Coastguard Worker const Byte *p = (const Byte *)data;
53*f6dc9357SAndroid Build Coastguard Worker const Byte *lim = p + size;
54*f6dc9357SAndroid Build Coastguard Worker for (; p != lim; p++)
55*f6dc9357SAndroid Build Coastguard Worker v = CRC_UPDATE_BYTE_2(v, *p);
56*f6dc9357SAndroid Build Coastguard Worker return v;
57*f6dc9357SAndroid Build Coastguard Worker }
58*f6dc9357SAndroid Build Coastguard Worker #endif
59*f6dc9357SAndroid Build Coastguard Worker
60*f6dc9357SAndroid Build Coastguard Worker
61*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC_NUM_TABLES_USE != 1
62*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_BE
63*f6dc9357SAndroid Build Coastguard Worker #define FUNC_NAME_LE_2(s) CrcUpdateT ## s
64*f6dc9357SAndroid Build Coastguard Worker #define FUNC_NAME_LE_1(s) FUNC_NAME_LE_2(s)
65*f6dc9357SAndroid Build Coastguard Worker #define FUNC_NAME_LE FUNC_NAME_LE_1(Z7_CRC_NUM_TABLES_USE)
66*f6dc9357SAndroid Build Coastguard Worker UInt32 Z7_FASTCALL FUNC_NAME_LE (UInt32 v, const void *data, size_t size, const UInt32 *table);
67*f6dc9357SAndroid Build Coastguard Worker #endif
68*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_LE
69*f6dc9357SAndroid Build Coastguard Worker #define FUNC_NAME_BE_2(s) CrcUpdateT1_BeT ## s
70*f6dc9357SAndroid Build Coastguard Worker #define FUNC_NAME_BE_1(s) FUNC_NAME_BE_2(s)
71*f6dc9357SAndroid Build Coastguard Worker #define FUNC_NAME_BE FUNC_NAME_BE_1(Z7_CRC_NUM_TABLES_USE)
72*f6dc9357SAndroid Build Coastguard Worker UInt32 Z7_FASTCALL FUNC_NAME_BE (UInt32 v, const void *data, size_t size, const UInt32 *table);
73*f6dc9357SAndroid Build Coastguard Worker #endif
74*f6dc9357SAndroid Build Coastguard Worker #endif
75*f6dc9357SAndroid Build Coastguard Worker
76*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_CRC_HW_FORCE
77*f6dc9357SAndroid Build Coastguard Worker
78*f6dc9357SAndroid Build Coastguard Worker /* ---------- hardware CRC ---------- */
79*f6dc9357SAndroid Build Coastguard Worker
80*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_LE
81*f6dc9357SAndroid Build Coastguard Worker
82*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM_OR_ARM64)
83*f6dc9357SAndroid Build Coastguard Worker // #pragma message("ARM*")
84*f6dc9357SAndroid Build Coastguard Worker
85*f6dc9357SAndroid Build Coastguard Worker #if (defined(__clang__) && (__clang_major__ >= 3)) \
86*f6dc9357SAndroid Build Coastguard Worker || defined(__GNUC__) && (__GNUC__ >= 6) && defined(MY_CPU_ARM64) \
87*f6dc9357SAndroid Build Coastguard Worker || defined(__GNUC__) && (__GNUC__ >= 8)
88*f6dc9357SAndroid Build Coastguard Worker #if !defined(__ARM_FEATURE_CRC32)
89*f6dc9357SAndroid Build Coastguard Worker // #pragma message("!defined(__ARM_FEATURE_CRC32)")
90*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
91*f6dc9357SAndroid Build Coastguard Worker #define __ARM_FEATURE_CRC32 1
92*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
93*f6dc9357SAndroid Build Coastguard Worker #define Z7_ARM_FEATURE_CRC32_WAS_SET
94*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__)
95*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64)
96*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_CRC __attribute__((__target__("crc")))
97*f6dc9357SAndroid Build Coastguard Worker #else
98*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_CRC __attribute__((__target__("armv8-a,crc")))
99*f6dc9357SAndroid Build Coastguard Worker #endif
100*f6dc9357SAndroid Build Coastguard Worker #else
101*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64)
102*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_GCC_VERSION) || (Z7_GCC_VERSION >= 60000)
103*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_CRC __attribute__((__target__("+crc")))
104*f6dc9357SAndroid Build Coastguard Worker #endif
105*f6dc9357SAndroid Build Coastguard Worker #else
106*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_GCC_VERSION) || (__GNUC__ >= 8)
107*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_FP) && __GNUC__ >= 8
108*f6dc9357SAndroid Build Coastguard Worker // for -mfloat-abi=hard: similar to <arm_acle.h>
109*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc+simd")))
110*f6dc9357SAndroid Build Coastguard Worker #else
111*f6dc9357SAndroid Build Coastguard Worker #define ATTRIB_CRC __attribute__((__target__("arch=armv8-a+crc")))
112*f6dc9357SAndroid Build Coastguard Worker #endif
113*f6dc9357SAndroid Build Coastguard Worker #endif
114*f6dc9357SAndroid Build Coastguard Worker #endif
115*f6dc9357SAndroid Build Coastguard Worker #endif
116*f6dc9357SAndroid Build Coastguard Worker #endif
117*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_FEATURE_CRC32)
118*f6dc9357SAndroid Build Coastguard Worker // #pragma message("<arm_acle.h>")
119*f6dc9357SAndroid Build Coastguard Worker /*
120*f6dc9357SAndroid Build Coastguard Worker arm_acle.h (GGC):
121*f6dc9357SAndroid Build Coastguard Worker before Nov 17, 2017:
122*f6dc9357SAndroid Build Coastguard Worker #ifdef __ARM_FEATURE_CRC32
123*f6dc9357SAndroid Build Coastguard Worker
124*f6dc9357SAndroid Build Coastguard Worker Nov 17, 2017: gcc10.0 (gcc 9.2.0) checked"
125*f6dc9357SAndroid Build Coastguard Worker #if __ARM_ARCH >= 8
126*f6dc9357SAndroid Build Coastguard Worker #pragma GCC target ("arch=armv8-a+crc")
127*f6dc9357SAndroid Build Coastguard Worker
128*f6dc9357SAndroid Build Coastguard Worker Aug 22, 2019: GCC 8.4?, 9.2.1, 10.1:
129*f6dc9357SAndroid Build Coastguard Worker #ifdef __ARM_FEATURE_CRC32
130*f6dc9357SAndroid Build Coastguard Worker #ifdef __ARM_FP
131*f6dc9357SAndroid Build Coastguard Worker #pragma GCC target ("arch=armv8-a+crc+simd")
132*f6dc9357SAndroid Build Coastguard Worker #else
133*f6dc9357SAndroid Build Coastguard Worker #pragma GCC target ("arch=armv8-a+crc")
134*f6dc9357SAndroid Build Coastguard Worker #endif
135*f6dc9357SAndroid Build Coastguard Worker */
136*f6dc9357SAndroid Build Coastguard Worker #if defined(__ARM_ARCH) && __ARM_ARCH < 8
137*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_GCC_VERSION) && (__GNUC__ == 8) && (Z7_GCC_VERSION < 80400) \
138*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_GCC_VERSION) && (__GNUC__ == 9) && (Z7_GCC_VERSION < 90201) \
139*f6dc9357SAndroid Build Coastguard Worker || defined(Z7_GCC_VERSION) && (__GNUC__ == 10) && (Z7_GCC_VERSION < 100100)
140*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
141*f6dc9357SAndroid Build Coastguard Worker // #pragma message("#define __ARM_ARCH 8")
142*f6dc9357SAndroid Build Coastguard Worker #undef __ARM_ARCH
143*f6dc9357SAndroid Build Coastguard Worker #define __ARM_ARCH 8
144*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
145*f6dc9357SAndroid Build Coastguard Worker #endif
146*f6dc9357SAndroid Build Coastguard Worker #endif
147*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_HW_USE
148*f6dc9357SAndroid Build Coastguard Worker #include <arm_acle.h>
149*f6dc9357SAndroid Build Coastguard Worker #endif
150*f6dc9357SAndroid Build Coastguard Worker #elif defined(_MSC_VER)
151*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_ARM64)
152*f6dc9357SAndroid Build Coastguard Worker #if (_MSC_VER >= 1910)
153*f6dc9357SAndroid Build Coastguard Worker #ifdef __clang__
154*f6dc9357SAndroid Build Coastguard Worker // #define Z7_CRC_HW_USE
155*f6dc9357SAndroid Build Coastguard Worker // #include <arm_acle.h>
156*f6dc9357SAndroid Build Coastguard Worker #else
157*f6dc9357SAndroid Build Coastguard Worker #define Z7_CRC_HW_USE
158*f6dc9357SAndroid Build Coastguard Worker #include <intrin.h>
159*f6dc9357SAndroid Build Coastguard Worker #endif
160*f6dc9357SAndroid Build Coastguard Worker #endif
161*f6dc9357SAndroid Build Coastguard Worker #endif
162*f6dc9357SAndroid Build Coastguard Worker #endif
163*f6dc9357SAndroid Build Coastguard Worker
164*f6dc9357SAndroid Build Coastguard Worker #else // non-ARM*
165*f6dc9357SAndroid Build Coastguard Worker
166*f6dc9357SAndroid Build Coastguard Worker // #define Z7_CRC_HW_USE // for debug : we can test HW-branch of code
167*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_USE
168*f6dc9357SAndroid Build Coastguard Worker #include "7zCrcEmu.h"
169*f6dc9357SAndroid Build Coastguard Worker #endif
170*f6dc9357SAndroid Build Coastguard Worker
171*f6dc9357SAndroid Build Coastguard Worker #endif // non-ARM*
172*f6dc9357SAndroid Build Coastguard Worker
173*f6dc9357SAndroid Build Coastguard Worker
174*f6dc9357SAndroid Build Coastguard Worker
175*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_CRC_HW_USE)
176*f6dc9357SAndroid Build Coastguard Worker
177*f6dc9357SAndroid Build Coastguard Worker // #pragma message("USE ARM HW CRC")
178*f6dc9357SAndroid Build Coastguard Worker
179*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_64BIT
180*f6dc9357SAndroid Build Coastguard Worker #define CRC_HW_WORD_TYPE UInt64
181*f6dc9357SAndroid Build Coastguard Worker #define CRC_HW_WORD_FUNC __crc32d
182*f6dc9357SAndroid Build Coastguard Worker #else
183*f6dc9357SAndroid Build Coastguard Worker #define CRC_HW_WORD_TYPE UInt32
184*f6dc9357SAndroid Build Coastguard Worker #define CRC_HW_WORD_FUNC __crc32w
185*f6dc9357SAndroid Build Coastguard Worker #endif
186*f6dc9357SAndroid Build Coastguard Worker
187*f6dc9357SAndroid Build Coastguard Worker #define CRC_HW_UNROLL_BYTES (sizeof(CRC_HW_WORD_TYPE) * 4)
188*f6dc9357SAndroid Build Coastguard Worker
189*f6dc9357SAndroid Build Coastguard Worker #ifdef ATTRIB_CRC
190*f6dc9357SAndroid Build Coastguard Worker ATTRIB_CRC
191*f6dc9357SAndroid Build Coastguard Worker #endif
192*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
193*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_FORCE
CrcUpdate(UInt32 v,const void * data,size_t size)194*f6dc9357SAndroid Build Coastguard Worker UInt32 Z7_FASTCALL CrcUpdate
195*f6dc9357SAndroid Build Coastguard Worker #else
196*f6dc9357SAndroid Build Coastguard Worker static UInt32 Z7_FASTCALL CrcUpdate_HW
197*f6dc9357SAndroid Build Coastguard Worker #endif
198*f6dc9357SAndroid Build Coastguard Worker (UInt32 v, const void *data, size_t size)
199*f6dc9357SAndroid Build Coastguard Worker {
200*f6dc9357SAndroid Build Coastguard Worker const Byte *p = (const Byte *)data;
201*f6dc9357SAndroid Build Coastguard Worker for (; size != 0 && ((unsigned)(ptrdiff_t)p & (CRC_HW_UNROLL_BYTES - 1)) != 0; size--)
202*f6dc9357SAndroid Build Coastguard Worker v = __crc32b(v, *p++);
203*f6dc9357SAndroid Build Coastguard Worker if (size >= CRC_HW_UNROLL_BYTES)
204*f6dc9357SAndroid Build Coastguard Worker {
205*f6dc9357SAndroid Build Coastguard Worker const Byte *lim = p + size;
206*f6dc9357SAndroid Build Coastguard Worker size &= CRC_HW_UNROLL_BYTES - 1;
207*f6dc9357SAndroid Build Coastguard Worker lim -= size;
208*f6dc9357SAndroid Build Coastguard Worker do
209*f6dc9357SAndroid Build Coastguard Worker {
210*f6dc9357SAndroid Build Coastguard Worker v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p));
211*f6dc9357SAndroid Build Coastguard Worker v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE)));
212*f6dc9357SAndroid Build Coastguard Worker p += 2 * sizeof(CRC_HW_WORD_TYPE);
213*f6dc9357SAndroid Build Coastguard Worker v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p));
214*f6dc9357SAndroid Build Coastguard Worker v = CRC_HW_WORD_FUNC(v, *(const CRC_HW_WORD_TYPE *)(const void *)(p + sizeof(CRC_HW_WORD_TYPE)));
215*f6dc9357SAndroid Build Coastguard Worker p += 2 * sizeof(CRC_HW_WORD_TYPE);
216*f6dc9357SAndroid Build Coastguard Worker }
217*f6dc9357SAndroid Build Coastguard Worker while (p != lim);
218*f6dc9357SAndroid Build Coastguard Worker }
219*f6dc9357SAndroid Build Coastguard Worker
220*f6dc9357SAndroid Build Coastguard Worker for (; size != 0; size--)
221*f6dc9357SAndroid Build Coastguard Worker v = __crc32b(v, *p++);
222*f6dc9357SAndroid Build Coastguard Worker
223*f6dc9357SAndroid Build Coastguard Worker return v;
224*f6dc9357SAndroid Build Coastguard Worker }
225*f6dc9357SAndroid Build Coastguard Worker
226*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_ARM_FEATURE_CRC32_WAS_SET
227*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
228*f6dc9357SAndroid Build Coastguard Worker #undef __ARM_FEATURE_CRC32
229*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
230*f6dc9357SAndroid Build Coastguard Worker #undef Z7_ARM_FEATURE_CRC32_WAS_SET
231*f6dc9357SAndroid Build Coastguard Worker #endif
232*f6dc9357SAndroid Build Coastguard Worker
233*f6dc9357SAndroid Build Coastguard Worker #endif // defined(Z7_CRC_HW_USE)
234*f6dc9357SAndroid Build Coastguard Worker #endif // MY_CPU_LE
235*f6dc9357SAndroid Build Coastguard Worker
236*f6dc9357SAndroid Build Coastguard Worker
237*f6dc9357SAndroid Build Coastguard Worker
238*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_CRC_HW_FORCE
239*f6dc9357SAndroid Build Coastguard Worker
240*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME)
241*f6dc9357SAndroid Build Coastguard Worker /*
242*f6dc9357SAndroid Build Coastguard Worker typedef UInt32 (Z7_FASTCALL *Z7_CRC_UPDATE_WITH_TABLE_FUNC)
243*f6dc9357SAndroid Build Coastguard Worker (UInt32 v, const void *data, size_t size, const UInt32 *table);
244*f6dc9357SAndroid Build Coastguard Worker Z7_CRC_UPDATE_WITH_TABLE_FUNC g_CrcUpdate;
245*f6dc9357SAndroid Build Coastguard Worker */
246*f6dc9357SAndroid Build Coastguard Worker static unsigned g_Crc_Algo;
247*f6dc9357SAndroid Build Coastguard Worker #if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE))
248*f6dc9357SAndroid Build Coastguard Worker static unsigned g_Crc_Be;
249*f6dc9357SAndroid Build Coastguard Worker #endif
250*f6dc9357SAndroid Build Coastguard Worker #endif // defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME)
251*f6dc9357SAndroid Build Coastguard Worker
252*f6dc9357SAndroid Build Coastguard Worker
253*f6dc9357SAndroid Build Coastguard Worker
254*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
255*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_USE
CrcUpdate_Base(UInt32 crc,const void * data,size_t size)256*f6dc9357SAndroid Build Coastguard Worker static UInt32 Z7_FASTCALL CrcUpdate_Base
257*f6dc9357SAndroid Build Coastguard Worker #else
258*f6dc9357SAndroid Build Coastguard Worker UInt32 Z7_FASTCALL CrcUpdate
259*f6dc9357SAndroid Build Coastguard Worker #endif
260*f6dc9357SAndroid Build Coastguard Worker (UInt32 crc, const void *data, size_t size)
261*f6dc9357SAndroid Build Coastguard Worker {
262*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC_NUM_TABLES_USE == 1
263*f6dc9357SAndroid Build Coastguard Worker return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size);
264*f6dc9357SAndroid Build Coastguard Worker #else // Z7_CRC_NUM_TABLES_USE != 1
265*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_UPDATE_T1_FUNC_NAME
266*f6dc9357SAndroid Build Coastguard Worker if (g_Crc_Algo == 1)
267*f6dc9357SAndroid Build Coastguard Worker return Z7_CRC_UPDATE_T1_FUNC_NAME(crc, data, size);
268*f6dc9357SAndroid Build Coastguard Worker #endif
269*f6dc9357SAndroid Build Coastguard Worker
270*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_LE
271*f6dc9357SAndroid Build Coastguard Worker return FUNC_NAME_LE(crc, data, size, g_CrcTable);
272*f6dc9357SAndroid Build Coastguard Worker #elif defined(MY_CPU_BE)
273*f6dc9357SAndroid Build Coastguard Worker return FUNC_NAME_BE(crc, data, size, g_CrcTable);
274*f6dc9357SAndroid Build Coastguard Worker #else
275*f6dc9357SAndroid Build Coastguard Worker if (g_Crc_Be)
276*f6dc9357SAndroid Build Coastguard Worker return FUNC_NAME_BE(crc, data, size, g_CrcTable);
277*f6dc9357SAndroid Build Coastguard Worker else
278*f6dc9357SAndroid Build Coastguard Worker return FUNC_NAME_LE(crc, data, size, g_CrcTable);
279*f6dc9357SAndroid Build Coastguard Worker #endif
280*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_CRC_NUM_TABLES_USE != 1
281*f6dc9357SAndroid Build Coastguard Worker }
282*f6dc9357SAndroid Build Coastguard Worker
283*f6dc9357SAndroid Build Coastguard Worker
284*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_USE
285*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
CrcUpdate(UInt32 crc,const void * data,size_t size)286*f6dc9357SAndroid Build Coastguard Worker UInt32 Z7_FASTCALL CrcUpdate(UInt32 crc, const void *data, size_t size)
287*f6dc9357SAndroid Build Coastguard Worker {
288*f6dc9357SAndroid Build Coastguard Worker if (g_Crc_Algo == 0)
289*f6dc9357SAndroid Build Coastguard Worker return CrcUpdate_HW(crc, data, size);
290*f6dc9357SAndroid Build Coastguard Worker return CrcUpdate_Base(crc, data, size);
291*f6dc9357SAndroid Build Coastguard Worker }
292*f6dc9357SAndroid Build Coastguard Worker #endif
293*f6dc9357SAndroid Build Coastguard Worker
294*f6dc9357SAndroid Build Coastguard Worker #endif // !defined(Z7_CRC_HW_FORCE)
295*f6dc9357SAndroid Build Coastguard Worker
296*f6dc9357SAndroid Build Coastguard Worker
297*f6dc9357SAndroid Build Coastguard Worker
CrcCalc(const void * data,size_t size)298*f6dc9357SAndroid Build Coastguard Worker UInt32 Z7_FASTCALL CrcCalc(const void *data, size_t size)
299*f6dc9357SAndroid Build Coastguard Worker {
300*f6dc9357SAndroid Build Coastguard Worker return CrcUpdate(CRC_INIT_VAL, data, size) ^ CRC_INIT_VAL;
301*f6dc9357SAndroid Build Coastguard Worker }
302*f6dc9357SAndroid Build Coastguard Worker
303*f6dc9357SAndroid Build Coastguard Worker
304*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN(64)
305*f6dc9357SAndroid Build Coastguard Worker UInt32 g_CrcTable[256 * Z7_CRC_NUM_TABLES_TOTAL];
306*f6dc9357SAndroid Build Coastguard Worker
307*f6dc9357SAndroid Build Coastguard Worker
CrcGenerateTable(void)308*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL CrcGenerateTable(void)
309*f6dc9357SAndroid Build Coastguard Worker {
310*f6dc9357SAndroid Build Coastguard Worker UInt32 i;
311*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < 256; i++)
312*f6dc9357SAndroid Build Coastguard Worker {
313*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_CRC_HW_FORCE)
314*f6dc9357SAndroid Build Coastguard Worker g_CrcTable[i] = __crc32b(i, 0);
315*f6dc9357SAndroid Build Coastguard Worker #else
316*f6dc9357SAndroid Build Coastguard Worker #define kCrcPoly 0xEDB88320
317*f6dc9357SAndroid Build Coastguard Worker UInt32 r = i;
318*f6dc9357SAndroid Build Coastguard Worker unsigned j;
319*f6dc9357SAndroid Build Coastguard Worker for (j = 0; j < 8; j++)
320*f6dc9357SAndroid Build Coastguard Worker r = (r >> 1) ^ (kCrcPoly & ((UInt32)0 - (r & 1)));
321*f6dc9357SAndroid Build Coastguard Worker g_CrcTable[i] = r;
322*f6dc9357SAndroid Build Coastguard Worker #endif
323*f6dc9357SAndroid Build Coastguard Worker }
324*f6dc9357SAndroid Build Coastguard Worker for (i = 256; i < 256 * Z7_CRC_NUM_TABLES_USE; i++)
325*f6dc9357SAndroid Build Coastguard Worker {
326*f6dc9357SAndroid Build Coastguard Worker const UInt32 r = g_CrcTable[(size_t)i - 256];
327*f6dc9357SAndroid Build Coastguard Worker g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
328*f6dc9357SAndroid Build Coastguard Worker }
329*f6dc9357SAndroid Build Coastguard Worker
330*f6dc9357SAndroid Build Coastguard Worker #if !defined(Z7_CRC_HW_FORCE) && \
331*f6dc9357SAndroid Build Coastguard Worker (defined(Z7_CRC_HW_USE) || defined(Z7_CRC_UPDATE_T1_FUNC_NAME) || defined(MY_CPU_BE))
332*f6dc9357SAndroid Build Coastguard Worker
333*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC_NUM_TABLES_USE <= 1
334*f6dc9357SAndroid Build Coastguard Worker g_Crc_Algo = 1;
335*f6dc9357SAndroid Build Coastguard Worker #else // Z7_CRC_NUM_TABLES_USE <= 1
336*f6dc9357SAndroid Build Coastguard Worker
337*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_LE)
338*f6dc9357SAndroid Build Coastguard Worker g_Crc_Algo = Z7_CRC_NUM_TABLES_USE;
339*f6dc9357SAndroid Build Coastguard Worker #else // !defined(MY_CPU_LE)
340*f6dc9357SAndroid Build Coastguard Worker {
341*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_BE
342*f6dc9357SAndroid Build Coastguard Worker UInt32 k = 0x01020304;
343*f6dc9357SAndroid Build Coastguard Worker const Byte *p = (const Byte *)&k;
344*f6dc9357SAndroid Build Coastguard Worker if (p[0] == 4 && p[1] == 3)
345*f6dc9357SAndroid Build Coastguard Worker g_Crc_Algo = Z7_CRC_NUM_TABLES_USE;
346*f6dc9357SAndroid Build Coastguard Worker else if (p[0] != 1 || p[1] != 2)
347*f6dc9357SAndroid Build Coastguard Worker g_Crc_Algo = 1;
348*f6dc9357SAndroid Build Coastguard Worker else
349*f6dc9357SAndroid Build Coastguard Worker #endif // MY_CPU_BE
350*f6dc9357SAndroid Build Coastguard Worker {
351*f6dc9357SAndroid Build Coastguard Worker for (i = 256 * Z7_CRC_NUM_TABLES_TOTAL - 1; i >= 256; i--)
352*f6dc9357SAndroid Build Coastguard Worker {
353*f6dc9357SAndroid Build Coastguard Worker const UInt32 x = g_CrcTable[(size_t)i - 256];
354*f6dc9357SAndroid Build Coastguard Worker g_CrcTable[i] = Z7_BSWAP32(x);
355*f6dc9357SAndroid Build Coastguard Worker }
356*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_CRC_UPDATE_T1_FUNC_NAME)
357*f6dc9357SAndroid Build Coastguard Worker g_Crc_Algo = Z7_CRC_NUM_TABLES_USE;
358*f6dc9357SAndroid Build Coastguard Worker #endif
359*f6dc9357SAndroid Build Coastguard Worker #if (!defined(MY_CPU_LE) && !defined(MY_CPU_BE))
360*f6dc9357SAndroid Build Coastguard Worker g_Crc_Be = 1;
361*f6dc9357SAndroid Build Coastguard Worker #endif
362*f6dc9357SAndroid Build Coastguard Worker }
363*f6dc9357SAndroid Build Coastguard Worker }
364*f6dc9357SAndroid Build Coastguard Worker #endif // !defined(MY_CPU_LE)
365*f6dc9357SAndroid Build Coastguard Worker
366*f6dc9357SAndroid Build Coastguard Worker #ifdef MY_CPU_LE
367*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_USE
368*f6dc9357SAndroid Build Coastguard Worker if (CPU_IsSupported_CRC32())
369*f6dc9357SAndroid Build Coastguard Worker g_Crc_Algo = 0;
370*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_CRC_HW_USE
371*f6dc9357SAndroid Build Coastguard Worker #endif // MY_CPU_LE
372*f6dc9357SAndroid Build Coastguard Worker
373*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_CRC_NUM_TABLES_USE <= 1
374*f6dc9357SAndroid Build Coastguard Worker #endif // g_Crc_Algo was declared
375*f6dc9357SAndroid Build Coastguard Worker }
376*f6dc9357SAndroid Build Coastguard Worker
z7_GetFunc_CrcUpdate(unsigned algo)377*f6dc9357SAndroid Build Coastguard Worker Z7_CRC_UPDATE_FUNC z7_GetFunc_CrcUpdate(unsigned algo)
378*f6dc9357SAndroid Build Coastguard Worker {
379*f6dc9357SAndroid Build Coastguard Worker if (algo == 0)
380*f6dc9357SAndroid Build Coastguard Worker return &CrcUpdate;
381*f6dc9357SAndroid Build Coastguard Worker
382*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_CRC_HW_USE)
383*f6dc9357SAndroid Build Coastguard Worker if (algo == sizeof(CRC_HW_WORD_TYPE) * 8)
384*f6dc9357SAndroid Build Coastguard Worker {
385*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_FORCE
386*f6dc9357SAndroid Build Coastguard Worker return &CrcUpdate;
387*f6dc9357SAndroid Build Coastguard Worker #else
388*f6dc9357SAndroid Build Coastguard Worker if (g_Crc_Algo == 0)
389*f6dc9357SAndroid Build Coastguard Worker return &CrcUpdate_HW;
390*f6dc9357SAndroid Build Coastguard Worker #endif
391*f6dc9357SAndroid Build Coastguard Worker }
392*f6dc9357SAndroid Build Coastguard Worker #endif
393*f6dc9357SAndroid Build Coastguard Worker
394*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_CRC_HW_FORCE
395*f6dc9357SAndroid Build Coastguard Worker if (algo == Z7_CRC_NUM_TABLES_USE)
396*f6dc9357SAndroid Build Coastguard Worker return
397*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC_HW_USE
398*f6dc9357SAndroid Build Coastguard Worker &CrcUpdate_Base;
399*f6dc9357SAndroid Build Coastguard Worker #else
400*f6dc9357SAndroid Build Coastguard Worker &CrcUpdate;
401*f6dc9357SAndroid Build Coastguard Worker #endif
402*f6dc9357SAndroid Build Coastguard Worker #endif
403*f6dc9357SAndroid Build Coastguard Worker
404*f6dc9357SAndroid Build Coastguard Worker return NULL;
405*f6dc9357SAndroid Build Coastguard Worker }
406*f6dc9357SAndroid Build Coastguard Worker
407*f6dc9357SAndroid Build Coastguard Worker #undef kCrcPoly
408*f6dc9357SAndroid Build Coastguard Worker #undef Z7_CRC_NUM_TABLES_USE
409*f6dc9357SAndroid Build Coastguard Worker #undef Z7_CRC_NUM_TABLES_TOTAL
410*f6dc9357SAndroid Build Coastguard Worker #undef CRC_UPDATE_BYTE_2
411*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_LE_2
412*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_LE_1
413*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_LE
414*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_BE_2
415*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_BE_1
416*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_BE
417*f6dc9357SAndroid Build Coastguard Worker
418*f6dc9357SAndroid Build Coastguard Worker #undef CRC_HW_UNROLL_BYTES
419*f6dc9357SAndroid Build Coastguard Worker #undef CRC_HW_WORD_FUNC
420*f6dc9357SAndroid Build Coastguard Worker #undef CRC_HW_WORD_TYPE
421