xref: /aosp_15_r20/external/lzma/C/7zCrc.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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