1 /* XzCrc64.c -- CRC64 calculation
2 2023-04-02 : 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 #ifdef MY_CPU_LE
12   #define CRC64_NUM_TABLES 4
13 #else
14   #define CRC64_NUM_TABLES 5
15 
16   UInt64 Z7_FASTCALL XzCrc64UpdateT1_BeT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
17 #endif
18 
19 #ifndef MY_CPU_BE
20   UInt64 Z7_FASTCALL XzCrc64UpdateT4(UInt64 v, const void *data, size_t size, const UInt64 *table);
21 #endif
22 
23 typedef UInt64 (Z7_FASTCALL *CRC64_FUNC)(UInt64 v, const void *data, size_t size, const UInt64 *table);
24 
25 static CRC64_FUNC g_Crc64Update;
26 UInt64 g_Crc64Table[256 * CRC64_NUM_TABLES];
27 
Crc64Update(UInt64 v, const void *data, size_t size)28 UInt64 Z7_FASTCALL Crc64Update(UInt64 v, const void *data, size_t size)
29 {
30   return g_Crc64Update(v, data, size, g_Crc64Table);
31 }
32 
Crc64Calc(const void *data, size_t size)33 UInt64 Z7_FASTCALL Crc64Calc(const void *data, size_t size)
34 {
35   return g_Crc64Update(CRC64_INIT_VAL, data, size, g_Crc64Table) ^ CRC64_INIT_VAL;
36 }
37 
Crc64GenerateTable(void)38 void Z7_FASTCALL Crc64GenerateTable(void)
39 {
40   UInt32 i;
41   for (i = 0; i < 256; i++)
42   {
43     UInt64 r = i;
44     unsigned j;
45     for (j = 0; j < 8; j++)
46       r = (r >> 1) ^ (kCrc64Poly & ((UInt64)0 - (r & 1)));
47     g_Crc64Table[i] = r;
48   }
49   for (i = 256; i < 256 * CRC64_NUM_TABLES; i++)
50   {
51     const UInt64 r = g_Crc64Table[(size_t)i - 256];
52     g_Crc64Table[i] = g_Crc64Table[r & 0xFF] ^ (r >> 8);
53   }
54 
55   #ifdef MY_CPU_LE
56 
57   g_Crc64Update = XzCrc64UpdateT4;
58 
59   #else
60   {
61     #ifndef MY_CPU_BE
62     UInt32 k = 1;
63     if (*(const Byte *)&k == 1)
64       g_Crc64Update = XzCrc64UpdateT4;
65     else
66     #endif
67     {
68       for (i = 256 * CRC64_NUM_TABLES - 1; i >= 256; i--)
69       {
70         const UInt64 x = g_Crc64Table[(size_t)i - 256];
71         g_Crc64Table[i] = Z7_BSWAP64(x);
72       }
73       g_Crc64Update = XzCrc64UpdateT1_BeT4;
74     }
75   }
76   #endif
77 }
78 
79 #undef kCrc64Poly
80 #undef CRC64_NUM_TABLES
81