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