Coverage Report

Created: 2026-04-10 07:52

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
42.2k
std::string IsFastCrc32Supported() {
363
42.2k
  bool has_fast_crc = false;
364
42.2k
  std::string fast_zero_msg;
365
42.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
42.2k
#ifdef __SSE4_2__
387
42.2k
  has_fast_crc = true;
388
42.2k
#endif  // __SSE4_2__
389
42.2k
  arch = "x86";
390
42.2k
#endif
391
42.2k
  if (has_fast_crc) {
392
42.2k
    fast_zero_msg.append("Supported on " + arch);
393
42.2k
  } else {
394
0
    fast_zero_msg.append("Not supported on " + arch);
395
0
  }
396
42.2k
  return fast_zero_msg;
397
42.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
231k
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
438
231k
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset));
439
440
#define CRCsinglet(crc, buf, offset) \
441
6.14M
  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.8M
    const unsigned char*& next) { // next data pointer, updated on return
524
14.8M
  uint32_t crc32bit = static_cast<uint32_t>(crc0);
525
14.8M
  if (len & 0x04) {
526
843k
    crc32bit = _mm_crc32_u32(crc32bit, *(uint32_t*)next);
527
843k
    next += sizeof(uint32_t);
528
843k
  }
529
14.8M
  if (len & 0x02) {
530
1.19M
    crc32bit = _mm_crc32_u16(crc32bit, *(uint16_t*)next);
531
1.19M
    next += sizeof(uint16_t);
532
1.19M
  }
533
14.8M
  if (len & 0x01) {
534
13.6M
    crc32bit = _mm_crc32_u8(crc32bit, *(next));
535
13.6M
    next++;
536
13.6M
  }
537
14.8M
  crc0 = crc32bit;
538
14.8M
}
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
231k
    const uint64_t* next2) {
550
231k
  const auto multiplier =
551
231k
      *(reinterpret_cast<const __m128i*>(clmul_constants) + block_size - 1);
552
231k
  const auto crc0_xmm = _mm_set_epi64x(0, crc0);
553
231k
  const auto res0 = _mm_clmulepi64_si128(crc0_xmm, multiplier, 0x00);
554
231k
  const auto crc1_xmm = _mm_set_epi64x(0, crc1);
555
231k
  const auto res1 = _mm_clmulepi64_si128(crc1_xmm, multiplier, 0x10);
556
231k
  const auto res = _mm_xor_si128(res0, res1);
557
231k
  crc0 = _mm_cvtsi128_si64(res);
558
231k
  crc0 = crc0 ^ *((uint64_t*)next2 - 1);
559
231k
  crc2 = _mm_crc32_u64(crc2, crc0);
560
231k
  return crc2;
561
231k
}
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.6M
uint32_t crc32c_3way(uint32_t crc, const char* buf, size_t len) {
572
14.6M
  const unsigned char* next = (const unsigned char*)buf;
573
14.6M
  uint64_t count;
574
14.6M
  uint64_t crc0, crc1, crc2;
575
14.6M
  crc0 = crc ^ 0xffffffffu;
576
577
578
14.6M
  if (len >= 8) {
579
    // if len > 216 then align and use triplets
580
1.52M
    if (len > 216) {
581
167k
      {
582
        // Work on the bytes (< 8) before the first 8-byte alignment addr starts
583
167k
        uint64_t align_bytes = (8 - (uintptr_t)next) & 7;
584
167k
        len -= align_bytes;
585
167k
        align_to_8(align_bytes, crc0, next);
586
167k
      }
587
588
      // Now work on the remaining blocks
589
167k
      count = len / 24; // number of triplets
590
167k
      len %= 24; // bytes remaining
591
167k
      uint64_t n = count >> 7; // #blocks = first block + full blocks
592
167k
      uint64_t block_size = count & 127;
593
167k
      if (block_size == 0) {
594
144
        block_size = 128;
595
167k
      } else {
596
167k
        n++;
597
167k
      }
598
      // points to the first byte of the next block
599
167k
      const uint64_t* next0 = (uint64_t*)next + block_size;
600
167k
      const uint64_t* next1 = next0 + block_size;
601
167k
      const uint64_t* next2 = next1 + block_size;
602
603
167k
      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
167k
      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.4k
            case 126:
618
64.4k
              CRCtriplet(crc, next, -126); // than 128
619
64.4k
              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
65.0k
            case 121:
633
65.0k
              CRCtriplet(crc, next, -121);
634
65.0k
              FALLTHROUGH_INTENDED;
635
65.1k
            case 120:
636
65.1k
              CRCtriplet(crc, next, -120);
637
65.1k
              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.9k
            case 115:
651
65.9k
              CRCtriplet(crc, next, -115);
652
65.9k
              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.1k
            case 109:
669
67.1k
              CRCtriplet(crc, next, -109);
670
67.1k
              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.8k
            case 106:
678
67.8k
              CRCtriplet(crc, next, -106);
679
67.8k
              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.2k
            case 97:
705
69.2k
              CRCtriplet(crc, next, -97);
706
69.2k
              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.9k
            case 89:
729
72.9k
              CRCtriplet(crc, next, -89);
730
72.9k
              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.7k
            case 84:
744
76.7k
              CRCtriplet(crc, next, -84);
745
76.7k
              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.7k
            case 78:
762
78.7k
              CRCtriplet(crc, next, -78);
763
78.7k
              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.4k
            case 75:
771
79.4k
              CRCtriplet(crc, next, -75);
772
79.4k
              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.9k
            case 70:
786
80.9k
              CRCtriplet(crc, next, -70);
787
80.9k
              FALLTHROUGH_INTENDED;
788
81.3k
            case 69:
789
81.3k
              CRCtriplet(crc, next, -69);
790
81.3k
              FALLTHROUGH_INTENDED;
791
82.9k
            case 68:
792
82.9k
              CRCtriplet(crc, next, -68);
793
82.9k
              FALLTHROUGH_INTENDED;
794
83.1k
            case 67:
795
83.1k
              CRCtriplet(crc, next, -67);
796
83.1k
              FALLTHROUGH_INTENDED;
797
83.5k
            case 66:
798
83.5k
              CRCtriplet(crc, next, -66);
799
83.5k
              FALLTHROUGH_INTENDED;
800
83.7k
            case 65:
801
83.7k
              CRCtriplet(crc, next, -65);
802
83.7k
              FALLTHROUGH_INTENDED;
803
84.1k
            case 64:
804
84.1k
              CRCtriplet(crc, next, -64);
805
84.1k
              FALLTHROUGH_INTENDED;
806
84.3k
            case 63:
807
84.3k
              CRCtriplet(crc, next, -63);
808
84.3k
              FALLTHROUGH_INTENDED;
809
84.9k
            case 62:
810
84.9k
              CRCtriplet(crc, next, -62);
811
84.9k
              FALLTHROUGH_INTENDED;
812
85.7k
            case 61:
813
85.7k
              CRCtriplet(crc, next, -61);
814
85.7k
              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.1k
            case 58:
822
87.1k
              CRCtriplet(crc, next, -58);
823
87.1k
              FALLTHROUGH_INTENDED;
824
88.9k
            case 57:
825
88.9k
              CRCtriplet(crc, next, -57);
826
88.9k
              FALLTHROUGH_INTENDED;
827
89.3k
            case 56:
828
89.3k
              CRCtriplet(crc, next, -56);
829
89.3k
              FALLTHROUGH_INTENDED;
830
89.7k
            case 55:
831
89.7k
              CRCtriplet(crc, next, -55);
832
89.7k
              FALLTHROUGH_INTENDED;
833
90.1k
            case 54:
834
90.1k
              CRCtriplet(crc, next, -54);
835
90.1k
              FALLTHROUGH_INTENDED;
836
90.5k
            case 53:
837
90.5k
              CRCtriplet(crc, next, -53);
838
90.5k
              FALLTHROUGH_INTENDED;
839
90.7k
            case 52:
840
90.7k
              CRCtriplet(crc, next, -52);
841
90.7k
              FALLTHROUGH_INTENDED;
842
90.9k
            case 51:
843
90.9k
              CRCtriplet(crc, next, -51);
844
90.9k
              FALLTHROUGH_INTENDED;
845
91.3k
            case 50:
846
91.3k
              CRCtriplet(crc, next, -50);
847
91.3k
              FALLTHROUGH_INTENDED;
848
91.5k
            case 49:
849
91.5k
              CRCtriplet(crc, next, -49);
850
91.5k
              FALLTHROUGH_INTENDED;
851
92.4k
            case 48:
852
92.4k
              CRCtriplet(crc, next, -48);
853
92.4k
              FALLTHROUGH_INTENDED;
854
93.1k
            case 47:
855
93.1k
              CRCtriplet(crc, next, -47);
856
93.1k
              FALLTHROUGH_INTENDED;
857
93.4k
            case 46:
858
93.4k
              CRCtriplet(crc, next, -46);
859
93.4k
              FALLTHROUGH_INTENDED;
860
93.6k
            case 45:
861
93.6k
              CRCtriplet(crc, next, -45);
862
93.6k
              FALLTHROUGH_INTENDED;
863
94.1k
            case 44:
864
94.1k
              CRCtriplet(crc, next, -44);
865
94.1k
              FALLTHROUGH_INTENDED;
866
94.4k
            case 43:
867
94.4k
              CRCtriplet(crc, next, -43);
868
94.4k
              FALLTHROUGH_INTENDED;
869
94.9k
            case 42:
870
94.9k
              CRCtriplet(crc, next, -42);
871
94.9k
              FALLTHROUGH_INTENDED;
872
95.7k
            case 41:
873
95.7k
              CRCtriplet(crc, next, -41);
874
95.7k
              FALLTHROUGH_INTENDED;
875
96.6k
            case 40:
876
96.6k
              CRCtriplet(crc, next, -40);
877
96.6k
              FALLTHROUGH_INTENDED;
878
96.9k
            case 39:
879
96.9k
              CRCtriplet(crc, next, -39);
880
96.9k
              FALLTHROUGH_INTENDED;
881
97.3k
            case 38:
882
97.3k
              CRCtriplet(crc, next, -38);
883
97.3k
              FALLTHROUGH_INTENDED;
884
97.8k
            case 37:
885
97.8k
              CRCtriplet(crc, next, -37);
886
97.8k
              FALLTHROUGH_INTENDED;
887
98.3k
            case 36:
888
98.3k
              CRCtriplet(crc, next, -36);
889
98.3k
              FALLTHROUGH_INTENDED;
890
99.1k
            case 35:
891
99.1k
              CRCtriplet(crc, next, -35);
892
99.1k
              FALLTHROUGH_INTENDED;
893
99.6k
            case 34:
894
99.6k
              CRCtriplet(crc, next, -34);
895
99.6k
              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
103k
            case 30:
906
103k
              CRCtriplet(crc, next, -30);
907
103k
              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
110k
            case 25:
921
110k
              CRCtriplet(crc, next, -25);
922
110k
              FALLTHROUGH_INTENDED;
923
111k
            case 24:
924
111k
              CRCtriplet(crc, next, -24);
925
111k
              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
116k
            case 21:
933
116k
              CRCtriplet(crc, next, -21);
934
116k
              FALLTHROUGH_INTENDED;
935
120k
            case 20:
936
120k
              CRCtriplet(crc, next, -20);
937
120k
              FALLTHROUGH_INTENDED;
938
123k
            case 19:
939
123k
              CRCtriplet(crc, next, -19);
940
123k
              FALLTHROUGH_INTENDED;
941
125k
            case 18:
942
125k
              CRCtriplet(crc, next, -18);
943
125k
              FALLTHROUGH_INTENDED;
944
129k
            case 17:
945
129k
              CRCtriplet(crc, next, -17);
946
129k
              FALLTHROUGH_INTENDED;
947
133k
            case 16:
948
133k
              CRCtriplet(crc, next, -16);
949
133k
              FALLTHROUGH_INTENDED;
950
139k
            case 15:
951
139k
              CRCtriplet(crc, next, -15);
952
139k
              FALLTHROUGH_INTENDED;
953
143k
            case 14:
954
143k
              CRCtriplet(crc, next, -14);
955
143k
              FALLTHROUGH_INTENDED;
956
147k
            case 13:
957
147k
              CRCtriplet(crc, next, -13);
958
147k
              FALLTHROUGH_INTENDED;
959
151k
            case 12:
960
151k
              CRCtriplet(crc, next, -12);
961
151k
              FALLTHROUGH_INTENDED;
962
183k
            case 11:
963
183k
              CRCtriplet(crc, next, -11);
964
183k
              FALLTHROUGH_INTENDED;
965
196k
            case 10:
966
196k
              CRCtriplet(crc, next, -10);
967
196k
              FALLTHROUGH_INTENDED;
968
229k
            case 9:
969
229k
              CRCtriplet(crc, next, -9);
970
229k
              FALLTHROUGH_INTENDED;
971
230k
            case 8:
972
230k
              CRCtriplet(crc, next, -8);
973
230k
              FALLTHROUGH_INTENDED;
974
230k
            case 7:
975
230k
              CRCtriplet(crc, next, -7);
976
230k
              FALLTHROUGH_INTENDED;
977
230k
            case 6:
978
230k
              CRCtriplet(crc, next, -6);
979
230k
              FALLTHROUGH_INTENDED;
980
230k
            case 5:
981
230k
              CRCtriplet(crc, next, -5);
982
230k
              FALLTHROUGH_INTENDED;
983
231k
            case 4:
984
231k
              CRCtriplet(crc, next, -4);
985
231k
              FALLTHROUGH_INTENDED;
986
231k
            case 3:
987
231k
              CRCtriplet(crc, next, -3);
988
231k
              FALLTHROUGH_INTENDED;
989
231k
            case 2:
990
231k
              CRCtriplet(crc, next, -2);
991
231k
              FALLTHROUGH_INTENDED;
992
231k
            case 1:
993
231k
              CRCduplet(crc, next, -1); // the final triplet is actually only 2
994
              //{ CombineCRC(); }
995
231k
              crc0 = CombineCRC(block_size, crc0, crc1, crc2, next2);
996
231k
              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
231k
              FALLTHROUGH_INTENDED;
1005
231k
            case 0:;
1006
231k
          } while (n > 0);
1007
167k
      }
1008
167k
      next = (const unsigned char*)next2;
1009
167k
    }
1010
1.52M
    uint64_t count2 = len >> 3; // 216 of less bytes is 27 or less singlets
1011
1.52M
    len = len & 7;
1012
1.52M
    next += (count2 * 8);
1013
1.52M
    switch (count2) {
1014
2.10k
      case 27:
1015
2.10k
        CRCsinglet(crc0, next, -27 * 8);
1016
2.10k
        FALLTHROUGH_INTENDED;
1017
15.5k
      case 26:
1018
15.5k
        CRCsinglet(crc0, next, -26 * 8);
1019
15.5k
        FALLTHROUGH_INTENDED;
1020
25.0k
      case 25:
1021
25.0k
        CRCsinglet(crc0, next, -25 * 8);
1022
25.0k
        FALLTHROUGH_INTENDED;
1023
31.7k
      case 24:
1024
31.7k
        CRCsinglet(crc0, next, -24 * 8);
1025
31.7k
        FALLTHROUGH_INTENDED;
1026
36.1k
      case 23:
1027
36.1k
        CRCsinglet(crc0, next, -23 * 8);
1028
36.1k
        FALLTHROUGH_INTENDED;
1029
41.4k
      case 22:
1030
41.4k
        CRCsinglet(crc0, next, -22 * 8);
1031
41.4k
        FALLTHROUGH_INTENDED;
1032
46.8k
      case 21:
1033
46.8k
        CRCsinglet(crc0, next, -21 * 8);
1034
46.8k
        FALLTHROUGH_INTENDED;
1035
51.8k
      case 20:
1036
51.8k
        CRCsinglet(crc0, next, -20 * 8);
1037
51.8k
        FALLTHROUGH_INTENDED;
1038
57.8k
      case 19:
1039
57.8k
        CRCsinglet(crc0, next, -19 * 8);
1040
57.8k
        FALLTHROUGH_INTENDED;
1041
63.9k
      case 18:
1042
63.9k
        CRCsinglet(crc0, next, -18 * 8);
1043
63.9k
        FALLTHROUGH_INTENDED;
1044
73.4k
      case 17:
1045
73.4k
        CRCsinglet(crc0, next, -17 * 8);
1046
73.4k
        FALLTHROUGH_INTENDED;
1047
80.3k
      case 16:
1048
80.3k
        CRCsinglet(crc0, next, -16 * 8);
1049
80.3k
        FALLTHROUGH_INTENDED;
1050
86.6k
      case 15:
1051
86.6k
        CRCsinglet(crc0, next, -15 * 8);
1052
86.6k
        FALLTHROUGH_INTENDED;
1053
95.5k
      case 14:
1054
95.5k
        CRCsinglet(crc0, next, -14 * 8);
1055
95.5k
        FALLTHROUGH_INTENDED;
1056
104k
      case 13:
1057
104k
        CRCsinglet(crc0, next, -13 * 8);
1058
104k
        FALLTHROUGH_INTENDED;
1059
113k
      case 12:
1060
113k
        CRCsinglet(crc0, next, -12 * 8);
1061
113k
        FALLTHROUGH_INTENDED;
1062
125k
      case 11:
1063
125k
        CRCsinglet(crc0, next, -11 * 8);
1064
125k
        FALLTHROUGH_INTENDED;
1065
146k
      case 10:
1066
146k
        CRCsinglet(crc0, next, -10 * 8);
1067
146k
        FALLTHROUGH_INTENDED;
1068
178k
      case 9:
1069
178k
        CRCsinglet(crc0, next, -9 * 8);
1070
178k
        FALLTHROUGH_INTENDED;
1071
199k
      case 8:
1072
199k
        CRCsinglet(crc0, next, -8 * 8);
1073
199k
        FALLTHROUGH_INTENDED;
1074
217k
      case 7:
1075
217k
        CRCsinglet(crc0, next, -7 * 8);
1076
217k
        FALLTHROUGH_INTENDED;
1077
280k
      case 6:
1078
280k
        CRCsinglet(crc0, next, -6 * 8);
1079
280k
        FALLTHROUGH_INTENDED;
1080
409k
      case 5:
1081
409k
        CRCsinglet(crc0, next, -5 * 8);
1082
409k
        FALLTHROUGH_INTENDED;
1083
555k
      case 4:
1084
555k
        CRCsinglet(crc0, next, -4 * 8);
1085
555k
        FALLTHROUGH_INTENDED;
1086
601k
      case 3:
1087
601k
        CRCsinglet(crc0, next, -3 * 8);
1088
601k
        FALLTHROUGH_INTENDED;
1089
1.03M
      case 2:
1090
1.03M
        CRCsinglet(crc0, next, -2 * 8);
1091
1.03M
        FALLTHROUGH_INTENDED;
1092
1.46M
      case 1:
1093
1.46M
        CRCsinglet(crc0, next, -1 * 8);
1094
1.46M
        FALLTHROUGH_INTENDED;
1095
1.52M
      case 0:;
1096
1.52M
    }
1097
1.52M
  }
1098
14.6M
  {
1099
14.6M
    align_to_8(len, crc0, next);
1100
14.6M
    return (uint32_t)crc0 ^ 0xffffffffu;
1101
14.6M
  }
1102
14.6M
}
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.6M
uint32_t Extend(uint32_t crc, const char* buf, size_t size) {
1133
14.6M
  return ChosenExtend(crc, buf, size);
1134
14.6M
}
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
58.3M
    size_t i, uint32_t p, uint32_t a, uint32_t b, uint32_t m) {
1144
  // clang-format off
1145
58.3M
  return i == 32 ? p : gf_multiply_sw_1(
1146
56.6M
      /* i = */ i + 1,
1147
56.6M
      /* p = */ p ^ ((0u-((b >> 31) & 1)) & a),
1148
56.6M
      /* a = */ (a >> 1) ^ ((0u-(a & 1)) & m),
1149
56.6M
      /* b = */ b << 1,
1150
56.6M
      /* m = */ m);
1151
  // clang-format on
1152
58.3M
}
1153
1.76M
static constexpr uint32_t gf_multiply_sw(uint32_t a, uint32_t b, uint32_t m) {
1154
1.76M
  return gf_multiply_sw_1(/* i = */ 0, /* p = */ 0, a, b, m);
1155
1.76M
}
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
909k
    std::array<uint32_t, 62> const& powers_array) {
1206
909k
  auto powers = powers_array.data();
1207
  // Append by multiplying by consecutive powers of two of the zeroes
1208
  // array
1209
909k
  size_t len_bits = len_over_4;
1210
1211
2.67M
  while (len_bits) {
1212
    // Advance directly to next bit set.
1213
1.76M
    auto r = CountTrailingZeroBits(len_bits);
1214
1.76M
    len_bits >>= r;
1215
1.76M
    powers += r;
1216
1217
1.76M
    crc = gf_multiply_sw(crc, *powers, polynomial);
1218
1219
1.76M
    len_bits >>= 1;
1220
1.76M
    powers++;
1221
1.76M
  }
1222
1223
909k
  return crc;
1224
909k
}
1225
1226
2.37M
static inline uint32_t InvertedToPure(uint32_t crc) { return ~crc; }
1227
1228
1.47M
static inline uint32_t PureToInverted(uint32_t crc) { return ~crc; }
1229
1230
560k
static inline uint32_t PureExtend(uint32_t crc, const char* buf, size_t size) {
1231
560k
  return InvertedToPure(Extend(PureToInverted(crc), buf, size));
1232
560k
}
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
909k
uint32_t Crc32cCombine(uint32_t crc1, uint32_t crc2, size_t crc2len) {
1279
909k
  uint32_t pure_crc1_with_init = InvertedToPure(crc1);
1280
909k
  uint32_t pure_crc2_with_init = InvertedToPure(crc2);
1281
909k
  uint32_t pure_crc2_init = static_cast<uint32_t>(-1);
1282
1283
  // Append up to 32 bits of zeroes in the normal way
1284
909k
  char zeros[4] = {0, 0, 0, 0};
1285
909k
  auto len = crc2len & 3;
1286
909k
  uint32_t tmp = pure_crc1_with_init ^ pure_crc2_init;
1287
909k
  if (len) {
1288
560k
    tmp = PureExtend(tmp, zeros, len);
1289
560k
  }
1290
909k
  return PureToInverted(
1291
909k
      Crc32AppendZeroes(tmp, crc2len / 4, crc32c_m, crc32c_powers) ^
1292
909k
      pure_crc2_with_init);
1293
909k
}
1294
1295
}  // namespace ROCKSDB_NAMESPACE::crc32c