Coverage Report

Created: 2026-05-31 07:45

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
49.7k
std::string IsFastCrc32Supported() {
363
49.7k
  bool has_fast_crc = false;
364
49.7k
  std::string fast_zero_msg;
365
49.7k
  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
49.7k
#ifdef __SSE4_2__
387
49.7k
  has_fast_crc = true;
388
49.7k
#endif  // __SSE4_2__
389
49.7k
  arch = "x86";
390
49.7k
#endif
391
49.7k
  if (has_fast_crc) {
392
49.7k
    fast_zero_msg.append("Supported on " + arch);
393
49.7k
  } else {
394
0
    fast_zero_msg.append("Not supported on " + arch);
395
0
  }
396
49.7k
  return fast_zero_msg;
397
49.7k
}
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.4M
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
433
12.4M
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset)); \
434
12.4M
  crc##2 = _mm_crc32_u64(crc##2, *(buf##2 + offset));
435
436
#define CRCduplet(crc, buf, offset)                   \
437
240k
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
438
240k
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset));
439
440
#define CRCsinglet(crc, buf, offset) \
441
6.58M
  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
17.2M
    const unsigned char*& next) { // next data pointer, updated on return
524
17.2M
  uint32_t crc32bit = static_cast<uint32_t>(crc0);
525
17.2M
  if (len & 0x04) {
526
1.01M
    crc32bit = _mm_crc32_u32(crc32bit, *(uint32_t*)next);
527
1.01M
    next += sizeof(uint32_t);
528
1.01M
  }
529
17.2M
  if (len & 0x02) {
530
1.34M
    crc32bit = _mm_crc32_u16(crc32bit, *(uint16_t*)next);
531
1.34M
    next += sizeof(uint16_t);
532
1.34M
  }
533
17.2M
  if (len & 0x01) {
534
15.9M
    crc32bit = _mm_crc32_u8(crc32bit, *(next));
535
15.9M
    next++;
536
15.9M
  }
537
17.2M
  crc0 = crc32bit;
538
17.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
240k
    const uint64_t* next2) {
550
240k
  const auto multiplier =
551
240k
      *(reinterpret_cast<const __m128i*>(clmul_constants) + block_size - 1);
552
240k
  const auto crc0_xmm = _mm_set_epi64x(0, crc0);
553
240k
  const auto res0 = _mm_clmulepi64_si128(crc0_xmm, multiplier, 0x00);
554
240k
  const auto crc1_xmm = _mm_set_epi64x(0, crc1);
555
240k
  const auto res1 = _mm_clmulepi64_si128(crc1_xmm, multiplier, 0x10);
556
240k
  const auto res = _mm_xor_si128(res0, res1);
557
240k
  crc0 = _mm_cvtsi128_si64(res);
558
240k
  crc0 = crc0 ^ *((uint64_t*)next2 - 1);
559
240k
  crc2 = _mm_crc32_u64(crc2, crc0);
560
240k
  return crc2;
561
240k
}
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
17.0M
uint32_t crc32c_3way(uint32_t crc, const char* buf, size_t len) {
572
17.0M
  const unsigned char* next = (const unsigned char*)buf;
573
17.0M
  uint64_t count;
574
17.0M
  uint64_t crc0, crc1, crc2;
575
17.0M
  crc0 = crc ^ 0xffffffffu;
576
577
578
17.0M
  if (len >= 8) {
579
    // if len > 216 then align and use triplets
580
1.66M
    if (len > 216) {
581
175k
      {
582
        // Work on the bytes (< 8) before the first 8-byte alignment addr starts
583
175k
        uint64_t align_bytes = (8 - (uintptr_t)next) & 7;
584
175k
        len -= align_bytes;
585
175k
        align_to_8(align_bytes, crc0, next);
586
175k
      }
587
588
      // Now work on the remaining blocks
589
175k
      count = len / 24; // number of triplets
590
175k
      len %= 24; // bytes remaining
591
175k
      uint64_t n = count >> 7; // #blocks = first block + full blocks
592
175k
      uint64_t block_size = count & 127;
593
175k
      if (block_size == 0) {
594
144
        block_size = 128;
595
175k
      } else {
596
175k
        n++;
597
175k
      }
598
      // points to the first byte of the next block
599
175k
      const uint64_t* next0 = (uint64_t*)next + block_size;
600
175k
      const uint64_t* next1 = next0 + block_size;
601
175k
      const uint64_t* next2 = next1 + block_size;
602
603
175k
      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
175k
      switch (block_size) {
608
144
        case 128:
609
64.3k
          do {
610
            // jumps here for a full block of len 128
611
64.3k
            CRCtriplet(crc, next, -128);
612
64.3k
            FALLTHROUGH_INTENDED;
613
64.5k
            case 127:
614
              // jumps here or below for the first block smaller
615
64.5k
              CRCtriplet(crc, next, -127);
616
64.5k
              FALLTHROUGH_INTENDED;
617
64.6k
            case 126:
618
64.6k
              CRCtriplet(crc, next, -126); // than 128
619
64.6k
              FALLTHROUGH_INTENDED;
620
64.7k
            case 125:
621
64.7k
              CRCtriplet(crc, next, -125);
622
64.7k
              FALLTHROUGH_INTENDED;
623
64.8k
            case 124:
624
64.8k
              CRCtriplet(crc, next, -124);
625
64.8k
              FALLTHROUGH_INTENDED;
626
64.9k
            case 123:
627
64.9k
              CRCtriplet(crc, next, -123);
628
64.9k
              FALLTHROUGH_INTENDED;
629
65.0k
            case 122:
630
65.0k
              CRCtriplet(crc, next, -122);
631
65.0k
              FALLTHROUGH_INTENDED;
632
65.2k
            case 121:
633
65.2k
              CRCtriplet(crc, next, -121);
634
65.2k
              FALLTHROUGH_INTENDED;
635
65.3k
            case 120:
636
65.3k
              CRCtriplet(crc, next, -120);
637
65.3k
              FALLTHROUGH_INTENDED;
638
65.4k
            case 119:
639
65.4k
              CRCtriplet(crc, next, -119);
640
65.4k
              FALLTHROUGH_INTENDED;
641
65.5k
            case 118:
642
65.5k
              CRCtriplet(crc, next, -118);
643
65.5k
              FALLTHROUGH_INTENDED;
644
65.7k
            case 117:
645
65.7k
              CRCtriplet(crc, next, -117);
646
65.7k
              FALLTHROUGH_INTENDED;
647
65.9k
            case 116:
648
65.9k
              CRCtriplet(crc, next, -116);
649
65.9k
              FALLTHROUGH_INTENDED;
650
66.1k
            case 115:
651
66.1k
              CRCtriplet(crc, next, -115);
652
66.1k
              FALLTHROUGH_INTENDED;
653
66.2k
            case 114:
654
66.2k
              CRCtriplet(crc, next, -114);
655
66.2k
              FALLTHROUGH_INTENDED;
656
66.4k
            case 113:
657
66.4k
              CRCtriplet(crc, next, -113);
658
66.4k
              FALLTHROUGH_INTENDED;
659
66.6k
            case 112:
660
66.6k
              CRCtriplet(crc, next, -112);
661
66.6k
              FALLTHROUGH_INTENDED;
662
66.8k
            case 111:
663
66.8k
              CRCtriplet(crc, next, -111);
664
66.8k
              FALLTHROUGH_INTENDED;
665
67.1k
            case 110:
666
67.1k
              CRCtriplet(crc, next, -110);
667
67.1k
              FALLTHROUGH_INTENDED;
668
67.3k
            case 109:
669
67.3k
              CRCtriplet(crc, next, -109);
670
67.3k
              FALLTHROUGH_INTENDED;
671
67.6k
            case 108:
672
67.6k
              CRCtriplet(crc, next, -108);
673
67.6k
              FALLTHROUGH_INTENDED;
674
67.8k
            case 107:
675
67.8k
              CRCtriplet(crc, next, -107);
676
67.8k
              FALLTHROUGH_INTENDED;
677
68.0k
            case 106:
678
68.0k
              CRCtriplet(crc, next, -106);
679
68.0k
              FALLTHROUGH_INTENDED;
680
68.1k
            case 105:
681
68.1k
              CRCtriplet(crc, next, -105);
682
68.1k
              FALLTHROUGH_INTENDED;
683
68.3k
            case 104:
684
68.3k
              CRCtriplet(crc, next, -104);
685
68.3k
              FALLTHROUGH_INTENDED;
686
68.4k
            case 103:
687
68.4k
              CRCtriplet(crc, next, -103);
688
68.4k
              FALLTHROUGH_INTENDED;
689
68.6k
            case 102:
690
68.6k
              CRCtriplet(crc, next, -102);
691
68.6k
              FALLTHROUGH_INTENDED;
692
68.9k
            case 101:
693
68.9k
              CRCtriplet(crc, next, -101);
694
68.9k
              FALLTHROUGH_INTENDED;
695
69.1k
            case 100:
696
69.1k
              CRCtriplet(crc, next, -100);
697
69.1k
              FALLTHROUGH_INTENDED;
698
69.2k
            case 99:
699
69.2k
              CRCtriplet(crc, next, -99);
700
69.2k
              FALLTHROUGH_INTENDED;
701
69.3k
            case 98:
702
69.3k
              CRCtriplet(crc, next, -98);
703
69.3k
              FALLTHROUGH_INTENDED;
704
69.4k
            case 97:
705
69.4k
              CRCtriplet(crc, next, -97);
706
69.4k
              FALLTHROUGH_INTENDED;
707
69.5k
            case 96:
708
69.5k
              CRCtriplet(crc, next, -96);
709
69.5k
              FALLTHROUGH_INTENDED;
710
69.8k
            case 95:
711
69.8k
              CRCtriplet(crc, next, -95);
712
69.8k
              FALLTHROUGH_INTENDED;
713
70.1k
            case 94:
714
70.1k
              CRCtriplet(crc, next, -94);
715
70.1k
              FALLTHROUGH_INTENDED;
716
71.2k
            case 93:
717
71.2k
              CRCtriplet(crc, next, -93);
718
71.2k
              FALLTHROUGH_INTENDED;
719
72.5k
            case 92:
720
72.5k
              CRCtriplet(crc, next, -92);
721
72.5k
              FALLTHROUGH_INTENDED;
722
72.6k
            case 91:
723
72.6k
              CRCtriplet(crc, next, -91);
724
72.6k
              FALLTHROUGH_INTENDED;
725
72.8k
            case 90:
726
72.8k
              CRCtriplet(crc, next, -90);
727
72.8k
              FALLTHROUGH_INTENDED;
728
73.1k
            case 89:
729
73.1k
              CRCtriplet(crc, next, -89);
730
73.1k
              FALLTHROUGH_INTENDED;
731
73.2k
            case 88:
732
73.2k
              CRCtriplet(crc, next, -88);
733
73.2k
              FALLTHROUGH_INTENDED;
734
73.5k
            case 87:
735
73.5k
              CRCtriplet(crc, next, -87);
736
73.5k
              FALLTHROUGH_INTENDED;
737
73.8k
            case 86:
738
73.8k
              CRCtriplet(crc, next, -86);
739
73.8k
              FALLTHROUGH_INTENDED;
740
75.4k
            case 85:
741
75.4k
              CRCtriplet(crc, next, -85);
742
75.4k
              FALLTHROUGH_INTENDED;
743
76.9k
            case 84:
744
76.9k
              CRCtriplet(crc, next, -84);
745
76.9k
              FALLTHROUGH_INTENDED;
746
77.2k
            case 83:
747
77.2k
              CRCtriplet(crc, next, -83);
748
77.2k
              FALLTHROUGH_INTENDED;
749
77.4k
            case 82:
750
77.4k
              CRCtriplet(crc, next, -82);
751
77.4k
              FALLTHROUGH_INTENDED;
752
77.8k
            case 81:
753
77.8k
              CRCtriplet(crc, next, -81);
754
77.8k
              FALLTHROUGH_INTENDED;
755
78.1k
            case 80:
756
78.1k
              CRCtriplet(crc, next, -80);
757
78.1k
              FALLTHROUGH_INTENDED;
758
78.5k
            case 79:
759
78.5k
              CRCtriplet(crc, next, -79);
760
78.5k
              FALLTHROUGH_INTENDED;
761
78.9k
            case 78:
762
78.9k
              CRCtriplet(crc, next, -78);
763
78.9k
              FALLTHROUGH_INTENDED;
764
79.1k
            case 77:
765
79.1k
              CRCtriplet(crc, next, -77);
766
79.1k
              FALLTHROUGH_INTENDED;
767
79.3k
            case 76:
768
79.3k
              CRCtriplet(crc, next, -76);
769
79.3k
              FALLTHROUGH_INTENDED;
770
79.6k
            case 75:
771
79.6k
              CRCtriplet(crc, next, -75);
772
79.6k
              FALLTHROUGH_INTENDED;
773
79.8k
            case 74:
774
79.8k
              CRCtriplet(crc, next, -74);
775
79.8k
              FALLTHROUGH_INTENDED;
776
80.1k
            case 73:
777
80.1k
              CRCtriplet(crc, next, -73);
778
80.1k
              FALLTHROUGH_INTENDED;
779
80.6k
            case 72:
780
80.6k
              CRCtriplet(crc, next, -72);
781
80.6k
              FALLTHROUGH_INTENDED;
782
80.9k
            case 71:
783
80.9k
              CRCtriplet(crc, next, -71);
784
80.9k
              FALLTHROUGH_INTENDED;
785
81.1k
            case 70:
786
81.1k
              CRCtriplet(crc, next, -70);
787
81.1k
              FALLTHROUGH_INTENDED;
788
81.6k
            case 69:
789
81.6k
              CRCtriplet(crc, next, -69);
790
81.6k
              FALLTHROUGH_INTENDED;
791
83.1k
            case 68:
792
83.1k
              CRCtriplet(crc, next, -68);
793
83.1k
              FALLTHROUGH_INTENDED;
794
83.3k
            case 67:
795
83.3k
              CRCtriplet(crc, next, -67);
796
83.3k
              FALLTHROUGH_INTENDED;
797
83.7k
            case 66:
798
83.7k
              CRCtriplet(crc, next, -66);
799
83.7k
              FALLTHROUGH_INTENDED;
800
84.0k
            case 65:
801
84.0k
              CRCtriplet(crc, next, -65);
802
84.0k
              FALLTHROUGH_INTENDED;
803
84.4k
            case 64:
804
84.4k
              CRCtriplet(crc, next, -64);
805
84.4k
              FALLTHROUGH_INTENDED;
806
84.6k
            case 63:
807
84.6k
              CRCtriplet(crc, next, -63);
808
84.6k
              FALLTHROUGH_INTENDED;
809
85.2k
            case 62:
810
85.2k
              CRCtriplet(crc, next, -62);
811
85.2k
              FALLTHROUGH_INTENDED;
812
85.9k
            case 61:
813
85.9k
              CRCtriplet(crc, next, -61);
814
85.9k
              FALLTHROUGH_INTENDED;
815
86.3k
            case 60:
816
86.3k
              CRCtriplet(crc, next, -60);
817
86.3k
              FALLTHROUGH_INTENDED;
818
86.7k
            case 59:
819
86.7k
              CRCtriplet(crc, next, -59);
820
86.7k
              FALLTHROUGH_INTENDED;
821
87.4k
            case 58:
822
87.4k
              CRCtriplet(crc, next, -58);
823
87.4k
              FALLTHROUGH_INTENDED;
824
89.3k
            case 57:
825
89.3k
              CRCtriplet(crc, next, -57);
826
89.3k
              FALLTHROUGH_INTENDED;
827
89.6k
            case 56:
828
89.6k
              CRCtriplet(crc, next, -56);
829
89.6k
              FALLTHROUGH_INTENDED;
830
90.0k
            case 55:
831
90.0k
              CRCtriplet(crc, next, -55);
832
90.0k
              FALLTHROUGH_INTENDED;
833
90.4k
            case 54:
834
90.4k
              CRCtriplet(crc, next, -54);
835
90.4k
              FALLTHROUGH_INTENDED;
836
90.8k
            case 53:
837
90.8k
              CRCtriplet(crc, next, -53);
838
90.8k
              FALLTHROUGH_INTENDED;
839
91.0k
            case 52:
840
91.0k
              CRCtriplet(crc, next, -52);
841
91.0k
              FALLTHROUGH_INTENDED;
842
91.2k
            case 51:
843
91.2k
              CRCtriplet(crc, next, -51);
844
91.2k
              FALLTHROUGH_INTENDED;
845
91.6k
            case 50:
846
91.6k
              CRCtriplet(crc, next, -50);
847
91.6k
              FALLTHROUGH_INTENDED;
848
91.9k
            case 49:
849
91.9k
              CRCtriplet(crc, next, -49);
850
91.9k
              FALLTHROUGH_INTENDED;
851
92.8k
            case 48:
852
92.8k
              CRCtriplet(crc, next, -48);
853
92.8k
              FALLTHROUGH_INTENDED;
854
93.5k
            case 47:
855
93.5k
              CRCtriplet(crc, next, -47);
856
93.5k
              FALLTHROUGH_INTENDED;
857
93.8k
            case 46:
858
93.8k
              CRCtriplet(crc, next, -46);
859
93.8k
              FALLTHROUGH_INTENDED;
860
94.1k
            case 45:
861
94.1k
              CRCtriplet(crc, next, -45);
862
94.1k
              FALLTHROUGH_INTENDED;
863
94.5k
            case 44:
864
94.5k
              CRCtriplet(crc, next, -44);
865
94.5k
              FALLTHROUGH_INTENDED;
866
94.8k
            case 43:
867
94.8k
              CRCtriplet(crc, next, -43);
868
94.8k
              FALLTHROUGH_INTENDED;
869
95.4k
            case 42:
870
95.4k
              CRCtriplet(crc, next, -42);
871
95.4k
              FALLTHROUGH_INTENDED;
872
96.1k
            case 41:
873
96.1k
              CRCtriplet(crc, next, -41);
874
96.1k
              FALLTHROUGH_INTENDED;
875
97.1k
            case 40:
876
97.1k
              CRCtriplet(crc, next, -40);
877
97.1k
              FALLTHROUGH_INTENDED;
878
97.4k
            case 39:
879
97.4k
              CRCtriplet(crc, next, -39);
880
97.4k
              FALLTHROUGH_INTENDED;
881
97.8k
            case 38:
882
97.8k
              CRCtriplet(crc, next, -38);
883
97.8k
              FALLTHROUGH_INTENDED;
884
98.3k
            case 37:
885
98.3k
              CRCtriplet(crc, next, -37);
886
98.3k
              FALLTHROUGH_INTENDED;
887
98.9k
            case 36:
888
98.9k
              CRCtriplet(crc, next, -36);
889
98.9k
              FALLTHROUGH_INTENDED;
890
99.7k
            case 35:
891
99.7k
              CRCtriplet(crc, next, -35);
892
99.7k
              FALLTHROUGH_INTENDED;
893
100k
            case 34:
894
100k
              CRCtriplet(crc, next, -34);
895
100k
              FALLTHROUGH_INTENDED;
896
100k
            case 33:
897
100k
              CRCtriplet(crc, next, -33);
898
100k
              FALLTHROUGH_INTENDED;
899
102k
            case 32:
900
102k
              CRCtriplet(crc, next, -32);
901
102k
              FALLTHROUGH_INTENDED;
902
102k
            case 31:
903
102k
              CRCtriplet(crc, next, -31);
904
102k
              FALLTHROUGH_INTENDED;
905
103k
            case 30:
906
103k
              CRCtriplet(crc, next, -30);
907
103k
              FALLTHROUGH_INTENDED;
908
106k
            case 29:
909
106k
              CRCtriplet(crc, next, -29);
910
106k
              FALLTHROUGH_INTENDED;
911
108k
            case 28:
912
108k
              CRCtriplet(crc, next, -28);
913
108k
              FALLTHROUGH_INTENDED;
914
109k
            case 27:
915
109k
              CRCtriplet(crc, next, -27);
916
109k
              FALLTHROUGH_INTENDED;
917
110k
            case 26:
918
110k
              CRCtriplet(crc, next, -26);
919
110k
              FALLTHROUGH_INTENDED;
920
111k
            case 25:
921
111k
              CRCtriplet(crc, next, -25);
922
111k
              FALLTHROUGH_INTENDED;
923
112k
            case 24:
924
112k
              CRCtriplet(crc, next, -24);
925
112k
              FALLTHROUGH_INTENDED;
926
114k
            case 23:
927
114k
              CRCtriplet(crc, next, -23);
928
114k
              FALLTHROUGH_INTENDED;
929
116k
            case 22:
930
116k
              CRCtriplet(crc, next, -22);
931
116k
              FALLTHROUGH_INTENDED;
932
119k
            case 21:
933
119k
              CRCtriplet(crc, next, -21);
934
119k
              FALLTHROUGH_INTENDED;
935
123k
            case 20:
936
123k
              CRCtriplet(crc, next, -20);
937
123k
              FALLTHROUGH_INTENDED;
938
126k
            case 19:
939
126k
              CRCtriplet(crc, next, -19);
940
126k
              FALLTHROUGH_INTENDED;
941
129k
            case 18:
942
129k
              CRCtriplet(crc, next, -18);
943
129k
              FALLTHROUGH_INTENDED;
944
133k
            case 17:
945
133k
              CRCtriplet(crc, next, -17);
946
133k
              FALLTHROUGH_INTENDED;
947
137k
            case 16:
948
137k
              CRCtriplet(crc, next, -16);
949
137k
              FALLTHROUGH_INTENDED;
950
143k
            case 15:
951
143k
              CRCtriplet(crc, next, -15);
952
143k
              FALLTHROUGH_INTENDED;
953
148k
            case 14:
954
148k
              CRCtriplet(crc, next, -14);
955
148k
              FALLTHROUGH_INTENDED;
956
153k
            case 13:
957
153k
              CRCtriplet(crc, next, -13);
958
153k
              FALLTHROUGH_INTENDED;
959
157k
            case 12:
960
157k
              CRCtriplet(crc, next, -12);
961
157k
              FALLTHROUGH_INTENDED;
962
190k
            case 11:
963
190k
              CRCtriplet(crc, next, -11);
964
190k
              FALLTHROUGH_INTENDED;
965
204k
            case 10:
966
204k
              CRCtriplet(crc, next, -10);
967
204k
              FALLTHROUGH_INTENDED;
968
238k
            case 9:
969
238k
              CRCtriplet(crc, next, -9);
970
238k
              FALLTHROUGH_INTENDED;
971
238k
            case 8:
972
238k
              CRCtriplet(crc, next, -8);
973
238k
              FALLTHROUGH_INTENDED;
974
238k
            case 7:
975
238k
              CRCtriplet(crc, next, -7);
976
238k
              FALLTHROUGH_INTENDED;
977
239k
            case 6:
978
239k
              CRCtriplet(crc, next, -6);
979
239k
              FALLTHROUGH_INTENDED;
980
239k
            case 5:
981
239k
              CRCtriplet(crc, next, -5);
982
239k
              FALLTHROUGH_INTENDED;
983
239k
            case 4:
984
239k
              CRCtriplet(crc, next, -4);
985
239k
              FALLTHROUGH_INTENDED;
986
239k
            case 3:
987
239k
              CRCtriplet(crc, next, -3);
988
239k
              FALLTHROUGH_INTENDED;
989
240k
            case 2:
990
240k
              CRCtriplet(crc, next, -2);
991
240k
              FALLTHROUGH_INTENDED;
992
240k
            case 1:
993
240k
              CRCduplet(crc, next, -1); // the final triplet is actually only 2
994
              //{ CombineCRC(); }
995
240k
              crc0 = CombineCRC(block_size, crc0, crc1, crc2, next2);
996
240k
              if (--n > 0) {
997
64.2k
                crc1 = crc2 = 0;
998
64.2k
                block_size = 128;
999
                // points to the first byte of the next block
1000
64.2k
                next0 = next2 + 128;
1001
64.2k
                next1 = next0 + 128; // from here on all blocks are 128 long
1002
64.2k
                next2 = next1 + 128;
1003
64.2k
              }
1004
240k
              FALLTHROUGH_INTENDED;
1005
240k
            case 0:;
1006
240k
          } while (n > 0);
1007
175k
      }
1008
175k
      next = (const unsigned char*)next2;
1009
175k
    }
1010
1.66M
    uint64_t count2 = len >> 3; // 216 of less bytes is 27 or less singlets
1011
1.66M
    len = len & 7;
1012
1.66M
    next += (count2 * 8);
1013
1.66M
    switch (count2) {
1014
2.11k
      case 27:
1015
2.11k
        CRCsinglet(crc0, next, -27 * 8);
1016
2.11k
        FALLTHROUGH_INTENDED;
1017
15.9k
      case 26:
1018
15.9k
        CRCsinglet(crc0, next, -26 * 8);
1019
15.9k
        FALLTHROUGH_INTENDED;
1020
26.1k
      case 25:
1021
26.1k
        CRCsinglet(crc0, next, -25 * 8);
1022
26.1k
        FALLTHROUGH_INTENDED;
1023
33.2k
      case 24:
1024
33.2k
        CRCsinglet(crc0, next, -24 * 8);
1025
33.2k
        FALLTHROUGH_INTENDED;
1026
37.7k
      case 23:
1027
37.7k
        CRCsinglet(crc0, next, -23 * 8);
1028
37.7k
        FALLTHROUGH_INTENDED;
1029
43.2k
      case 22:
1030
43.2k
        CRCsinglet(crc0, next, -22 * 8);
1031
43.2k
        FALLTHROUGH_INTENDED;
1032
48.8k
      case 21:
1033
48.8k
        CRCsinglet(crc0, next, -21 * 8);
1034
48.8k
        FALLTHROUGH_INTENDED;
1035
53.8k
      case 20:
1036
53.8k
        CRCsinglet(crc0, next, -20 * 8);
1037
53.8k
        FALLTHROUGH_INTENDED;
1038
59.8k
      case 19:
1039
59.8k
        CRCsinglet(crc0, next, -19 * 8);
1040
59.8k
        FALLTHROUGH_INTENDED;
1041
66.6k
      case 18:
1042
66.6k
        CRCsinglet(crc0, next, -18 * 8);
1043
66.6k
        FALLTHROUGH_INTENDED;
1044
76.9k
      case 17:
1045
76.9k
        CRCsinglet(crc0, next, -17 * 8);
1046
76.9k
        FALLTHROUGH_INTENDED;
1047
83.9k
      case 16:
1048
83.9k
        CRCsinglet(crc0, next, -16 * 8);
1049
83.9k
        FALLTHROUGH_INTENDED;
1050
90.3k
      case 15:
1051
90.3k
        CRCsinglet(crc0, next, -15 * 8);
1052
90.3k
        FALLTHROUGH_INTENDED;
1053
99.4k
      case 14:
1054
99.4k
        CRCsinglet(crc0, next, -14 * 8);
1055
99.4k
        FALLTHROUGH_INTENDED;
1056
107k
      case 13:
1057
107k
        CRCsinglet(crc0, next, -13 * 8);
1058
107k
        FALLTHROUGH_INTENDED;
1059
117k
      case 12:
1060
117k
        CRCsinglet(crc0, next, -12 * 8);
1061
117k
        FALLTHROUGH_INTENDED;
1062
129k
      case 11:
1063
129k
        CRCsinglet(crc0, next, -11 * 8);
1064
129k
        FALLTHROUGH_INTENDED;
1065
151k
      case 10:
1066
151k
        CRCsinglet(crc0, next, -10 * 8);
1067
151k
        FALLTHROUGH_INTENDED;
1068
186k
      case 9:
1069
186k
        CRCsinglet(crc0, next, -9 * 8);
1070
186k
        FALLTHROUGH_INTENDED;
1071
211k
      case 8:
1072
211k
        CRCsinglet(crc0, next, -8 * 8);
1073
211k
        FALLTHROUGH_INTENDED;
1074
228k
      case 7:
1075
228k
        CRCsinglet(crc0, next, -7 * 8);
1076
228k
        FALLTHROUGH_INTENDED;
1077
298k
      case 6:
1078
298k
        CRCsinglet(crc0, next, -6 * 8);
1079
298k
        FALLTHROUGH_INTENDED;
1080
442k
      case 5:
1081
442k
        CRCsinglet(crc0, next, -5 * 8);
1082
442k
        FALLTHROUGH_INTENDED;
1083
610k
      case 4:
1084
610k
        CRCsinglet(crc0, next, -4 * 8);
1085
610k
        FALLTHROUGH_INTENDED;
1086
656k
      case 3:
1087
656k
        CRCsinglet(crc0, next, -3 * 8);
1088
656k
        FALLTHROUGH_INTENDED;
1089
1.10M
      case 2:
1090
1.10M
        CRCsinglet(crc0, next, -2 * 8);
1091
1.10M
        FALLTHROUGH_INTENDED;
1092
1.60M
      case 1:
1093
1.60M
        CRCsinglet(crc0, next, -1 * 8);
1094
1.60M
        FALLTHROUGH_INTENDED;
1095
1.66M
      case 0:;
1096
1.66M
    }
1097
1.66M
  }
1098
17.0M
  {
1099
17.0M
    align_to_8(len, crc0, next);
1100
17.0M
    return (uint32_t)crc0 ^ 0xffffffffu;
1101
17.0M
  }
1102
17.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
17.0M
uint32_t Extend(uint32_t crc, const char* buf, size_t size) {
1133
17.0M
  return ChosenExtend(crc, buf, size);
1134
17.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
64.5M
    size_t i, uint32_t p, uint32_t a, uint32_t b, uint32_t m) {
1144
  // clang-format off
1145
64.5M
  return i == 32 ? p : gf_multiply_sw_1(
1146
62.5M
      /* i = */ i + 1,
1147
62.5M
      /* p = */ p ^ ((0u-((b >> 31) & 1)) & a),
1148
62.5M
      /* a = */ (a >> 1) ^ ((0u-(a & 1)) & m),
1149
62.5M
      /* b = */ b << 1,
1150
62.5M
      /* m = */ m);
1151
  // clang-format on
1152
64.5M
}
1153
1.95M
static constexpr uint32_t gf_multiply_sw(uint32_t a, uint32_t b, uint32_t m) {
1154
1.95M
  return gf_multiply_sw_1(/* i = */ 0, /* p = */ 0, a, b, m);
1155
1.95M
}
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
1.04M
    std::array<uint32_t, 62> const& powers_array) {
1206
1.04M
  auto powers = powers_array.data();
1207
  // Append by multiplying by consecutive powers of two of the zeroes
1208
  // array
1209
1.04M
  size_t len_bits = len_over_4;
1210
1211
3.00M
  while (len_bits) {
1212
    // Advance directly to next bit set.
1213
1.95M
    auto r = CountTrailingZeroBits(len_bits);
1214
1.95M
    len_bits >>= r;
1215
1.95M
    powers += r;
1216
1217
1.95M
    crc = gf_multiply_sw(crc, *powers, polynomial);
1218
1219
1.95M
    len_bits >>= 1;
1220
1.95M
    powers++;
1221
1.95M
  }
1222
1223
1.04M
  return crc;
1224
1.04M
}
1225
1226
2.74M
static inline uint32_t InvertedToPure(uint32_t crc) { return ~crc; }
1227
1228
1.69M
static inline uint32_t PureToInverted(uint32_t crc) { return ~crc; }
1229
1230
648k
static inline uint32_t PureExtend(uint32_t crc, const char* buf, size_t size) {
1231
648k
  return InvertedToPure(Extend(PureToInverted(crc), buf, size));
1232
648k
}
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
1.04M
uint32_t Crc32cCombine(uint32_t crc1, uint32_t crc2, size_t crc2len) {
1279
1.04M
  uint32_t pure_crc1_with_init = InvertedToPure(crc1);
1280
1.04M
  uint32_t pure_crc2_with_init = InvertedToPure(crc2);
1281
1.04M
  uint32_t pure_crc2_init = static_cast<uint32_t>(-1);
1282
1283
  // Append up to 32 bits of zeroes in the normal way
1284
1.04M
  char zeros[4] = {0, 0, 0, 0};
1285
1.04M
  auto len = crc2len & 3;
1286
1.04M
  uint32_t tmp = pure_crc1_with_init ^ pure_crc2_init;
1287
1.04M
  if (len) {
1288
648k
    tmp = PureExtend(tmp, zeros, len);
1289
648k
  }
1290
1.04M
  return PureToInverted(
1291
1.04M
      Crc32AppendZeroes(tmp, crc2len / 4, crc32c_m, crc32c_powers) ^
1292
1.04M
      pure_crc2_with_init);
1293
1.04M
}
1294
1295
}  // namespace ROCKSDB_NAMESPACE::crc32c