Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/lzma/src/XzCrc64.c
4253 views
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
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
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
142