Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/lzma/src/7zCrcOpt.c
4253 views
1
/* 7zCrcOpt.c -- CRC32 calculation (optimized functions)
2
2023-12-07 : Igor Pavlov : Public domain */
3
4
#include "Precomp.h"
5
6
#include "CpuArch.h"
7
8
#if !defined(Z7_CRC_NUM_TABLES) || Z7_CRC_NUM_TABLES > 1
9
10
// for debug only : define Z7_CRC_DEBUG_BE to test big-endian code in little-endian cpu
11
// #define Z7_CRC_DEBUG_BE
12
#ifdef Z7_CRC_DEBUG_BE
13
#undef MY_CPU_LE
14
#define MY_CPU_BE
15
#endif
16
17
// the value Z7_CRC_NUM_TABLES_USE must be defined to same value as in 7zCrc.c
18
#ifdef Z7_CRC_NUM_TABLES
19
#define Z7_CRC_NUM_TABLES_USE Z7_CRC_NUM_TABLES
20
#else
21
#define Z7_CRC_NUM_TABLES_USE 12
22
#endif
23
24
#if Z7_CRC_NUM_TABLES_USE % 4 || \
25
Z7_CRC_NUM_TABLES_USE < 4 * 1 || \
26
Z7_CRC_NUM_TABLES_USE > 4 * 6
27
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
28
#endif
29
30
31
#ifndef MY_CPU_BE
32
33
#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
34
35
#define Q(n, d) \
36
( (table + ((n) * 4 + 3) * 0x100)[(Byte)(d)] \
37
^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 1 * 8) & 0xFF] \
38
^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 2 * 8) & 0xFF] \
39
^ (table + ((n) * 4 + 0) * 0x100)[((d) >> 3 * 8)] )
40
41
#define R(a) *((const UInt32 *)(const void *)p + (a))
42
43
#define CRC_FUNC_PRE_LE2(step) \
44
UInt32 Z7_FASTCALL CrcUpdateT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
45
46
#define CRC_FUNC_PRE_LE(step) \
47
CRC_FUNC_PRE_LE2(step); \
48
CRC_FUNC_PRE_LE2(step)
49
50
CRC_FUNC_PRE_LE(Z7_CRC_NUM_TABLES_USE)
51
{
52
const Byte *p = (const Byte *)data;
53
const Byte *lim;
54
for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
55
v = CRC_UPDATE_BYTE_2(v, *p);
56
lim = p + size;
57
if (size >= Z7_CRC_NUM_TABLES_USE)
58
{
59
lim -= Z7_CRC_NUM_TABLES_USE;
60
do
61
{
62
v ^= R(0);
63
{
64
#if Z7_CRC_NUM_TABLES_USE == 1 * 4
65
v = Q(0, v);
66
#else
67
#define U2(r, op) \
68
{ d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
69
UInt32 d, x;
70
U2(1, =)
71
#if Z7_CRC_NUM_TABLES_USE >= 3 * 4
72
#define U(r) U2(r, ^=)
73
U(2)
74
#if Z7_CRC_NUM_TABLES_USE >= 4 * 4
75
U(3)
76
#if Z7_CRC_NUM_TABLES_USE >= 5 * 4
77
U(4)
78
#if Z7_CRC_NUM_TABLES_USE >= 6 * 4
79
U(5)
80
#if Z7_CRC_NUM_TABLES_USE >= 7 * 4
81
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
82
#endif
83
#endif
84
#endif
85
#endif
86
#endif
87
#undef U
88
#undef U2
89
v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
90
#endif
91
}
92
p += Z7_CRC_NUM_TABLES_USE;
93
}
94
while (p <= lim);
95
lim += Z7_CRC_NUM_TABLES_USE;
96
}
97
for (; p < lim; p++)
98
v = CRC_UPDATE_BYTE_2(v, *p);
99
return v;
100
}
101
102
#undef CRC_UPDATE_BYTE_2
103
#undef R
104
#undef Q
105
#undef CRC_FUNC_PRE_LE
106
#undef CRC_FUNC_PRE_LE2
107
108
#endif
109
110
111
112
113
#ifndef MY_CPU_LE
114
115
#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[((crc) >> 24) ^ (b)] ^ ((crc) << 8))
116
117
#define Q(n, d) \
118
( (table + ((n) * 4 + 0) * 0x100)[((d)) & 0xFF] \
119
^ (table + ((n) * 4 + 1) * 0x100)[((d) >> 1 * 8) & 0xFF] \
120
^ (table + ((n) * 4 + 2) * 0x100)[((d) >> 2 * 8) & 0xFF] \
121
^ (table + ((n) * 4 + 3) * 0x100)[((d) >> 3 * 8)] )
122
123
#ifdef Z7_CRC_DEBUG_BE
124
#define R(a) GetBe32a((const UInt32 *)(const void *)p + (a))
125
#else
126
#define R(a) *((const UInt32 *)(const void *)p + (a))
127
#endif
128
129
130
#define CRC_FUNC_PRE_BE2(step) \
131
UInt32 Z7_FASTCALL CrcUpdateT1_BeT ## step (UInt32 v, const void *data, size_t size, const UInt32 *table)
132
133
#define CRC_FUNC_PRE_BE(step) \
134
CRC_FUNC_PRE_BE2(step); \
135
CRC_FUNC_PRE_BE2(step)
136
137
CRC_FUNC_PRE_BE(Z7_CRC_NUM_TABLES_USE)
138
{
139
const Byte *p = (const Byte *)data;
140
const Byte *lim;
141
table += 0x100;
142
v = Z7_BSWAP32(v);
143
for (; size && ((unsigned)(ptrdiff_t)p & (7 - (Z7_CRC_NUM_TABLES_USE & 4))) != 0; size--, p++)
144
v = CRC_UPDATE_BYTE_2_BE(v, *p);
145
lim = p + size;
146
if (size >= Z7_CRC_NUM_TABLES_USE)
147
{
148
lim -= Z7_CRC_NUM_TABLES_USE;
149
do
150
{
151
v ^= R(0);
152
{
153
#if Z7_CRC_NUM_TABLES_USE == 1 * 4
154
v = Q(0, v);
155
#else
156
#define U2(r, op) \
157
{ d = R(r); x op Q(Z7_CRC_NUM_TABLES_USE / 4 - 1 - (r), d); }
158
UInt32 d, x;
159
U2(1, =)
160
#if Z7_CRC_NUM_TABLES_USE >= 3 * 4
161
#define U(r) U2(r, ^=)
162
U(2)
163
#if Z7_CRC_NUM_TABLES_USE >= 4 * 4
164
U(3)
165
#if Z7_CRC_NUM_TABLES_USE >= 5 * 4
166
U(4)
167
#if Z7_CRC_NUM_TABLES_USE >= 6 * 4
168
U(5)
169
#if Z7_CRC_NUM_TABLES_USE >= 7 * 4
170
#error Stop_Compiling_Bad_Z7_CRC_NUM_TABLES
171
#endif
172
#endif
173
#endif
174
#endif
175
#endif
176
#undef U
177
#undef U2
178
v = x ^ Q(Z7_CRC_NUM_TABLES_USE / 4 - 1, v);
179
#endif
180
}
181
p += Z7_CRC_NUM_TABLES_USE;
182
}
183
while (p <= lim);
184
lim += Z7_CRC_NUM_TABLES_USE;
185
}
186
for (; p < lim; p++)
187
v = CRC_UPDATE_BYTE_2_BE(v, *p);
188
return Z7_BSWAP32(v);
189
}
190
191
#undef CRC_UPDATE_BYTE_2_BE
192
#undef R
193
#undef Q
194
#undef CRC_FUNC_PRE_BE
195
#undef CRC_FUNC_PRE_BE2
196
197
#endif
198
#undef Z7_CRC_NUM_TABLES_USE
199
#endif
200
201