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