xref: /aosp_15_r20/external/lzma/C/XzCrc64.c (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker /* XzCrc64.c -- CRC64 calculation
2*f6dc9357SAndroid Build Coastguard Worker 2023-12-08 : 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 "XzCrc64.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "CpuArch.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker #define kCrc64Poly UINT64_CONST(0xC96C5795D7870F42)
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker // for debug only : define Z7_CRC64_DEBUG_BE to test big-endian code in little-endian cpu
12*f6dc9357SAndroid Build Coastguard Worker // #define Z7_CRC64_DEBUG_BE
13*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC64_DEBUG_BE
14*f6dc9357SAndroid Build Coastguard Worker #undef MY_CPU_LE
15*f6dc9357SAndroid Build Coastguard Worker #define MY_CPU_BE
16*f6dc9357SAndroid Build Coastguard Worker #endif
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_CRC64_NUM_TABLES
19*f6dc9357SAndroid Build Coastguard Worker   #define Z7_CRC64_NUM_TABLES_USE  Z7_CRC64_NUM_TABLES
20*f6dc9357SAndroid Build Coastguard Worker #else
21*f6dc9357SAndroid Build Coastguard Worker   #define Z7_CRC64_NUM_TABLES_USE  12
22*f6dc9357SAndroid Build Coastguard Worker #endif
23*f6dc9357SAndroid Build Coastguard Worker 
24*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC64_NUM_TABLES_USE < 1
25*f6dc9357SAndroid Build Coastguard Worker   #error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
26*f6dc9357SAndroid Build Coastguard Worker #endif
27*f6dc9357SAndroid Build Coastguard Worker 
28*f6dc9357SAndroid Build Coastguard Worker 
29*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC64_NUM_TABLES_USE != 1
30*f6dc9357SAndroid Build Coastguard Worker 
31*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_BE
32*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_NAME_LE_2(s)   XzCrc64UpdateT ## s
33*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_NAME_LE_1(s)   FUNC_NAME_LE_2(s)
34*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_NAME_LE        FUNC_NAME_LE_1(Z7_CRC64_NUM_TABLES_USE)
35*f6dc9357SAndroid Build Coastguard Worker   UInt64 Z7_FASTCALL FUNC_NAME_LE (UInt64 v, const void *data, size_t size, const UInt64 *table);
36*f6dc9357SAndroid Build Coastguard Worker #endif
37*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_LE
38*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_NAME_BE_2(s)   XzCrc64UpdateBeT ## s
39*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_NAME_BE_1(s)   FUNC_NAME_BE_2(s)
40*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_NAME_BE        FUNC_NAME_BE_1(Z7_CRC64_NUM_TABLES_USE)
41*f6dc9357SAndroid Build Coastguard Worker   UInt64 Z7_FASTCALL FUNC_NAME_BE (UInt64 v, const void *data, size_t size, const UInt64 *table);
42*f6dc9357SAndroid Build Coastguard Worker #endif
43*f6dc9357SAndroid Build Coastguard Worker 
44*f6dc9357SAndroid Build Coastguard Worker #if defined(MY_CPU_LE)
45*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_REF  FUNC_NAME_LE
46*f6dc9357SAndroid Build Coastguard Worker #elif defined(MY_CPU_BE)
47*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_REF  FUNC_NAME_BE
48*f6dc9357SAndroid Build Coastguard Worker #else
49*f6dc9357SAndroid Build Coastguard Worker   #define FUNC_REF  g_Crc64Update
50*f6dc9357SAndroid Build Coastguard Worker   static UInt64 (Z7_FASTCALL *FUNC_REF)(UInt64 v, const void *data, size_t size, const UInt64 *table);
51*f6dc9357SAndroid Build Coastguard Worker #endif
52*f6dc9357SAndroid Build Coastguard Worker 
53*f6dc9357SAndroid Build Coastguard Worker #endif
54*f6dc9357SAndroid Build Coastguard Worker 
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker MY_ALIGN(64)
57*f6dc9357SAndroid Build Coastguard Worker static UInt64 g_Crc64Table[256 * Z7_CRC64_NUM_TABLES_USE];
58*f6dc9357SAndroid Build Coastguard Worker 
59*f6dc9357SAndroid Build Coastguard Worker 
Crc64Update(UInt64 v,const void * data,size_t size)60*f6dc9357SAndroid Build Coastguard Worker UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size)
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC64_NUM_TABLES_USE == 1
63*f6dc9357SAndroid Build Coastguard Worker   #define CRC64_UPDATE_BYTE_2(crc, b)  (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
64*f6dc9357SAndroid Build Coastguard Worker   const UInt64 *table = g_Crc64Table;
65*f6dc9357SAndroid Build Coastguard Worker   const Byte *p = (const Byte *)data;
66*f6dc9357SAndroid Build Coastguard Worker   const Byte *lim = p + size;
67*f6dc9357SAndroid Build Coastguard Worker   for (; p != lim; p++)
68*f6dc9357SAndroid Build Coastguard Worker     v = CRC64_UPDATE_BYTE_2(v, *p);
69*f6dc9357SAndroid Build Coastguard Worker   return v;
70*f6dc9357SAndroid Build Coastguard Worker   #undef CRC64_UPDATE_BYTE_2
71*f6dc9357SAndroid Build Coastguard Worker #else
72*f6dc9357SAndroid Build Coastguard Worker   return FUNC_REF (v, data, size, g_Crc64Table);
73*f6dc9357SAndroid Build Coastguard Worker #endif
74*f6dc9357SAndroid Build Coastguard Worker }
75*f6dc9357SAndroid Build Coastguard Worker 
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker Z7_NO_INLINE
Crc64GenerateTable(void)78*f6dc9357SAndroid Build Coastguard Worker void Z7_FASTCALL Crc64GenerateTable(void)
79*f6dc9357SAndroid Build Coastguard Worker {
80*f6dc9357SAndroid Build Coastguard Worker   unsigned i;
81*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 256; i++)
82*f6dc9357SAndroid Build Coastguard Worker   {
83*f6dc9357SAndroid Build Coastguard Worker     UInt64 r = i;
84*f6dc9357SAndroid Build Coastguard Worker     unsigned j;
85*f6dc9357SAndroid Build Coastguard Worker     for (j = 0; j < 8; j++)
86*f6dc9357SAndroid Build Coastguard Worker       r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1)));
87*f6dc9357SAndroid Build Coastguard Worker     g_Crc64Table[i] = r;
88*f6dc9357SAndroid Build Coastguard Worker   }
89*f6dc9357SAndroid Build Coastguard Worker 
90*f6dc9357SAndroid Build Coastguard Worker #if Z7_CRC64_NUM_TABLES_USE != 1
91*f6dc9357SAndroid Build Coastguard Worker #if 1 || 1 && defined(MY_CPU_X86) // low register count
92*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i++)
93*f6dc9357SAndroid Build Coastguard Worker   {
94*f6dc9357SAndroid Build Coastguard Worker     const UInt64 r0 = g_Crc64Table[(size_t)i];
95*f6dc9357SAndroid Build Coastguard Worker     g_Crc64Table[(size_t)i + 256] = g_Crc64Table[(Byte)r0] ^ (r0 >> 8);
96*f6dc9357SAndroid Build Coastguard Worker   }
97*f6dc9357SAndroid Build Coastguard Worker #else
98*f6dc9357SAndroid Build Coastguard Worker   for (i = 0; i < 256 * (Z7_CRC64_NUM_TABLES_USE - 1); i += 2)
99*f6dc9357SAndroid Build Coastguard Worker   {
100*f6dc9357SAndroid Build Coastguard Worker     UInt64 r0 = g_Crc64Table[(size_t)(i)    ];
101*f6dc9357SAndroid Build Coastguard Worker     UInt64 r1 = g_Crc64Table[(size_t)(i) + 1];
102*f6dc9357SAndroid Build Coastguard Worker     r0 = g_Crc64Table[(Byte)r0] ^ (r0 >> 8);
103*f6dc9357SAndroid Build Coastguard Worker     r1 = g_Crc64Table[(Byte)r1] ^ (r1 >> 8);
104*f6dc9357SAndroid Build Coastguard Worker     g_Crc64Table[(size_t)i + 256    ] = r0;
105*f6dc9357SAndroid Build Coastguard Worker     g_Crc64Table[(size_t)i + 256 + 1] = r1;
106*f6dc9357SAndroid Build Coastguard Worker   }
107*f6dc9357SAndroid Build Coastguard Worker #endif
108*f6dc9357SAndroid Build Coastguard Worker 
109*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_LE
110*f6dc9357SAndroid Build Coastguard Worker   {
111*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_BE
112*f6dc9357SAndroid Build Coastguard Worker     UInt32 k = 1;
113*f6dc9357SAndroid Build Coastguard Worker     if (*(const Byte *)&k == 1)
114*f6dc9357SAndroid Build Coastguard Worker       FUNC_REF = FUNC_NAME_LE;
115*f6dc9357SAndroid Build Coastguard Worker     else
116*f6dc9357SAndroid Build Coastguard Worker #endif
117*f6dc9357SAndroid Build Coastguard Worker     {
118*f6dc9357SAndroid Build Coastguard Worker #ifndef MY_CPU_BE
119*f6dc9357SAndroid Build Coastguard Worker       FUNC_REF = FUNC_NAME_BE;
120*f6dc9357SAndroid Build Coastguard Worker #endif
121*f6dc9357SAndroid Build Coastguard Worker       for (i = 0; i < 256 * Z7_CRC64_NUM_TABLES_USE; i++)
122*f6dc9357SAndroid Build Coastguard Worker       {
123*f6dc9357SAndroid Build Coastguard Worker         const UInt64 x = g_Crc64Table[i];
124*f6dc9357SAndroid Build Coastguard Worker         g_Crc64Table[i] = Z7_BSWAP64(x);
125*f6dc9357SAndroid Build Coastguard Worker       }
126*f6dc9357SAndroid Build Coastguard Worker     }
127*f6dc9357SAndroid Build Coastguard Worker   }
128*f6dc9357SAndroid Build Coastguard Worker #endif // ndef MY_CPU_LE
129*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_CRC64_NUM_TABLES_USE != 1
130*f6dc9357SAndroid Build Coastguard Worker }
131*f6dc9357SAndroid Build Coastguard Worker 
132*f6dc9357SAndroid Build Coastguard Worker #undef kCrc64Poly
133*f6dc9357SAndroid Build Coastguard Worker #undef Z7_CRC64_NUM_TABLES_USE
134*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_REF
135*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_LE_2
136*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_LE_1
137*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_LE
138*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_BE_2
139*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_BE_1
140*f6dc9357SAndroid Build Coastguard Worker #undef FUNC_NAME_BE
141