Coverage Report

Created: 2026-03-31 07:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/rocksdb/util/crc32c.cc
Line
Count
Source
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2
//  This source code is licensed under both the GPLv2 (found in the
3
//  COPYING file in the root directory) and Apache 2.0 License
4
//  (found in the LICENSE.Apache file in the root directory).
5
//
6
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7
// Use of this source code is governed by a BSD-style license that can be
8
// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
//
10
// A portable implementation of crc32c, optimized to handle
11
// four bytes at a time.
12
#include "util/crc32c.h"
13
14
#include <array>
15
#include <cstdint>
16
#include <utility>
17
18
#include "port/lang.h"
19
#include "util/coding.h"
20
#include "util/crc32c_arm64.h"
21
#include "util/math.h"
22
23
#ifdef __powerpc64__
24
#include "util/crc32c_ppc.h"
25
#include "util/crc32c_ppc_constants.h"
26
27
#if __linux__
28
#ifdef ROCKSDB_AUXV_GETAUXVAL_PRESENT
29
#include <sys/auxv.h>
30
#endif
31
32
#ifndef PPC_FEATURE2_VEC_CRYPTO
33
#define PPC_FEATURE2_VEC_CRYPTO 0x02000000
34
#endif
35
36
#ifndef AT_HWCAP2
37
#define AT_HWCAP2 26
38
#endif
39
40
#elif __FreeBSD__
41
#include <machine/cpu.h>
42
#include <sys/auxv.h>
43
#include <sys/elf_common.h>
44
#endif /* __linux__ */
45
46
#endif
47
48
ASSERT_FEATURE_COMPAT_HEADER();
49
50
#ifdef __SSE4_2__
51
#include <nmmintrin.h>
52
#include <wmmintrin.h>
53
#endif
54
55
#if defined(HAVE_ARM64_CRC)
56
bool pmull_runtime_flag = false;
57
#endif
58
59
namespace ROCKSDB_NAMESPACE::crc32c {
60
61
#if defined(HAVE_POWER8) && defined(HAS_ALTIVEC)
62
#ifdef __powerpc64__
63
static int arch_ppc_crc32 = 0;
64
#endif /* __powerpc64__ */
65
#endif
66
67
static const uint32_t table0_[256] = {
68
    0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, 0xc79a971f, 0x35f1141c,
69
    0x26a1e7e8, 0xd4ca64eb, 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b,
70
    0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, 0x105ec76f, 0xe235446c,
71
    0xf165b798, 0x030e349b, 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384,
72
    0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, 0x5d1d08bf, 0xaf768bbc,
73
    0xbc267848, 0x4e4dfb4b, 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a,
74
    0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, 0xaa64d611, 0x580f5512,
75
    0x4b5fa6e6, 0xb93425e5, 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa,
76
    0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, 0xf779deae, 0x05125dad,
77
    0x1642ae59, 0xe4292d5a, 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a,
78
    0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, 0x417b1dbc, 0xb3109ebf,
79
    0xa0406d4b, 0x522bee48, 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957,
80
    0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, 0x0c38d26c, 0xfe53516f,
81
    0xed03a29b, 0x1f682198, 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927,
82
    0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, 0xdbfc821c, 0x2997011f,
83
    0x3ac7f2eb, 0xc8ac71e8, 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7,
84
    0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, 0xa65c047d, 0x5437877e,
85
    0x4767748a, 0xb50cf789, 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859,
86
    0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, 0x7198540d, 0x83f3d70e,
87
    0x90a324fa, 0x62c8a7f9, 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6,
88
    0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, 0x3cdb9bdd, 0xceb018de,
89
    0xdde0eb2a, 0x2f8b6829, 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c,
90
    0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, 0x082f63b7, 0xfa44e0b4,
91
    0xe9141340, 0x1b7f9043, 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c,
92
    0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, 0x55326b08, 0xa759e80b,
93
    0xb4091bff, 0x466298fc, 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c,
94
    0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, 0xa24bb5a6, 0x502036a5,
95
    0x4370c551, 0xb11b4652, 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d,
96
    0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, 0xef087a76, 0x1d63f975,
97
    0x0e330a81, 0xfc588982, 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d,
98
    0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, 0x38cc2a06, 0xcaa7a905,
99
    0xd9f75af1, 0x2b9cd9f2, 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed,
100
    0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, 0x0417b1db, 0xf67c32d8,
101
    0xe52cc12c, 0x1747422f, 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff,
102
    0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, 0xd3d3e1ab, 0x21b862a8,
103
    0x32e8915c, 0xc083125f, 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540,
104
    0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, 0x9e902e7b, 0x6cfbad78,
105
    0x7fab5e8c, 0x8dc0dd8f, 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee,
106
    0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, 0x69e9f0d5, 0x9b8273d6,
107
    0x88d28022, 0x7ab90321, 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e,
108
    0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, 0x34f4f86a, 0xc69f7b69,
109
    0xd5cf889d, 0x27a40b9e, 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e,
110
    0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351};
111
#ifndef __SSE4_2__
112
static const uint32_t table1_[256] = {
113
    0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, 0x4e8a61dc, 0x5d28f9ab,
114
    0x69cf5132, 0x7a6dc945, 0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21,
115
    0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd, 0x3fc5f181, 0x2c6769f6,
116
    0x1880c16f, 0x0b225918, 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4,
117
    0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, 0xec5b53e5, 0xfff9cb92,
118
    0xcb1e630b, 0xd8bcfb7c, 0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b,
119
    0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47, 0xe29f20ba, 0xf13db8cd,
120
    0xc5da1054, 0xd6788823, 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff,
121
    0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, 0x0ec4735f, 0x1d66eb28,
122
    0x298143b1, 0x3a23dbc6, 0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2,
123
    0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e, 0xff17c604, 0xecb55e73,
124
    0xd852f6ea, 0xcbf06e9d, 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41,
125
    0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, 0x2c896460, 0x3f2bfc17,
126
    0x0bcc548e, 0x186eccf9, 0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c,
127
    0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0, 0x5dc6f43d, 0x4e646c4a,
128
    0x7a83c4d3, 0x69215ca4, 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78,
129
    0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, 0xce1644da, 0xddb4dcad,
130
    0xe9537434, 0xfaf1ec43, 0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27,
131
    0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb, 0xbf59d487, 0xacfb4cf0,
132
    0x981ce469, 0x8bbe7c1e, 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2,
133
    0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, 0x6cc776e3, 0x7f65ee94,
134
    0x4b82460d, 0x5820de7a, 0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260,
135
    0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc, 0x66d73941, 0x7575a136,
136
    0x419209af, 0x523091d8, 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004,
137
    0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, 0x8a8c6aa4, 0x992ef2d3,
138
    0xadc95a4a, 0xbe6bc23d, 0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059,
139
    0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185, 0x844819fb, 0x97ea818c,
140
    0xa30d2915, 0xb0afb162, 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be,
141
    0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, 0x57d6bb9f, 0x447423e8,
142
    0x70938b71, 0x63311306, 0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3,
143
    0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f, 0x26992bc2, 0x353bb3b5,
144
    0x01dc1b2c, 0x127e835b, 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287,
145
    0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, 0x4a5e5d21, 0x59fcc556,
146
    0x6d1b6dcf, 0x7eb9f5b8, 0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc,
147
    0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600, 0x3b11cd7c, 0x28b3550b,
148
    0x1c54fd92, 0x0ff665e5, 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439,
149
    0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, 0xe88f6f18, 0xfb2df76f,
150
    0xcfca5ff6, 0xdc68c781, 0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766,
151
    0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba, 0xe64b1c47, 0xf5e98430,
152
    0xc10e2ca9, 0xd2acb4de, 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502,
153
    0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, 0x0a104fa2, 0x19b2d7d5,
154
    0x2d557f4c, 0x3ef7e73b, 0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f,
155
    0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483};
156
static const uint32_t table2_[256] = {
157
    0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, 0x9edea41a, 0x3b9f3664,
158
    0xd1b1f617, 0x74f06469, 0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6,
159
    0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac, 0x70a27d8a, 0xd5e3eff4,
160
    0x3fcd2f87, 0x9a8cbdf9, 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3,
161
    0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, 0xd62de755, 0x736c752b,
162
    0x9942b558, 0x3c032726, 0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67,
163
    0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d, 0xd915c5d1, 0x7c5457af,
164
    0x967a97dc, 0x333b05a2, 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8,
165
    0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, 0x0f382284, 0xaa79b0fa,
166
    0x40577089, 0xe516e2f7, 0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828,
167
    0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32, 0xc76580d9, 0x622412a7,
168
    0x880ad2d4, 0x2d4b40aa, 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0,
169
    0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, 0x61ea1a06, 0xc4ab8878,
170
    0x2e85480b, 0x8bc4da75, 0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20,
171
    0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a, 0x8f96c396, 0x2ad751e8,
172
    0xc0f9919b, 0x65b803e5, 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff,
173
    0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, 0xb8ffdfd7, 0x1dbe4da9,
174
    0xf7908dda, 0x52d11fa4, 0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b,
175
    0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161, 0x56830647, 0xf3c29439,
176
    0x19ec544a, 0xbcadc634, 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e,
177
    0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, 0xf00c9c98, 0x554d0ee6,
178
    0xbf63ce95, 0x1a225ceb, 0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730,
179
    0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a, 0xb3764986, 0x1637dbf8,
180
    0xfc191b8b, 0x595889f5, 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def,
181
    0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, 0x655baed3, 0xc01a3cad,
182
    0x2a34fcde, 0x8f756ea0, 0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f,
183
    0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065, 0x6a638c57, 0xcf221e29,
184
    0x250cde5a, 0x804d4c24, 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e,
185
    0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, 0xccec1688, 0x69ad84f6,
186
    0x83834485, 0x26c2d6fb, 0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae,
187
    0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4, 0x2290cf18, 0x87d15d66,
188
    0x6dff9d15, 0xc8be0f6b, 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71,
189
    0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, 0xd29c5380, 0x77ddc1fe,
190
    0x9df3018d, 0x38b293f3, 0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c,
191
    0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36, 0x3ce08a10, 0x99a1186e,
192
    0x738fd81d, 0xd6ce4a63, 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79,
193
    0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, 0x9a6f10cf, 0x3f2e82b1,
194
    0xd50042c2, 0x7041d0bc, 0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd,
195
    0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7, 0x9557324b, 0x3016a035,
196
    0xda386046, 0x7f79f238, 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622,
197
    0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, 0x437ad51e, 0xe63b4760,
198
    0x0c158713, 0xa954156d, 0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2,
199
    0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8};
200
static const uint32_t table3_[256] = {
201
    0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, 0x7b2231f3, 0xa6679b4b,
202
    0xc4451272, 0x1900b8ca, 0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf,
203
    0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c, 0xe964b13d, 0x34211b85,
204
    0x560392bc, 0x8b463804, 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7,
205
    0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, 0x6402e328, 0xb9474990,
206
    0xdb65c0a9, 0x06206a11, 0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2,
207
    0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41, 0x2161776d, 0xfc24ddd5,
208
    0x9e0654ec, 0x4343fe54, 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7,
209
    0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, 0x45639445, 0x98263efd,
210
    0xfa04b7c4, 0x27411d7c, 0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69,
211
    0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a, 0xaba65fe7, 0x76e3f55f,
212
    0x14c17c66, 0xc984d6de, 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d,
213
    0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, 0x26c00df2, 0xfb85a74a,
214
    0x99a72e73, 0x44e284cb, 0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3,
215
    0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610, 0xb4868d3c, 0x69c32784,
216
    0x0be1aebd, 0xd6a40405, 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6,
217
    0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, 0x07a17a9f, 0xdae4d027,
218
    0xb8c6591e, 0x6583f3a6, 0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3,
219
    0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040, 0x95e7fa51, 0x48a250e9,
220
    0x2a80d9d0, 0xf7c57368, 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b,
221
    0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, 0x1881a844, 0xc5c402fc,
222
    0xa7e68bc5, 0x7aa3217d, 0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006,
223
    0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5, 0xa4e4aad9, 0x79a10061,
224
    0x1b838958, 0xc6c623e0, 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213,
225
    0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, 0xc0e649f1, 0x1da3e349,
226
    0x7f816a70, 0xa2c4c0c8, 0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd,
227
    0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e, 0x8585ddb4, 0x58c0770c,
228
    0x3ae2fe35, 0xe7a7548d, 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e,
229
    0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, 0x08e38fa1, 0xd5a62519,
230
    0xb784ac20, 0x6ac10698, 0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0,
231
    0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443, 0x9aa50f6f, 0x47e0a5d7,
232
    0x25c22cee, 0xf8878656, 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5,
233
    0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, 0x8224a72b, 0x5f610d93,
234
    0x3d4384aa, 0xe0062e12, 0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07,
235
    0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4, 0x106227e5, 0xcd278d5d,
236
    0xaf050464, 0x7240aedc, 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f,
237
    0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, 0x9d0475f0, 0x4041df48,
238
    0x22635671, 0xff26fcc9, 0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a,
239
    0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99, 0xd867e1b5, 0x05224b0d,
240
    0x6700c234, 0xba45688c, 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f,
241
    0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, 0xbc65029d, 0x6120a825,
242
    0x0302211c, 0xde478ba4, 0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1,
243
    0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842};
244
245
// Used to fetch a naturally-aligned 32-bit word in little endian byte-order
246
static inline uint32_t LE_LOAD32(const uint8_t* p) {
247
  return DecodeFixed32(reinterpret_cast<const char*>(p));
248
}
249
#endif  // !__SSE4_2__
250
251
0
static inline void DefaultCRC32(uint64_t* l, uint8_t const** p) {
252
#ifndef __SSE4_2__
253
  uint32_t c = static_cast<uint32_t>(*l ^ LE_LOAD32(*p));
254
  *p += 4;
255
  *l = table3_[c & 0xff] ^ table2_[(c >> 8) & 0xff] ^
256
       table1_[(c >> 16) & 0xff] ^ table0_[c >> 24];
257
  // DO it twice.
258
  c = static_cast<uint32_t>(*l ^ LE_LOAD32(*p));
259
  *p += 4;
260
  *l = table3_[c & 0xff] ^ table2_[(c >> 8) & 0xff] ^
261
       table1_[(c >> 16) & 0xff] ^ table0_[c >> 24];
262
#elif defined(__LP64__) || defined(_WIN64)
263
  *l = _mm_crc32_u64(*l, DecodeFixed64(reinterpret_cast<const char*>(*p)));
264
0
  *p += 8;
265
#else
266
  *l = _mm_crc32_u32(static_cast<unsigned int>(*l), LE_LOAD32(*p));
267
  *p += 4;
268
  *l = _mm_crc32_u32(static_cast<unsigned int>(*l), LE_LOAD32(*p));
269
  *p += 4;
270
#endif
271
0
}
272
273
template <void (*CRC32)(uint64_t*, uint8_t const**)>
274
0
uint32_t ExtendImpl(uint32_t crc, const char* buf, size_t size) {
275
0
  const uint8_t* p = reinterpret_cast<const uint8_t*>(buf);
276
0
  const uint8_t* e = p + size;
277
0
  uint64_t l = crc ^ 0xffffffffu;
278
279
// Align n to (1 << m) byte boundary
280
0
#define ALIGN(n, m) ((n + ((1 << m) - 1)) & ~((1 << m) - 1))
281
282
0
#define STEP1                  \
283
0
  do {                         \
284
0
    int c = (l & 0xff) ^ *p++; \
285
0
    l = table0_[c] ^ (l >> 8); \
286
0
  } while (0)
287
288
  // Point x at first 16-byte aligned byte in string.  This might be
289
  // just past the end of the string.
290
0
  const uintptr_t pval = reinterpret_cast<uintptr_t>(p);
291
0
  const uint8_t* x = reinterpret_cast<const uint8_t*>(ALIGN(pval, 4));
292
0
  if (x <= e) {
293
    // Process bytes until finished or p is 16-byte aligned
294
0
    while (p != x) {
295
0
      STEP1;
296
0
    }
297
0
  }
298
  // Process bytes 16 at a time
299
0
  while ((e - p) >= 16) {
300
0
    CRC32(&l, &p);
301
0
    CRC32(&l, &p);
302
0
  }
303
  // Process bytes 8 at a time
304
0
  while ((e - p) >= 8) {
305
0
    CRC32(&l, &p);
306
0
  }
307
  // Process the last few bytes
308
0
  while (p != e) {
309
0
    STEP1;
310
0
  }
311
0
#undef STEP1
312
0
#undef ALIGN
313
0
  return static_cast<uint32_t>(l ^ 0xffffffffu);
314
0
}
315
316
using Function = uint32_t (*)(uint32_t, const char*, size_t);
317
318
#if defined(HAVE_POWER8) && defined(HAS_ALTIVEC)
319
uint32_t ExtendPPCImpl(uint32_t crc, const char* buf, size_t size) {
320
  return crc32c_ppc(crc, (const unsigned char*)buf, size);
321
}
322
323
#if __linux__
324
static int arch_ppc_probe(void) {
325
  arch_ppc_crc32 = 0;
326
327
#if defined(__powerpc64__) && defined(ROCKSDB_AUXV_GETAUXVAL_PRESENT)
328
  if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) arch_ppc_crc32 = 1;
329
#endif /* __powerpc64__ */
330
331
  return arch_ppc_crc32;
332
}
333
#elif __FreeBSD__
334
static int arch_ppc_probe(void) {
335
  unsigned long cpufeatures;
336
  arch_ppc_crc32 = 0;
337
338
#if defined(__powerpc64__)
339
  elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof(cpufeatures));
340
  if (cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO) arch_ppc_crc32 = 1;
341
#endif  /* __powerpc64__ */
342
343
  return arch_ppc_crc32;
344
}
345
#endif  // __linux__
346
347
static bool isAltiVec() {
348
  if (arch_ppc_probe()) {
349
    return true;
350
  } else {
351
    return false;
352
  }
353
}
354
#endif
355
356
#if defined(HAVE_ARM64_CRC)
357
uint32_t ExtendARMImpl(uint32_t crc, const char* buf, size_t size) {
358
  return crc32c_arm64(crc, (const unsigned char*)buf, size);
359
}
360
#endif
361
362
40.2k
std::string IsFastCrc32Supported() {
363
40.2k
  bool has_fast_crc = false;
364
40.2k
  std::string fast_zero_msg;
365
40.2k
  std::string arch;
366
#ifdef HAVE_POWER8
367
#ifdef HAS_ALTIVEC
368
  if (arch_ppc_probe()) {
369
    has_fast_crc = true;
370
    arch = "PPC";
371
  }
372
#else
373
  has_fast_crc = false;
374
  arch = "PPC";
375
#endif
376
#elif defined(HAVE_ARM64_CRC)
377
  if (crc32c_runtime_check()) {
378
    has_fast_crc = true;
379
    arch = "Arm64";
380
    pmull_runtime_flag = crc32c_pmull_runtime_check();
381
  } else {
382
    has_fast_crc = false;
383
    arch = "Arm64";
384
  }
385
#else
386
40.2k
#ifdef __SSE4_2__
387
40.2k
  has_fast_crc = true;
388
40.2k
#endif  // __SSE4_2__
389
40.2k
  arch = "x86";
390
40.2k
#endif
391
40.2k
  if (has_fast_crc) {
392
40.2k
    fast_zero_msg.append("Supported on " + arch);
393
40.2k
  } else {
394
0
    fast_zero_msg.append("Not supported on " + arch);
395
0
  }
396
40.2k
  return fast_zero_msg;
397
40.2k
}
398
399
/*
400
 * Copyright 2016 Ferry Toth, Exalon Delft BV, The Netherlands
401
 *  This software is provided 'as-is', without any express or implied
402
 * warranty.  In no event will the author be held liable for any damages
403
 * arising from the use of this software.
404
 *  Permission is granted to anyone to use this software for any purpose,
405
 * including commercial applications, and to alter it and redistribute it
406
 * freely, subject to the following restrictions:
407
 *  1. The origin of this software must not be misrepresented; you must not
408
 *   claim that you wrote the original software. If you use this software
409
 *   in a product, an acknowledgment in the product documentation would be
410
 *   appreciated but is not required.
411
 * 2. Altered source versions must be plainly marked as such, and must not be
412
 *   misrepresented as being the original software.
413
 * 3. This notice may not be removed or altered from any source distribution.
414
 *  Ferry Toth
415
 * ftoth@exalondelft.nl
416
 *
417
 * https://github.com/htot/crc32c
418
 *
419
 * Modified by Facebook
420
 *
421
 * Original intel whitepaper:
422
 * "Fast CRC Computation for iSCSI Polynomial Using CRC32 Instruction"
423
 * https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/crc-iscsi-polynomial-crc32-instruction-paper.pdf
424
 *
425
 * This version is from the folly library, created by Dave Watson
426
 * <davejwatson@fb.com>
427
 *
428
 */
429
#if defined(__SSE4_2__) && defined(__PCLMUL__)
430
431
#define CRCtriplet(crc, buf, offset)                  \
432
12.2M
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
433
12.2M
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset)); \
434
12.2M
  crc##2 = _mm_crc32_u64(crc##2, *(buf##2 + offset));
435
436
#define CRCduplet(crc, buf, offset)                   \
437
229k
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
438
229k
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset));
439
440
#define CRCsinglet(crc, buf, offset) \
441
6.04M
  crc = _mm_crc32_u64(crc, *(uint64_t*)(buf + offset));
442
443
// Numbers taken directly from intel whitepaper.
444
// clang-format off
445
const uint64_t clmul_constants[] = {
446
    0x14cd00bd6, 0x105ec76f0, 0x0ba4fc28e, 0x14cd00bd6,
447
    0x1d82c63da, 0x0f20c0dfe, 0x09e4addf8, 0x0ba4fc28e,
448
    0x039d3b296, 0x1384aa63a, 0x102f9b8a2, 0x1d82c63da,
449
    0x14237f5e6, 0x01c291d04, 0x00d3b6092, 0x09e4addf8,
450
    0x0c96cfdc0, 0x0740eef02, 0x18266e456, 0x039d3b296,
451
    0x0daece73e, 0x0083a6eec, 0x0ab7aff2a, 0x102f9b8a2,
452
    0x1248ea574, 0x1c1733996, 0x083348832, 0x14237f5e6,
453
    0x12c743124, 0x02ad91c30, 0x0b9e02b86, 0x00d3b6092,
454
    0x018b33a4e, 0x06992cea2, 0x1b331e26a, 0x0c96cfdc0,
455
    0x17d35ba46, 0x07e908048, 0x1bf2e8b8a, 0x18266e456,
456
    0x1a3e0968a, 0x11ed1f9d8, 0x0ce7f39f4, 0x0daece73e,
457
    0x061d82e56, 0x0f1d0f55e, 0x0d270f1a2, 0x0ab7aff2a,
458
    0x1c3f5f66c, 0x0a87ab8a8, 0x12ed0daac, 0x1248ea574,
459
    0x065863b64, 0x08462d800, 0x11eef4f8e, 0x083348832,
460
    0x1ee54f54c, 0x071d111a8, 0x0b3e32c28, 0x12c743124,
461
    0x0064f7f26, 0x0ffd852c6, 0x0dd7e3b0c, 0x0b9e02b86,
462
    0x0f285651c, 0x0dcb17aa4, 0x010746f3c, 0x018b33a4e,
463
    0x1c24afea4, 0x0f37c5aee, 0x0271d9844, 0x1b331e26a,
464
    0x08e766a0c, 0x06051d5a2, 0x093a5f730, 0x17d35ba46,
465
    0x06cb08e5c, 0x11d5ca20e, 0x06b749fb2, 0x1bf2e8b8a,
466
    0x1167f94f2, 0x021f3d99c, 0x0cec3662e, 0x1a3e0968a,
467
    0x19329634a, 0x08f158014, 0x0e6fc4e6a, 0x0ce7f39f4,
468
    0x08227bb8a, 0x1a5e82106, 0x0b0cd4768, 0x061d82e56,
469
    0x13c2b89c4, 0x188815ab2, 0x0d7a4825c, 0x0d270f1a2,
470
    0x10f5ff2ba, 0x105405f3e, 0x00167d312, 0x1c3f5f66c,
471
    0x0f6076544, 0x0e9adf796, 0x026f6a60a, 0x12ed0daac,
472
    0x1a2adb74e, 0x096638b34, 0x19d34af3a, 0x065863b64,
473
    0x049c3cc9c, 0x1e50585a0, 0x068bce87a, 0x11eef4f8e,
474
    0x1524fa6c6, 0x19f1c69dc, 0x16cba8aca, 0x1ee54f54c,
475
    0x042d98888, 0x12913343e, 0x1329d9f7e, 0x0b3e32c28,
476
    0x1b1c69528, 0x088f25a3a, 0x02178513a, 0x0064f7f26,
477
    0x0e0ac139e, 0x04e36f0b0, 0x0170076fa, 0x0dd7e3b0c,
478
    0x141a1a2e2, 0x0bd6f81f8, 0x16ad828b4, 0x0f285651c,
479
    0x041d17b64, 0x19425cbba, 0x1fae1cc66, 0x010746f3c,
480
    0x1a75b4b00, 0x18db37e8a, 0x0f872e54c, 0x1c24afea4,
481
    0x01e41e9fc, 0x04c144932, 0x086d8e4d2, 0x0271d9844,
482
    0x160f7af7a, 0x052148f02, 0x05bb8f1bc, 0x08e766a0c,
483
    0x0a90fd27a, 0x0a3c6f37a, 0x0b3af077a, 0x093a5f730,
484
    0x04984d782, 0x1d22c238e, 0x0ca6ef3ac, 0x06cb08e5c,
485
    0x0234e0b26, 0x063ded06a, 0x1d88abd4a, 0x06b749fb2,
486
    0x04597456a, 0x04d56973c, 0x0e9e28eb4, 0x1167f94f2,
487
    0x07b3ff57a, 0x19385bf2e, 0x0c9c8b782, 0x0cec3662e,
488
    0x13a9cba9e, 0x0e417f38a, 0x093e106a4, 0x19329634a,
489
    0x167001a9c, 0x14e727980, 0x1ddffc5d4, 0x0e6fc4e6a,
490
    0x00df04680, 0x0d104b8fc, 0x02342001e, 0x08227bb8a,
491
    0x00a2a8d7e, 0x05b397730, 0x168763fa6, 0x0b0cd4768,
492
    0x1ed5a407a, 0x0e78eb416, 0x0d2c3ed1a, 0x13c2b89c4,
493
    0x0995a5724, 0x1641378f0, 0x19b1afbc4, 0x0d7a4825c,
494
    0x109ffedc0, 0x08d96551c, 0x0f2271e60, 0x10f5ff2ba,
495
    0x00b0bf8ca, 0x00bf80dd2, 0x123888b7a, 0x00167d312,
496
    0x1e888f7dc, 0x18dcddd1c, 0x002ee03b2, 0x0f6076544,
497
    0x183e8d8fe, 0x06a45d2b2, 0x133d7a042, 0x026f6a60a,
498
    0x116b0f50c, 0x1dd3e10e8, 0x05fabe670, 0x1a2adb74e,
499
    0x130004488, 0x0de87806c, 0x000bcf5f6, 0x19d34af3a,
500
    0x18f0c7078, 0x014338754, 0x017f27698, 0x049c3cc9c,
501
    0x058ca5f00, 0x15e3e77ee, 0x1af900c24, 0x068bce87a,
502
    0x0b5cfca28, 0x0dd07448e, 0x0ded288f8, 0x1524fa6c6,
503
    0x059f229bc, 0x1d8048348, 0x06d390dec, 0x16cba8aca,
504
    0x037170390, 0x0a3e3e02c, 0x06353c1cc, 0x042d98888,
505
    0x0c4584f5c, 0x0d73c7bea, 0x1f16a3418, 0x1329d9f7e,
506
    0x0531377e2, 0x185137662, 0x1d8d9ca7c, 0x1b1c69528,
507
    0x0b25b29f2, 0x18a08b5bc, 0x19fb2a8b0, 0x02178513a,
508
    0x1a08fe6ac, 0x1da758ae0, 0x045cddf4e, 0x0e0ac139e,
509
    0x1a91647f2, 0x169cf9eb0, 0x1a0f717c4, 0x0170076fa,
510
};
511
512
// Compute the crc32c value for buffer smaller than 8
513
#ifdef ROCKSDB_UBSAN_RUN
514
#if defined(__clang__)
515
__attribute__((__no_sanitize__("alignment")))
516
#elif defined(__GNUC__)
517
__attribute__((__no_sanitize_undefined__))
518
#endif
519
#endif
520
inline void align_to_8(
521
    size_t len,
522
    uint64_t& crc0, // crc so far, updated on return
523
14.2M
    const unsigned char*& next) { // next data pointer, updated on return
524
14.2M
  uint32_t crc32bit = static_cast<uint32_t>(crc0);
525
14.2M
  if (len & 0x04) {
526
824k
    crc32bit = _mm_crc32_u32(crc32bit, *(uint32_t*)next);
527
824k
    next += sizeof(uint32_t);
528
824k
  }
529
14.2M
  if (len & 0x02) {
530
1.17M
    crc32bit = _mm_crc32_u16(crc32bit, *(uint16_t*)next);
531
1.17M
    next += sizeof(uint16_t);
532
1.17M
  }
533
14.2M
  if (len & 0x01) {
534
13.0M
    crc32bit = _mm_crc32_u8(crc32bit, *(next));
535
13.0M
    next++;
536
13.0M
  }
537
14.2M
  crc0 = crc32bit;
538
14.2M
}
539
540
//
541
// CombineCRC performs pclmulqdq multiplication of 2 partial CRC's and a well
542
// chosen constant and xor's these with the remaining CRC.
543
//
544
inline uint64_t CombineCRC(
545
    size_t block_size,
546
    uint64_t crc0,
547
    uint64_t crc1,
548
    uint64_t crc2,
549
229k
    const uint64_t* next2) {
550
229k
  const auto multiplier =
551
229k
      *(reinterpret_cast<const __m128i*>(clmul_constants) + block_size - 1);
552
229k
  const auto crc0_xmm = _mm_set_epi64x(0, crc0);
553
229k
  const auto res0 = _mm_clmulepi64_si128(crc0_xmm, multiplier, 0x00);
554
229k
  const auto crc1_xmm = _mm_set_epi64x(0, crc1);
555
229k
  const auto res1 = _mm_clmulepi64_si128(crc1_xmm, multiplier, 0x10);
556
229k
  const auto res = _mm_xor_si128(res0, res1);
557
229k
  crc0 = _mm_cvtsi128_si64(res);
558
229k
  crc0 = crc0 ^ *((uint64_t*)next2 - 1);
559
229k
  crc2 = _mm_crc32_u64(crc2, crc0);
560
229k
  return crc2;
561
229k
}
562
563
// Compute CRC-32C using the Intel hardware instruction.
564
#ifdef ROCKSDB_UBSAN_RUN
565
#if defined(__clang__)
566
__attribute__((__no_sanitize__("alignment")))
567
#elif defined(__GNUC__)
568
__attribute__((__no_sanitize_undefined__))
569
#endif
570
#endif
571
14.0M
uint32_t crc32c_3way(uint32_t crc, const char* buf, size_t len) {
572
14.0M
  const unsigned char* next = (const unsigned char*)buf;
573
14.0M
  uint64_t count;
574
14.0M
  uint64_t crc0, crc1, crc2;
575
14.0M
  crc0 = crc ^ 0xffffffffu;
576
577
578
14.0M
  if (len >= 8) {
579
    // if len > 216 then align and use triplets
580
1.49M
    if (len > 216) {
581
165k
      {
582
        // Work on the bytes (< 8) before the first 8-byte alignment addr starts
583
165k
        uint64_t align_bytes = (8 - (uintptr_t)next) & 7;
584
165k
        len -= align_bytes;
585
165k
        align_to_8(align_bytes, crc0, next);
586
165k
      }
587
588
      // Now work on the remaining blocks
589
165k
      count = len / 24; // number of triplets
590
165k
      len %= 24; // bytes remaining
591
165k
      uint64_t n = count >> 7; // #blocks = first block + full blocks
592
165k
      uint64_t block_size = count & 127;
593
165k
      if (block_size == 0) {
594
144
        block_size = 128;
595
165k
      } else {
596
165k
        n++;
597
165k
      }
598
      // points to the first byte of the next block
599
165k
      const uint64_t* next0 = (uint64_t*)next + block_size;
600
165k
      const uint64_t* next1 = next0 + block_size;
601
165k
      const uint64_t* next2 = next1 + block_size;
602
603
165k
      crc1 = crc2 = 0;
604
      // Use Duff's device, a for() loop inside a switch()
605
      // statement. This needs to execute at least once, round len
606
      // down to nearest triplet multiple
607
165k
      switch (block_size) {
608
144
        case 128:
609
64.1k
          do {
610
            // jumps here for a full block of len 128
611
64.1k
            CRCtriplet(crc, next, -128);
612
64.1k
            FALLTHROUGH_INTENDED;
613
64.2k
            case 127:
614
              // jumps here or below for the first block smaller
615
64.2k
              CRCtriplet(crc, next, -127);
616
64.2k
              FALLTHROUGH_INTENDED;
617
64.3k
            case 126:
618
64.3k
              CRCtriplet(crc, next, -126); // than 128
619
64.3k
              FALLTHROUGH_INTENDED;
620
64.4k
            case 125:
621
64.4k
              CRCtriplet(crc, next, -125);
622
64.4k
              FALLTHROUGH_INTENDED;
623
64.5k
            case 124:
624
64.5k
              CRCtriplet(crc, next, -124);
625
64.5k
              FALLTHROUGH_INTENDED;
626
64.7k
            case 123:
627
64.7k
              CRCtriplet(crc, next, -123);
628
64.7k
              FALLTHROUGH_INTENDED;
629
64.8k
            case 122:
630
64.8k
              CRCtriplet(crc, next, -122);
631
64.8k
              FALLTHROUGH_INTENDED;
632
64.9k
            case 121:
633
64.9k
              CRCtriplet(crc, next, -121);
634
64.9k
              FALLTHROUGH_INTENDED;
635
65.0k
            case 120:
636
65.0k
              CRCtriplet(crc, next, -120);
637
65.0k
              FALLTHROUGH_INTENDED;
638
65.1k
            case 119:
639
65.1k
              CRCtriplet(crc, next, -119);
640
65.1k
              FALLTHROUGH_INTENDED;
641
65.3k
            case 118:
642
65.3k
              CRCtriplet(crc, next, -118);
643
65.3k
              FALLTHROUGH_INTENDED;
644
65.5k
            case 117:
645
65.5k
              CRCtriplet(crc, next, -117);
646
65.5k
              FALLTHROUGH_INTENDED;
647
65.7k
            case 116:
648
65.7k
              CRCtriplet(crc, next, -116);
649
65.7k
              FALLTHROUGH_INTENDED;
650
65.8k
            case 115:
651
65.8k
              CRCtriplet(crc, next, -115);
652
65.8k
              FALLTHROUGH_INTENDED;
653
66.0k
            case 114:
654
66.0k
              CRCtriplet(crc, next, -114);
655
66.0k
              FALLTHROUGH_INTENDED;
656
66.1k
            case 113:
657
66.1k
              CRCtriplet(crc, next, -113);
658
66.1k
              FALLTHROUGH_INTENDED;
659
66.4k
            case 112:
660
66.4k
              CRCtriplet(crc, next, -112);
661
66.4k
              FALLTHROUGH_INTENDED;
662
66.6k
            case 111:
663
66.6k
              CRCtriplet(crc, next, -111);
664
66.6k
              FALLTHROUGH_INTENDED;
665
66.8k
            case 110:
666
66.8k
              CRCtriplet(crc, next, -110);
667
66.8k
              FALLTHROUGH_INTENDED;
668
67.0k
            case 109:
669
67.0k
              CRCtriplet(crc, next, -109);
670
67.0k
              FALLTHROUGH_INTENDED;
671
67.3k
            case 108:
672
67.3k
              CRCtriplet(crc, next, -108);
673
67.3k
              FALLTHROUGH_INTENDED;
674
67.6k
            case 107:
675
67.6k
              CRCtriplet(crc, next, -107);
676
67.6k
              FALLTHROUGH_INTENDED;
677
67.7k
            case 106:
678
67.7k
              CRCtriplet(crc, next, -106);
679
67.7k
              FALLTHROUGH_INTENDED;
680
67.9k
            case 105:
681
67.9k
              CRCtriplet(crc, next, -105);
682
67.9k
              FALLTHROUGH_INTENDED;
683
68.1k
            case 104:
684
68.1k
              CRCtriplet(crc, next, -104);
685
68.1k
              FALLTHROUGH_INTENDED;
686
68.2k
            case 103:
687
68.2k
              CRCtriplet(crc, next, -103);
688
68.2k
              FALLTHROUGH_INTENDED;
689
68.4k
            case 102:
690
68.4k
              CRCtriplet(crc, next, -102);
691
68.4k
              FALLTHROUGH_INTENDED;
692
68.7k
            case 101:
693
68.7k
              CRCtriplet(crc, next, -101);
694
68.7k
              FALLTHROUGH_INTENDED;
695
68.8k
            case 100:
696
68.8k
              CRCtriplet(crc, next, -100);
697
68.8k
              FALLTHROUGH_INTENDED;
698
68.9k
            case 99:
699
68.9k
              CRCtriplet(crc, next, -99);
700
68.9k
              FALLTHROUGH_INTENDED;
701
69.0k
            case 98:
702
69.0k
              CRCtriplet(crc, next, -98);
703
69.0k
              FALLTHROUGH_INTENDED;
704
69.1k
            case 97:
705
69.1k
              CRCtriplet(crc, next, -97);
706
69.1k
              FALLTHROUGH_INTENDED;
707
69.3k
            case 96:
708
69.3k
              CRCtriplet(crc, next, -96);
709
69.3k
              FALLTHROUGH_INTENDED;
710
69.6k
            case 95:
711
69.6k
              CRCtriplet(crc, next, -95);
712
69.6k
              FALLTHROUGH_INTENDED;
713
69.9k
            case 94:
714
69.9k
              CRCtriplet(crc, next, -94);
715
69.9k
              FALLTHROUGH_INTENDED;
716
71.0k
            case 93:
717
71.0k
              CRCtriplet(crc, next, -93);
718
71.0k
              FALLTHROUGH_INTENDED;
719
72.2k
            case 92:
720
72.2k
              CRCtriplet(crc, next, -92);
721
72.2k
              FALLTHROUGH_INTENDED;
722
72.4k
            case 91:
723
72.4k
              CRCtriplet(crc, next, -91);
724
72.4k
              FALLTHROUGH_INTENDED;
725
72.6k
            case 90:
726
72.6k
              CRCtriplet(crc, next, -90);
727
72.6k
              FALLTHROUGH_INTENDED;
728
72.8k
            case 89:
729
72.8k
              CRCtriplet(crc, next, -89);
730
72.8k
              FALLTHROUGH_INTENDED;
731
73.0k
            case 88:
732
73.0k
              CRCtriplet(crc, next, -88);
733
73.0k
              FALLTHROUGH_INTENDED;
734
73.2k
            case 87:
735
73.2k
              CRCtriplet(crc, next, -87);
736
73.2k
              FALLTHROUGH_INTENDED;
737
73.6k
            case 86:
738
73.6k
              CRCtriplet(crc, next, -86);
739
73.6k
              FALLTHROUGH_INTENDED;
740
75.2k
            case 85:
741
75.2k
              CRCtriplet(crc, next, -85);
742
75.2k
              FALLTHROUGH_INTENDED;
743
76.6k
            case 84:
744
76.6k
              CRCtriplet(crc, next, -84);
745
76.6k
              FALLTHROUGH_INTENDED;
746
76.9k
            case 83:
747
76.9k
              CRCtriplet(crc, next, -83);
748
76.9k
              FALLTHROUGH_INTENDED;
749
77.2k
            case 82:
750
77.2k
              CRCtriplet(crc, next, -82);
751
77.2k
              FALLTHROUGH_INTENDED;
752
77.5k
            case 81:
753
77.5k
              CRCtriplet(crc, next, -81);
754
77.5k
              FALLTHROUGH_INTENDED;
755
77.9k
            case 80:
756
77.9k
              CRCtriplet(crc, next, -80);
757
77.9k
              FALLTHROUGH_INTENDED;
758
78.3k
            case 79:
759
78.3k
              CRCtriplet(crc, next, -79);
760
78.3k
              FALLTHROUGH_INTENDED;
761
78.6k
            case 78:
762
78.6k
              CRCtriplet(crc, next, -78);
763
78.6k
              FALLTHROUGH_INTENDED;
764
78.8k
            case 77:
765
78.8k
              CRCtriplet(crc, next, -77);
766
78.8k
              FALLTHROUGH_INTENDED;
767
79.1k
            case 76:
768
79.1k
              CRCtriplet(crc, next, -76);
769
79.1k
              FALLTHROUGH_INTENDED;
770
79.3k
            case 75:
771
79.3k
              CRCtriplet(crc, next, -75);
772
79.3k
              FALLTHROUGH_INTENDED;
773
79.6k
            case 74:
774
79.6k
              CRCtriplet(crc, next, -74);
775
79.6k
              FALLTHROUGH_INTENDED;
776
79.8k
            case 73:
777
79.8k
              CRCtriplet(crc, next, -73);
778
79.8k
              FALLTHROUGH_INTENDED;
779
80.3k
            case 72:
780
80.3k
              CRCtriplet(crc, next, -72);
781
80.3k
              FALLTHROUGH_INTENDED;
782
80.6k
            case 71:
783
80.6k
              CRCtriplet(crc, next, -71);
784
80.6k
              FALLTHROUGH_INTENDED;
785
80.8k
            case 70:
786
80.8k
              CRCtriplet(crc, next, -70);
787
80.8k
              FALLTHROUGH_INTENDED;
788
81.3k
            case 69:
789
81.3k
              CRCtriplet(crc, next, -69);
790
81.3k
              FALLTHROUGH_INTENDED;
791
82.8k
            case 68:
792
82.8k
              CRCtriplet(crc, next, -68);
793
82.8k
              FALLTHROUGH_INTENDED;
794
83.0k
            case 67:
795
83.0k
              CRCtriplet(crc, next, -67);
796
83.0k
              FALLTHROUGH_INTENDED;
797
83.4k
            case 66:
798
83.4k
              CRCtriplet(crc, next, -66);
799
83.4k
              FALLTHROUGH_INTENDED;
800
83.7k
            case 65:
801
83.7k
              CRCtriplet(crc, next, -65);
802
83.7k
              FALLTHROUGH_INTENDED;
803
84.0k
            case 64:
804
84.0k
              CRCtriplet(crc, next, -64);
805
84.0k
              FALLTHROUGH_INTENDED;
806
84.3k
            case 63:
807
84.3k
              CRCtriplet(crc, next, -63);
808
84.3k
              FALLTHROUGH_INTENDED;
809
84.8k
            case 62:
810
84.8k
              CRCtriplet(crc, next, -62);
811
84.8k
              FALLTHROUGH_INTENDED;
812
85.6k
            case 61:
813
85.6k
              CRCtriplet(crc, next, -61);
814
85.6k
              FALLTHROUGH_INTENDED;
815
86.0k
            case 60:
816
86.0k
              CRCtriplet(crc, next, -60);
817
86.0k
              FALLTHROUGH_INTENDED;
818
86.4k
            case 59:
819
86.4k
              CRCtriplet(crc, next, -59);
820
86.4k
              FALLTHROUGH_INTENDED;
821
87.0k
            case 58:
822
87.0k
              CRCtriplet(crc, next, -58);
823
87.0k
              FALLTHROUGH_INTENDED;
824
88.9k
            case 57:
825
88.9k
              CRCtriplet(crc, next, -57);
826
88.9k
              FALLTHROUGH_INTENDED;
827
89.2k
            case 56:
828
89.2k
              CRCtriplet(crc, next, -56);
829
89.2k
              FALLTHROUGH_INTENDED;
830
89.6k
            case 55:
831
89.6k
              CRCtriplet(crc, next, -55);
832
89.6k
              FALLTHROUGH_INTENDED;
833
90.0k
            case 54:
834
90.0k
              CRCtriplet(crc, next, -54);
835
90.0k
              FALLTHROUGH_INTENDED;
836
90.4k
            case 53:
837
90.4k
              CRCtriplet(crc, next, -53);
838
90.4k
              FALLTHROUGH_INTENDED;
839
90.6k
            case 52:
840
90.6k
              CRCtriplet(crc, next, -52);
841
90.6k
              FALLTHROUGH_INTENDED;
842
90.8k
            case 51:
843
90.8k
              CRCtriplet(crc, next, -51);
844
90.8k
              FALLTHROUGH_INTENDED;
845
91.2k
            case 50:
846
91.2k
              CRCtriplet(crc, next, -50);
847
91.2k
              FALLTHROUGH_INTENDED;
848
91.4k
            case 49:
849
91.4k
              CRCtriplet(crc, next, -49);
850
91.4k
              FALLTHROUGH_INTENDED;
851
92.3k
            case 48:
852
92.3k
              CRCtriplet(crc, next, -48);
853
92.3k
              FALLTHROUGH_INTENDED;
854
93.0k
            case 47:
855
93.0k
              CRCtriplet(crc, next, -47);
856
93.0k
              FALLTHROUGH_INTENDED;
857
93.2k
            case 46:
858
93.2k
              CRCtriplet(crc, next, -46);
859
93.2k
              FALLTHROUGH_INTENDED;
860
93.5k
            case 45:
861
93.5k
              CRCtriplet(crc, next, -45);
862
93.5k
              FALLTHROUGH_INTENDED;
863
93.9k
            case 44:
864
93.9k
              CRCtriplet(crc, next, -44);
865
93.9k
              FALLTHROUGH_INTENDED;
866
94.3k
            case 43:
867
94.3k
              CRCtriplet(crc, next, -43);
868
94.3k
              FALLTHROUGH_INTENDED;
869
94.8k
            case 42:
870
94.8k
              CRCtriplet(crc, next, -42);
871
94.8k
              FALLTHROUGH_INTENDED;
872
95.5k
            case 41:
873
95.5k
              CRCtriplet(crc, next, -41);
874
95.5k
              FALLTHROUGH_INTENDED;
875
96.5k
            case 40:
876
96.5k
              CRCtriplet(crc, next, -40);
877
96.5k
              FALLTHROUGH_INTENDED;
878
96.7k
            case 39:
879
96.7k
              CRCtriplet(crc, next, -39);
880
96.7k
              FALLTHROUGH_INTENDED;
881
97.1k
            case 38:
882
97.1k
              CRCtriplet(crc, next, -38);
883
97.1k
              FALLTHROUGH_INTENDED;
884
97.6k
            case 37:
885
97.6k
              CRCtriplet(crc, next, -37);
886
97.6k
              FALLTHROUGH_INTENDED;
887
98.1k
            case 36:
888
98.1k
              CRCtriplet(crc, next, -36);
889
98.1k
              FALLTHROUGH_INTENDED;
890
99.0k
            case 35:
891
99.0k
              CRCtriplet(crc, next, -35);
892
99.0k
              FALLTHROUGH_INTENDED;
893
99.4k
            case 34:
894
99.4k
              CRCtriplet(crc, next, -34);
895
99.4k
              FALLTHROUGH_INTENDED;
896
100k
            case 33:
897
100k
              CRCtriplet(crc, next, -33);
898
100k
              FALLTHROUGH_INTENDED;
899
101k
            case 32:
900
101k
              CRCtriplet(crc, next, -32);
901
101k
              FALLTHROUGH_INTENDED;
902
101k
            case 31:
903
101k
              CRCtriplet(crc, next, -31);
904
101k
              FALLTHROUGH_INTENDED;
905
102k
            case 30:
906
102k
              CRCtriplet(crc, next, -30);
907
102k
              FALLTHROUGH_INTENDED;
908
105k
            case 29:
909
105k
              CRCtriplet(crc, next, -29);
910
105k
              FALLTHROUGH_INTENDED;
911
107k
            case 28:
912
107k
              CRCtriplet(crc, next, -28);
913
107k
              FALLTHROUGH_INTENDED;
914
108k
            case 27:
915
108k
              CRCtriplet(crc, next, -27);
916
108k
              FALLTHROUGH_INTENDED;
917
109k
            case 26:
918
109k
              CRCtriplet(crc, next, -26);
919
109k
              FALLTHROUGH_INTENDED;
920
109k
            case 25:
921
109k
              CRCtriplet(crc, next, -25);
922
109k
              FALLTHROUGH_INTENDED;
923
110k
            case 24:
924
110k
              CRCtriplet(crc, next, -24);
925
110k
              FALLTHROUGH_INTENDED;
926
112k
            case 23:
927
112k
              CRCtriplet(crc, next, -23);
928
112k
              FALLTHROUGH_INTENDED;
929
114k
            case 22:
930
114k
              CRCtriplet(crc, next, -22);
931
114k
              FALLTHROUGH_INTENDED;
932
115k
            case 21:
933
115k
              CRCtriplet(crc, next, -21);
934
115k
              FALLTHROUGH_INTENDED;
935
120k
            case 20:
936
120k
              CRCtriplet(crc, next, -20);
937
120k
              FALLTHROUGH_INTENDED;
938
122k
            case 19:
939
122k
              CRCtriplet(crc, next, -19);
940
122k
              FALLTHROUGH_INTENDED;
941
125k
            case 18:
942
125k
              CRCtriplet(crc, next, -18);
943
125k
              FALLTHROUGH_INTENDED;
944
128k
            case 17:
945
128k
              CRCtriplet(crc, next, -17);
946
128k
              FALLTHROUGH_INTENDED;
947
132k
            case 16:
948
132k
              CRCtriplet(crc, next, -16);
949
132k
              FALLTHROUGH_INTENDED;
950
138k
            case 15:
951
138k
              CRCtriplet(crc, next, -15);
952
138k
              FALLTHROUGH_INTENDED;
953
142k
            case 14:
954
142k
              CRCtriplet(crc, next, -14);
955
142k
              FALLTHROUGH_INTENDED;
956
146k
            case 13:
957
146k
              CRCtriplet(crc, next, -13);
958
146k
              FALLTHROUGH_INTENDED;
959
150k
            case 12:
960
150k
              CRCtriplet(crc, next, -12);
961
150k
              FALLTHROUGH_INTENDED;
962
181k
            case 11:
963
181k
              CRCtriplet(crc, next, -11);
964
181k
              FALLTHROUGH_INTENDED;
965
193k
            case 10:
966
193k
              CRCtriplet(crc, next, -10);
967
193k
              FALLTHROUGH_INTENDED;
968
227k
            case 9:
969
227k
              CRCtriplet(crc, next, -9);
970
227k
              FALLTHROUGH_INTENDED;
971
227k
            case 8:
972
227k
              CRCtriplet(crc, next, -8);
973
227k
              FALLTHROUGH_INTENDED;
974
228k
            case 7:
975
228k
              CRCtriplet(crc, next, -7);
976
228k
              FALLTHROUGH_INTENDED;
977
228k
            case 6:
978
228k
              CRCtriplet(crc, next, -6);
979
228k
              FALLTHROUGH_INTENDED;
980
228k
            case 5:
981
228k
              CRCtriplet(crc, next, -5);
982
228k
              FALLTHROUGH_INTENDED;
983
228k
            case 4:
984
228k
              CRCtriplet(crc, next, -4);
985
228k
              FALLTHROUGH_INTENDED;
986
228k
            case 3:
987
228k
              CRCtriplet(crc, next, -3);
988
228k
              FALLTHROUGH_INTENDED;
989
229k
            case 2:
990
229k
              CRCtriplet(crc, next, -2);
991
229k
              FALLTHROUGH_INTENDED;
992
229k
            case 1:
993
229k
              CRCduplet(crc, next, -1); // the final triplet is actually only 2
994
              //{ CombineCRC(); }
995
229k
              crc0 = CombineCRC(block_size, crc0, crc1, crc2, next2);
996
229k
              if (--n > 0) {
997
64.0k
                crc1 = crc2 = 0;
998
64.0k
                block_size = 128;
999
                // points to the first byte of the next block
1000
64.0k
                next0 = next2 + 128;
1001
64.0k
                next1 = next0 + 128; // from here on all blocks are 128 long
1002
64.0k
                next2 = next1 + 128;
1003
64.0k
              }
1004
229k
              FALLTHROUGH_INTENDED;
1005
229k
            case 0:;
1006
229k
          } while (n > 0);
1007
165k
      }
1008
165k
      next = (const unsigned char*)next2;
1009
165k
    }
1010
1.49M
    uint64_t count2 = len >> 3; // 216 of less bytes is 27 or less singlets
1011
1.49M
    len = len & 7;
1012
1.49M
    next += (count2 * 8);
1013
1.49M
    switch (count2) {
1014
2.06k
      case 27:
1015
2.06k
        CRCsinglet(crc0, next, -27 * 8);
1016
2.06k
        FALLTHROUGH_INTENDED;
1017
15.4k
      case 26:
1018
15.4k
        CRCsinglet(crc0, next, -26 * 8);
1019
15.4k
        FALLTHROUGH_INTENDED;
1020
24.4k
      case 25:
1021
24.4k
        CRCsinglet(crc0, next, -25 * 8);
1022
24.4k
        FALLTHROUGH_INTENDED;
1023
31.0k
      case 24:
1024
31.0k
        CRCsinglet(crc0, next, -24 * 8);
1025
31.0k
        FALLTHROUGH_INTENDED;
1026
35.3k
      case 23:
1027
35.3k
        CRCsinglet(crc0, next, -23 * 8);
1028
35.3k
        FALLTHROUGH_INTENDED;
1029
40.6k
      case 22:
1030
40.6k
        CRCsinglet(crc0, next, -22 * 8);
1031
40.6k
        FALLTHROUGH_INTENDED;
1032
46.1k
      case 21:
1033
46.1k
        CRCsinglet(crc0, next, -21 * 8);
1034
46.1k
        FALLTHROUGH_INTENDED;
1035
51.0k
      case 20:
1036
51.0k
        CRCsinglet(crc0, next, -20 * 8);
1037
51.0k
        FALLTHROUGH_INTENDED;
1038
56.9k
      case 19:
1039
56.9k
        CRCsinglet(crc0, next, -19 * 8);
1040
56.9k
        FALLTHROUGH_INTENDED;
1041
63.1k
      case 18:
1042
63.1k
        CRCsinglet(crc0, next, -18 * 8);
1043
63.1k
        FALLTHROUGH_INTENDED;
1044
72.4k
      case 17:
1045
72.4k
        CRCsinglet(crc0, next, -17 * 8);
1046
72.4k
        FALLTHROUGH_INTENDED;
1047
79.2k
      case 16:
1048
79.2k
        CRCsinglet(crc0, next, -16 * 8);
1049
79.2k
        FALLTHROUGH_INTENDED;
1050
85.5k
      case 15:
1051
85.5k
        CRCsinglet(crc0, next, -15 * 8);
1052
85.5k
        FALLTHROUGH_INTENDED;
1053
94.4k
      case 14:
1054
94.4k
        CRCsinglet(crc0, next, -14 * 8);
1055
94.4k
        FALLTHROUGH_INTENDED;
1056
102k
      case 13:
1057
102k
        CRCsinglet(crc0, next, -13 * 8);
1058
102k
        FALLTHROUGH_INTENDED;
1059
112k
      case 12:
1060
112k
        CRCsinglet(crc0, next, -12 * 8);
1061
112k
        FALLTHROUGH_INTENDED;
1062
123k
      case 11:
1063
123k
        CRCsinglet(crc0, next, -11 * 8);
1064
123k
        FALLTHROUGH_INTENDED;
1065
144k
      case 10:
1066
144k
        CRCsinglet(crc0, next, -10 * 8);
1067
144k
        FALLTHROUGH_INTENDED;
1068
176k
      case 9:
1069
176k
        CRCsinglet(crc0, next, -9 * 8);
1070
176k
        FALLTHROUGH_INTENDED;
1071
197k
      case 8:
1072
197k
        CRCsinglet(crc0, next, -8 * 8);
1073
197k
        FALLTHROUGH_INTENDED;
1074
214k
      case 7:
1075
214k
        CRCsinglet(crc0, next, -7 * 8);
1076
214k
        FALLTHROUGH_INTENDED;
1077
276k
      case 6:
1078
276k
        CRCsinglet(crc0, next, -6 * 8);
1079
276k
        FALLTHROUGH_INTENDED;
1080
402k
      case 5:
1081
402k
        CRCsinglet(crc0, next, -5 * 8);
1082
402k
        FALLTHROUGH_INTENDED;
1083
542k
      case 4:
1084
542k
        CRCsinglet(crc0, next, -4 * 8);
1085
542k
        FALLTHROUGH_INTENDED;
1086
588k
      case 3:
1087
588k
        CRCsinglet(crc0, next, -3 * 8);
1088
588k
        FALLTHROUGH_INTENDED;
1089
1.02M
      case 2:
1090
1.02M
        CRCsinglet(crc0, next, -2 * 8);
1091
1.02M
        FALLTHROUGH_INTENDED;
1092
1.43M
      case 1:
1093
1.43M
        CRCsinglet(crc0, next, -1 * 8);
1094
1.43M
        FALLTHROUGH_INTENDED;
1095
1.49M
      case 0:;
1096
1.49M
    }
1097
1.49M
  }
1098
14.0M
  {
1099
14.0M
    align_to_8(len, crc0, next);
1100
14.0M
    return (uint32_t)crc0 ^ 0xffffffffu;
1101
14.0M
  }
1102
14.0M
}
1103
1104
#endif //__SSE4_2__ && __PCLMUL__
1105
1106
4
static inline Function Choose_Extend() {
1107
#ifdef HAVE_POWER8
1108
  return isAltiVec() ? ExtendPPCImpl : ExtendImpl<DefaultCRC32>;
1109
#elif defined(HAVE_ARM64_CRC)
1110
  if(crc32c_runtime_check()) {
1111
    pmull_runtime_flag = crc32c_pmull_runtime_check();
1112
    return ExtendARMImpl;
1113
  } else {
1114
    return ExtendImpl<DefaultCRC32>;
1115
  }
1116
#elif defined(__SSE4_2__) && defined(__PCLMUL__) && !defined NO_THREEWAY_CRC32C
1117
  // NOTE: runtime detection no longer supported on x86
1118
#ifdef _MSC_VER
1119
#pragma warning(disable: 4551)
1120
#endif
1121
4
  (void)ExtendImpl<DefaultCRC32>; // suppress unused warning
1122
#ifdef _MSC_VER
1123
#pragma warning(default: 4551)
1124
#endif
1125
4
  return crc32c_3way;
1126
#else
1127
  return ExtendImpl<DefaultCRC32>;
1128
#endif
1129
4
}
1130
1131
static Function ChosenExtend = Choose_Extend();
1132
14.0M
uint32_t Extend(uint32_t crc, const char* buf, size_t size) {
1133
14.0M
  return ChosenExtend(crc, buf, size);
1134
14.0M
}
1135
1136
// The code for crc32c combine, copied with permission from folly
1137
1138
// Standard galois-field multiply.  The only modification is that a,
1139
// b, m, and p are all bit-reflected.
1140
//
1141
// https://en.wikipedia.org/wiki/Finite_field_arithmetic
1142
static constexpr uint32_t gf_multiply_sw_1(
1143
57.2M
    size_t i, uint32_t p, uint32_t a, uint32_t b, uint32_t m) {
1144
  // clang-format off
1145
57.2M
  return i == 32 ? p : gf_multiply_sw_1(
1146
55.5M
      /* i = */ i + 1,
1147
55.5M
      /* p = */ p ^ ((0u-((b >> 31) & 1)) & a),
1148
55.5M
      /* a = */ (a >> 1) ^ ((0u-(a & 1)) & m),
1149
55.5M
      /* b = */ b << 1,
1150
55.5M
      /* m = */ m);
1151
  // clang-format on
1152
57.2M
}
1153
1.73M
static constexpr uint32_t gf_multiply_sw(uint32_t a, uint32_t b, uint32_t m) {
1154
1.73M
  return gf_multiply_sw_1(/* i = */ 0, /* p = */ 0, a, b, m);
1155
1.73M
}
1156
1157
0
static constexpr uint32_t gf_square_sw(uint32_t a, uint32_t m) {
1158
0
  return gf_multiply_sw(a, a, m);
1159
0
}
1160
1161
template <size_t i, uint32_t m>
1162
struct gf_powers_memo {
1163
  static constexpr uint32_t value =
1164
      gf_square_sw(gf_powers_memo<i - 1, m>::value, m);
1165
};
1166
template <uint32_t m>
1167
struct gf_powers_memo<0, m> {
1168
  static constexpr uint32_t value = m;
1169
};
1170
1171
template <typename T, T... Ints>
1172
struct integer_sequence {
1173
  using value_type = T;
1174
  static constexpr size_t size() { return sizeof...(Ints); }
1175
};
1176
1177
template <typename T, std::size_t N, T... Is>
1178
struct make_integer_sequence : make_integer_sequence<T, N - 1, N - 1, Is...> {};
1179
1180
template <typename T, T... Is>
1181
struct make_integer_sequence<T, 0, Is...> : integer_sequence<T, Is...> {};
1182
1183
template <std::size_t N>
1184
using make_index_sequence = make_integer_sequence<std::size_t, N>;
1185
1186
template <uint32_t m>
1187
struct gf_powers_make {
1188
  template <size_t... i>
1189
  using index_sequence = integer_sequence<size_t, i...>;
1190
  template <size_t... i>
1191
  constexpr std::array<uint32_t, sizeof...(i)> operator()(
1192
0
      index_sequence<i...>) const {
1193
0
    return std::array<uint32_t, sizeof...(i)>{{gf_powers_memo<i, m>::value...}};
1194
0
  }
1195
};
1196
1197
static constexpr uint32_t crc32c_m = 0x82f63b78;
1198
1199
static constexpr std::array<uint32_t, 62> const crc32c_powers =
1200
    gf_powers_make<crc32c_m>{}(make_index_sequence<62>{});
1201
1202
// Expects a "pure" crc (see Crc32cCombine)
1203
static uint32_t Crc32AppendZeroes(
1204
    uint32_t crc, size_t len_over_4, uint32_t polynomial,
1205
888k
    std::array<uint32_t, 62> const& powers_array) {
1206
888k
  auto powers = powers_array.data();
1207
  // Append by multiplying by consecutive powers of two of the zeroes
1208
  // array
1209
888k
  size_t len_bits = len_over_4;
1210
1211
2.62M
  while (len_bits) {
1212
    // Advance directly to next bit set.
1213
1.73M
    auto r = CountTrailingZeroBits(len_bits);
1214
1.73M
    len_bits >>= r;
1215
1.73M
    powers += r;
1216
1217
1.73M
    crc = gf_multiply_sw(crc, *powers, polynomial);
1218
1219
1.73M
    len_bits >>= 1;
1220
1.73M
    powers++;
1221
1.73M
  }
1222
1223
888k
  return crc;
1224
888k
}
1225
1226
2.32M
static inline uint32_t InvertedToPure(uint32_t crc) { return ~crc; }
1227
1228
1.43M
static inline uint32_t PureToInverted(uint32_t crc) { return ~crc; }
1229
1230
548k
static inline uint32_t PureExtend(uint32_t crc, const char* buf, size_t size) {
1231
548k
  return InvertedToPure(Extend(PureToInverted(crc), buf, size));
1232
548k
}
1233
1234
// Background:
1235
// RocksDB uses two kinds of crc32c values: masked and unmasked. Neither is
1236
// a "pure" CRC because a pure CRC satisfies (^ for xor)
1237
//  crc(a ^ b) = crc(a) ^ crc(b)
1238
// The unmasked is closest, and this function takes unmasked crc32c values.
1239
// The unmasked values are impure in two ways:
1240
// * The initial setting at the start of CRC computation is all 1 bits
1241
// (like -1) instead of zero.
1242
// * The result has all bits invered.
1243
// Note that together, these result in the empty string having a crc32c of
1244
// zero. See
1245
// https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks#CRC_variants
1246
//
1247
// Simplified version of strategy, using xor through pure CRCs (+ for concat):
1248
//
1249
// pure_crc(str1 + str2) = pure_crc(str1 + zeros(len(str2))) ^
1250
//                         pure_crc(zeros(len(str1)) + str2)
1251
//
1252
// because the xor of these two zero-padded strings is str1 + str2. For pure
1253
// CRC, leading zeros don't affect the result, so we only need
1254
//
1255
// pure_crc(str1 + str2) = pure_crc(str1 + zeros(len(str2))) ^
1256
//                         pure_crc(str2)
1257
//
1258
// Considering we aren't working with pure CRCs, what is actually in the input?
1259
//
1260
// crc1 = PureToInverted(PureExtendCrc32c(-1, zeros, crc1len) ^
1261
//                       PureCrc32c(str1, crc1len))
1262
// crc2 = PureToInverted(PureExtendCrc32c(-1, zeros, crc2len) ^
1263
//                       PureCrc32c(str2, crc2len))
1264
//
1265
// The result we want to compute is
1266
// combined = PureToInverted(PureExtendCrc32c(PureExtendCrc32c(-1, zeros,
1267
//                                                             crc1len) ^
1268
//                                            PureCrc32c(str1, crc1len),
1269
//                                            zeros, crc2len) ^
1270
//                           PureCrc32c(str2, crc2len))
1271
//
1272
// Thus, in addition to extending crc1 over the length of str2 in (virtual)
1273
// zeros, we need to cancel out the -1 initializer that was used in computing
1274
// crc2. To cancel it out, we also need to extend it over crc2len in zeros.
1275
// To simplify, since the end of str1 and that -1 initializer for crc2 are at
1276
// the same logical position, we can combine them before we extend over the
1277
// zeros.
1278
888k
uint32_t Crc32cCombine(uint32_t crc1, uint32_t crc2, size_t crc2len) {
1279
888k
  uint32_t pure_crc1_with_init = InvertedToPure(crc1);
1280
888k
  uint32_t pure_crc2_with_init = InvertedToPure(crc2);
1281
888k
  uint32_t pure_crc2_init = static_cast<uint32_t>(-1);
1282
1283
  // Append up to 32 bits of zeroes in the normal way
1284
888k
  char zeros[4] = {0, 0, 0, 0};
1285
888k
  auto len = crc2len & 3;
1286
888k
  uint32_t tmp = pure_crc1_with_init ^ pure_crc2_init;
1287
888k
  if (len) {
1288
548k
    tmp = PureExtend(tmp, zeros, len);
1289
548k
  }
1290
888k
  return PureToInverted(
1291
888k
      Crc32AppendZeroes(tmp, crc2len / 4, crc32c_m, crc32c_powers) ^
1292
888k
      pure_crc2_with_init);
1293
888k
}
1294
1295
}  // namespace ROCKSDB_NAMESPACE::crc32c