Coverage Report

Created: 2024-07-27 06:53

/src/rocksdb/util/crc32c.cc
Line
Count
Source (jump to first uncovered line)
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
9.02k
std::string IsFastCrc32Supported() {
363
9.02k
  bool has_fast_crc = false;
364
9.02k
  std::string fast_zero_msg;
365
9.02k
  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
9.02k
#ifdef __SSE4_2__
387
9.02k
  has_fast_crc = true;
388
9.02k
#endif  // __SSE4_2__
389
9.02k
  arch = "x86";
390
9.02k
#endif
391
9.02k
  if (has_fast_crc) {
392
9.02k
    fast_zero_msg.append("Supported on " + arch);
393
9.02k
  } else {
394
0
    fast_zero_msg.append("Not supported on " + arch);
395
0
  }
396
9.02k
  return fast_zero_msg;
397
9.02k
}
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
27.4M
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
433
27.4M
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset)); \
434
27.4M
  crc##2 = _mm_crc32_u64(crc##2, *(buf##2 + offset));
435
436
#define CRCduplet(crc, buf, offset)                   \
437
412k
  crc##0 = _mm_crc32_u64(crc##0, *(buf##0 + offset)); \
438
412k
  crc##1 = _mm_crc32_u64(crc##1, *(buf##1 + offset));
439
440
#define CRCsinglet(crc, buf, offset) \
441
10.3M
  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
4.42M
    const unsigned char*& next) { // next data pointer, updated on return
524
4.42M
  uint32_t crc32bit = static_cast<uint32_t>(crc0);
525
4.42M
  if (len & 0x04) {
526
1.39M
    crc32bit = _mm_crc32_u32(crc32bit, *(uint32_t*)next);
527
1.39M
    next += sizeof(uint32_t);
528
1.39M
  }
529
4.42M
  if (len & 0x02) {
530
2.31M
    crc32bit = _mm_crc32_u16(crc32bit, *(uint16_t*)next);
531
2.31M
    next += sizeof(uint16_t);
532
2.31M
  }
533
4.42M
  if (len & 0x01) {
534
2.54M
    crc32bit = _mm_crc32_u8(crc32bit, *(next));
535
2.54M
    next++;
536
2.54M
  }
537
4.42M
  crc0 = crc32bit;
538
4.42M
}
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
412k
    const uint64_t* next2) {
550
412k
  const auto multiplier =
551
412k
      *(reinterpret_cast<const __m128i*>(clmul_constants) + block_size - 1);
552
412k
  const auto crc0_xmm = _mm_set_epi64x(0, crc0);
553
412k
  const auto res0 = _mm_clmulepi64_si128(crc0_xmm, multiplier, 0x00);
554
412k
  const auto crc1_xmm = _mm_set_epi64x(0, crc1);
555
412k
  const auto res1 = _mm_clmulepi64_si128(crc1_xmm, multiplier, 0x10);
556
412k
  const auto res = _mm_xor_si128(res0, res1);
557
412k
  crc0 = _mm_cvtsi128_si64(res);
558
412k
  crc0 = crc0 ^ *((uint64_t*)next2 - 1);
559
412k
  crc2 = _mm_crc32_u64(crc2, crc0);
560
412k
  return crc2;
561
412k
}
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
4.16M
uint32_t crc32c_3way(uint32_t crc, const char* buf, size_t len) {
572
4.16M
  const unsigned char* next = (const unsigned char*)buf;
573
4.16M
  uint64_t count;
574
4.16M
  uint64_t crc0, crc1, crc2;
575
4.16M
  crc0 = crc ^ 0xffffffffu;
576
577
578
4.16M
  if (len >= 8) {
579
    // if len > 216 then align and use triplets
580
2.76M
    if (len > 216) {
581
258k
      {
582
        // Work on the bytes (< 8) before the first 8-byte alignment addr starts
583
258k
        uint64_t align_bytes = (8 - (uintptr_t)next) & 7;
584
258k
        len -= align_bytes;
585
258k
        align_to_8(align_bytes, crc0, next);
586
258k
      }
587
588
      // Now work on the remaining blocks
589
258k
      count = len / 24; // number of triplets
590
258k
      len %= 24; // bytes remaining
591
258k
      uint64_t n = count >> 7; // #blocks = first block + full blocks
592
258k
      uint64_t block_size = count & 127;
593
258k
      if (block_size == 0) {
594
249
        block_size = 128;
595
258k
      } else {
596
258k
        n++;
597
258k
      }
598
      // points to the first byte of the next block
599
258k
      const uint64_t* next0 = (uint64_t*)next + block_size;
600
258k
      const uint64_t* next1 = next0 + block_size;
601
258k
      const uint64_t* next2 = next1 + block_size;
602
603
258k
      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
258k
      switch (block_size) {
608
249
        case 128:
609
153k
          do {
610
            // jumps here for a full block of len 128
611
153k
            CRCtriplet(crc, next, -128);
612
153k
            FALLTHROUGH_INTENDED;
613
153k
            case 127:
614
              // jumps here or below for the first block smaller
615
153k
              CRCtriplet(crc, next, -127);
616
153k
              FALLTHROUGH_INTENDED;
617
154k
            case 126:
618
154k
              CRCtriplet(crc, next, -126); // than 128
619
154k
              FALLTHROUGH_INTENDED;
620
154k
            case 125:
621
154k
              CRCtriplet(crc, next, -125);
622
154k
              FALLTHROUGH_INTENDED;
623
155k
            case 124:
624
155k
              CRCtriplet(crc, next, -124);
625
155k
              FALLTHROUGH_INTENDED;
626
155k
            case 123:
627
155k
              CRCtriplet(crc, next, -123);
628
155k
              FALLTHROUGH_INTENDED;
629
155k
            case 122:
630
155k
              CRCtriplet(crc, next, -122);
631
155k
              FALLTHROUGH_INTENDED;
632
156k
            case 121:
633
156k
              CRCtriplet(crc, next, -121);
634
156k
              FALLTHROUGH_INTENDED;
635
156k
            case 120:
636
156k
              CRCtriplet(crc, next, -120);
637
156k
              FALLTHROUGH_INTENDED;
638
156k
            case 119:
639
156k
              CRCtriplet(crc, next, -119);
640
156k
              FALLTHROUGH_INTENDED;
641
157k
            case 118:
642
157k
              CRCtriplet(crc, next, -118);
643
157k
              FALLTHROUGH_INTENDED;
644
157k
            case 117:
645
157k
              CRCtriplet(crc, next, -117);
646
157k
              FALLTHROUGH_INTENDED;
647
157k
            case 116:
648
157k
              CRCtriplet(crc, next, -116);
649
157k
              FALLTHROUGH_INTENDED;
650
158k
            case 115:
651
158k
              CRCtriplet(crc, next, -115);
652
158k
              FALLTHROUGH_INTENDED;
653
159k
            case 114:
654
159k
              CRCtriplet(crc, next, -114);
655
159k
              FALLTHROUGH_INTENDED;
656
160k
            case 113:
657
160k
              CRCtriplet(crc, next, -113);
658
160k
              FALLTHROUGH_INTENDED;
659
160k
            case 112:
660
160k
              CRCtriplet(crc, next, -112);
661
160k
              FALLTHROUGH_INTENDED;
662
161k
            case 111:
663
161k
              CRCtriplet(crc, next, -111);
664
161k
              FALLTHROUGH_INTENDED;
665
162k
            case 110:
666
162k
              CRCtriplet(crc, next, -110);
667
162k
              FALLTHROUGH_INTENDED;
668
162k
            case 109:
669
162k
              CRCtriplet(crc, next, -109);
670
162k
              FALLTHROUGH_INTENDED;
671
163k
            case 108:
672
163k
              CRCtriplet(crc, next, -108);
673
163k
              FALLTHROUGH_INTENDED;
674
163k
            case 107:
675
163k
              CRCtriplet(crc, next, -107);
676
163k
              FALLTHROUGH_INTENDED;
677
163k
            case 106:
678
163k
              CRCtriplet(crc, next, -106);
679
163k
              FALLTHROUGH_INTENDED;
680
163k
            case 105:
681
163k
              CRCtriplet(crc, next, -105);
682
163k
              FALLTHROUGH_INTENDED;
683
164k
            case 104:
684
164k
              CRCtriplet(crc, next, -104);
685
164k
              FALLTHROUGH_INTENDED;
686
164k
            case 103:
687
164k
              CRCtriplet(crc, next, -103);
688
164k
              FALLTHROUGH_INTENDED;
689
165k
            case 102:
690
165k
              CRCtriplet(crc, next, -102);
691
165k
              FALLTHROUGH_INTENDED;
692
165k
            case 101:
693
165k
              CRCtriplet(crc, next, -101);
694
165k
              FALLTHROUGH_INTENDED;
695
165k
            case 100:
696
165k
              CRCtriplet(crc, next, -100);
697
165k
              FALLTHROUGH_INTENDED;
698
166k
            case 99:
699
166k
              CRCtriplet(crc, next, -99);
700
166k
              FALLTHROUGH_INTENDED;
701
166k
            case 98:
702
166k
              CRCtriplet(crc, next, -98);
703
166k
              FALLTHROUGH_INTENDED;
704
168k
            case 97:
705
168k
              CRCtriplet(crc, next, -97);
706
168k
              FALLTHROUGH_INTENDED;
707
168k
            case 96:
708
168k
              CRCtriplet(crc, next, -96);
709
168k
              FALLTHROUGH_INTENDED;
710
168k
            case 95:
711
168k
              CRCtriplet(crc, next, -95);
712
168k
              FALLTHROUGH_INTENDED;
713
169k
            case 94:
714
169k
              CRCtriplet(crc, next, -94);
715
169k
              FALLTHROUGH_INTENDED;
716
171k
            case 93:
717
171k
              CRCtriplet(crc, next, -93);
718
171k
              FALLTHROUGH_INTENDED;
719
172k
            case 92:
720
172k
              CRCtriplet(crc, next, -92);
721
172k
              FALLTHROUGH_INTENDED;
722
173k
            case 91:
723
173k
              CRCtriplet(crc, next, -91);
724
173k
              FALLTHROUGH_INTENDED;
725
174k
            case 90:
726
174k
              CRCtriplet(crc, next, -90);
727
174k
              FALLTHROUGH_INTENDED;
728
175k
            case 89:
729
175k
              CRCtriplet(crc, next, -89);
730
175k
              FALLTHROUGH_INTENDED;
731
175k
            case 88:
732
175k
              CRCtriplet(crc, next, -88);
733
175k
              FALLTHROUGH_INTENDED;
734
176k
            case 87:
735
176k
              CRCtriplet(crc, next, -87);
736
176k
              FALLTHROUGH_INTENDED;
737
176k
            case 86:
738
176k
              CRCtriplet(crc, next, -86);
739
176k
              FALLTHROUGH_INTENDED;
740
181k
            case 85:
741
181k
              CRCtriplet(crc, next, -85);
742
181k
              FALLTHROUGH_INTENDED;
743
185k
            case 84:
744
185k
              CRCtriplet(crc, next, -84);
745
185k
              FALLTHROUGH_INTENDED;
746
186k
            case 83:
747
186k
              CRCtriplet(crc, next, -83);
748
186k
              FALLTHROUGH_INTENDED;
749
187k
            case 82:
750
187k
              CRCtriplet(crc, next, -82);
751
187k
              FALLTHROUGH_INTENDED;
752
188k
            case 81:
753
188k
              CRCtriplet(crc, next, -81);
754
188k
              FALLTHROUGH_INTENDED;
755
189k
            case 80:
756
189k
              CRCtriplet(crc, next, -80);
757
189k
              FALLTHROUGH_INTENDED;
758
190k
            case 79:
759
190k
              CRCtriplet(crc, next, -79);
760
190k
              FALLTHROUGH_INTENDED;
761
191k
            case 78:
762
191k
              CRCtriplet(crc, next, -78);
763
191k
              FALLTHROUGH_INTENDED;
764
191k
            case 77:
765
191k
              CRCtriplet(crc, next, -77);
766
191k
              FALLTHROUGH_INTENDED;
767
192k
            case 76:
768
192k
              CRCtriplet(crc, next, -76);
769
192k
              FALLTHROUGH_INTENDED;
770
192k
            case 75:
771
192k
              CRCtriplet(crc, next, -75);
772
192k
              FALLTHROUGH_INTENDED;
773
192k
            case 74:
774
192k
              CRCtriplet(crc, next, -74);
775
192k
              FALLTHROUGH_INTENDED;
776
193k
            case 73:
777
193k
              CRCtriplet(crc, next, -73);
778
193k
              FALLTHROUGH_INTENDED;
779
193k
            case 72:
780
193k
              CRCtriplet(crc, next, -72);
781
193k
              FALLTHROUGH_INTENDED;
782
194k
            case 71:
783
194k
              CRCtriplet(crc, next, -71);
784
194k
              FALLTHROUGH_INTENDED;
785
195k
            case 70:
786
195k
              CRCtriplet(crc, next, -70);
787
195k
              FALLTHROUGH_INTENDED;
788
195k
            case 69:
789
195k
              CRCtriplet(crc, next, -69);
790
195k
              FALLTHROUGH_INTENDED;
791
196k
            case 68:
792
196k
              CRCtriplet(crc, next, -68);
793
196k
              FALLTHROUGH_INTENDED;
794
197k
            case 67:
795
197k
              CRCtriplet(crc, next, -67);
796
197k
              FALLTHROUGH_INTENDED;
797
197k
            case 66:
798
197k
              CRCtriplet(crc, next, -66);
799
197k
              FALLTHROUGH_INTENDED;
800
198k
            case 65:
801
198k
              CRCtriplet(crc, next, -65);
802
198k
              FALLTHROUGH_INTENDED;
803
199k
            case 64:
804
199k
              CRCtriplet(crc, next, -64);
805
199k
              FALLTHROUGH_INTENDED;
806
200k
            case 63:
807
200k
              CRCtriplet(crc, next, -63);
808
200k
              FALLTHROUGH_INTENDED;
809
201k
            case 62:
810
201k
              CRCtriplet(crc, next, -62);
811
201k
              FALLTHROUGH_INTENDED;
812
202k
            case 61:
813
202k
              CRCtriplet(crc, next, -61);
814
202k
              FALLTHROUGH_INTENDED;
815
203k
            case 60:
816
203k
              CRCtriplet(crc, next, -60);
817
203k
              FALLTHROUGH_INTENDED;
818
203k
            case 59:
819
203k
              CRCtriplet(crc, next, -59);
820
203k
              FALLTHROUGH_INTENDED;
821
204k
            case 58:
822
204k
              CRCtriplet(crc, next, -58);
823
204k
              FALLTHROUGH_INTENDED;
824
207k
            case 57:
825
207k
              CRCtriplet(crc, next, -57);
826
207k
              FALLTHROUGH_INTENDED;
827
208k
            case 56:
828
208k
              CRCtriplet(crc, next, -56);
829
208k
              FALLTHROUGH_INTENDED;
830
209k
            case 55:
831
209k
              CRCtriplet(crc, next, -55);
832
209k
              FALLTHROUGH_INTENDED;
833
209k
            case 54:
834
209k
              CRCtriplet(crc, next, -54);
835
209k
              FALLTHROUGH_INTENDED;
836
210k
            case 53:
837
210k
              CRCtriplet(crc, next, -53);
838
210k
              FALLTHROUGH_INTENDED;
839
211k
            case 52:
840
211k
              CRCtriplet(crc, next, -52);
841
211k
              FALLTHROUGH_INTENDED;
842
211k
            case 51:
843
211k
              CRCtriplet(crc, next, -51);
844
211k
              FALLTHROUGH_INTENDED;
845
215k
            case 50:
846
215k
              CRCtriplet(crc, next, -50);
847
215k
              FALLTHROUGH_INTENDED;
848
216k
            case 49:
849
216k
              CRCtriplet(crc, next, -49);
850
216k
              FALLTHROUGH_INTENDED;
851
218k
            case 48:
852
218k
              CRCtriplet(crc, next, -48);
853
218k
              FALLTHROUGH_INTENDED;
854
219k
            case 47:
855
219k
              CRCtriplet(crc, next, -47);
856
219k
              FALLTHROUGH_INTENDED;
857
220k
            case 46:
858
220k
              CRCtriplet(crc, next, -46);
859
220k
              FALLTHROUGH_INTENDED;
860
221k
            case 45:
861
221k
              CRCtriplet(crc, next, -45);
862
221k
              FALLTHROUGH_INTENDED;
863
224k
            case 44:
864
224k
              CRCtriplet(crc, next, -44);
865
224k
              FALLTHROUGH_INTENDED;
866
225k
            case 43:
867
225k
              CRCtriplet(crc, next, -43);
868
225k
              FALLTHROUGH_INTENDED;
869
226k
            case 42:
870
226k
              CRCtriplet(crc, next, -42);
871
226k
              FALLTHROUGH_INTENDED;
872
226k
            case 41:
873
226k
              CRCtriplet(crc, next, -41);
874
226k
              FALLTHROUGH_INTENDED;
875
228k
            case 40:
876
228k
              CRCtriplet(crc, next, -40);
877
228k
              FALLTHROUGH_INTENDED;
878
231k
            case 39:
879
231k
              CRCtriplet(crc, next, -39);
880
231k
              FALLTHROUGH_INTENDED;
881
232k
            case 38:
882
232k
              CRCtriplet(crc, next, -38);
883
232k
              FALLTHROUGH_INTENDED;
884
233k
            case 37:
885
233k
              CRCtriplet(crc, next, -37);
886
233k
              FALLTHROUGH_INTENDED;
887
235k
            case 36:
888
235k
              CRCtriplet(crc, next, -36);
889
235k
              FALLTHROUGH_INTENDED;
890
235k
            case 35:
891
235k
              CRCtriplet(crc, next, -35);
892
235k
              FALLTHROUGH_INTENDED;
893
237k
            case 34:
894
237k
              CRCtriplet(crc, next, -34);
895
237k
              FALLTHROUGH_INTENDED;
896
238k
            case 33:
897
238k
              CRCtriplet(crc, next, -33);
898
238k
              FALLTHROUGH_INTENDED;
899
239k
            case 32:
900
239k
              CRCtriplet(crc, next, -32);
901
239k
              FALLTHROUGH_INTENDED;
902
239k
            case 31:
903
239k
              CRCtriplet(crc, next, -31);
904
239k
              FALLTHROUGH_INTENDED;
905
241k
            case 30:
906
241k
              CRCtriplet(crc, next, -30);
907
241k
              FALLTHROUGH_INTENDED;
908
243k
            case 29:
909
243k
              CRCtriplet(crc, next, -29);
910
243k
              FALLTHROUGH_INTENDED;
911
244k
            case 28:
912
244k
              CRCtriplet(crc, next, -28);
913
244k
              FALLTHROUGH_INTENDED;
914
245k
            case 27:
915
245k
              CRCtriplet(crc, next, -27);
916
245k
              FALLTHROUGH_INTENDED;
917
246k
            case 26:
918
246k
              CRCtriplet(crc, next, -26);
919
246k
              FALLTHROUGH_INTENDED;
920
249k
            case 25:
921
249k
              CRCtriplet(crc, next, -25);
922
249k
              FALLTHROUGH_INTENDED;
923
250k
            case 24:
924
250k
              CRCtriplet(crc, next, -24);
925
250k
              FALLTHROUGH_INTENDED;
926
250k
            case 23:
927
250k
              CRCtriplet(crc, next, -23);
928
250k
              FALLTHROUGH_INTENDED;
929
252k
            case 22:
930
252k
              CRCtriplet(crc, next, -22);
931
252k
              FALLTHROUGH_INTENDED;
932
253k
            case 21:
933
253k
              CRCtriplet(crc, next, -21);
934
253k
              FALLTHROUGH_INTENDED;
935
256k
            case 20:
936
256k
              CRCtriplet(crc, next, -20);
937
256k
              FALLTHROUGH_INTENDED;
938
257k
            case 19:
939
257k
              CRCtriplet(crc, next, -19);
940
257k
              FALLTHROUGH_INTENDED;
941
262k
            case 18:
942
262k
              CRCtriplet(crc, next, -18);
943
262k
              FALLTHROUGH_INTENDED;
944
265k
            case 17:
945
265k
              CRCtriplet(crc, next, -17);
946
265k
              FALLTHROUGH_INTENDED;
947
266k
            case 16:
948
266k
              CRCtriplet(crc, next, -16);
949
266k
              FALLTHROUGH_INTENDED;
950
276k
            case 15:
951
276k
              CRCtriplet(crc, next, -15);
952
276k
              FALLTHROUGH_INTENDED;
953
285k
            case 14:
954
285k
              CRCtriplet(crc, next, -14);
955
285k
              FALLTHROUGH_INTENDED;
956
296k
            case 13:
957
296k
              CRCtriplet(crc, next, -13);
958
296k
              FALLTHROUGH_INTENDED;
959
299k
            case 12:
960
299k
              CRCtriplet(crc, next, -12);
961
299k
              FALLTHROUGH_INTENDED;
962
324k
            case 11:
963
324k
              CRCtriplet(crc, next, -11);
964
324k
              FALLTHROUGH_INTENDED;
965
373k
            case 10:
966
373k
              CRCtriplet(crc, next, -10);
967
373k
              FALLTHROUGH_INTENDED;
968
406k
            case 9:
969
406k
              CRCtriplet(crc, next, -9);
970
406k
              FALLTHROUGH_INTENDED;
971
408k
            case 8:
972
408k
              CRCtriplet(crc, next, -8);
973
408k
              FALLTHROUGH_INTENDED;
974
409k
            case 7:
975
409k
              CRCtriplet(crc, next, -7);
976
409k
              FALLTHROUGH_INTENDED;
977
410k
            case 6:
978
410k
              CRCtriplet(crc, next, -6);
979
410k
              FALLTHROUGH_INTENDED;
980
410k
            case 5:
981
410k
              CRCtriplet(crc, next, -5);
982
410k
              FALLTHROUGH_INTENDED;
983
411k
            case 4:
984
411k
              CRCtriplet(crc, next, -4);
985
411k
              FALLTHROUGH_INTENDED;
986
411k
            case 3:
987
411k
              CRCtriplet(crc, next, -3);
988
411k
              FALLTHROUGH_INTENDED;
989
411k
            case 2:
990
411k
              CRCtriplet(crc, next, -2);
991
411k
              FALLTHROUGH_INTENDED;
992
412k
            case 1:
993
412k
              CRCduplet(crc, next, -1); // the final triplet is actually only 2
994
              //{ CombineCRC(); }
995
412k
              crc0 = CombineCRC(block_size, crc0, crc1, crc2, next2);
996
412k
              if (--n > 0) {
997
153k
                crc1 = crc2 = 0;
998
153k
                block_size = 128;
999
                // points to the first byte of the next block
1000
153k
                next0 = next2 + 128;
1001
153k
                next1 = next0 + 128; // from here on all blocks are 128 long
1002
153k
                next2 = next1 + 128;
1003
153k
              }
1004
412k
              FALLTHROUGH_INTENDED;
1005
412k
            case 0:;
1006
412k
          } while (n > 0);
1007
258k
      }
1008
258k
      next = (const unsigned char*)next2;
1009
258k
    }
1010
2.76M
    uint64_t count2 = len >> 3; // 216 of less bytes is 27 or less singlets
1011
2.76M
    len = len & 7;
1012
2.76M
    next += (count2 * 8);
1013
2.76M
    switch (count2) {
1014
5.81k
      case 27:
1015
5.81k
        CRCsinglet(crc0, next, -27 * 8);
1016
5.81k
        FALLTHROUGH_INTENDED;
1017
31.4k
      case 26:
1018
31.4k
        CRCsinglet(crc0, next, -26 * 8);
1019
31.4k
        FALLTHROUGH_INTENDED;
1020
50.2k
      case 25:
1021
50.2k
        CRCsinglet(crc0, next, -25 * 8);
1022
50.2k
        FALLTHROUGH_INTENDED;
1023
59.2k
      case 24:
1024
59.2k
        CRCsinglet(crc0, next, -24 * 8);
1025
59.2k
        FALLTHROUGH_INTENDED;
1026
71.0k
      case 23:
1027
71.0k
        CRCsinglet(crc0, next, -23 * 8);
1028
71.0k
        FALLTHROUGH_INTENDED;
1029
89.5k
      case 22:
1030
89.5k
        CRCsinglet(crc0, next, -22 * 8);
1031
89.5k
        FALLTHROUGH_INTENDED;
1032
107k
      case 21:
1033
107k
        CRCsinglet(crc0, next, -21 * 8);
1034
107k
        FALLTHROUGH_INTENDED;
1035
112k
      case 20:
1036
112k
        CRCsinglet(crc0, next, -20 * 8);
1037
112k
        FALLTHROUGH_INTENDED;
1038
135k
      case 19:
1039
135k
        CRCsinglet(crc0, next, -19 * 8);
1040
135k
        FALLTHROUGH_INTENDED;
1041
144k
      case 18:
1042
144k
        CRCsinglet(crc0, next, -18 * 8);
1043
144k
        FALLTHROUGH_INTENDED;
1044
156k
      case 17:
1045
156k
        CRCsinglet(crc0, next, -17 * 8);
1046
156k
        FALLTHROUGH_INTENDED;
1047
170k
      case 16:
1048
170k
        CRCsinglet(crc0, next, -16 * 8);
1049
170k
        FALLTHROUGH_INTENDED;
1050
185k
      case 15:
1051
185k
        CRCsinglet(crc0, next, -15 * 8);
1052
185k
        FALLTHROUGH_INTENDED;
1053
202k
      case 14:
1054
202k
        CRCsinglet(crc0, next, -14 * 8);
1055
202k
        FALLTHROUGH_INTENDED;
1056
214k
      case 13:
1057
214k
        CRCsinglet(crc0, next, -13 * 8);
1058
214k
        FALLTHROUGH_INTENDED;
1059
228k
      case 12:
1060
228k
        CRCsinglet(crc0, next, -12 * 8);
1061
228k
        FALLTHROUGH_INTENDED;
1062
250k
      case 11:
1063
250k
        CRCsinglet(crc0, next, -11 * 8);
1064
250k
        FALLTHROUGH_INTENDED;
1065
278k
      case 10:
1066
278k
        CRCsinglet(crc0, next, -10 * 8);
1067
278k
        FALLTHROUGH_INTENDED;
1068
311k
      case 9:
1069
311k
        CRCsinglet(crc0, next, -9 * 8);
1070
311k
        FALLTHROUGH_INTENDED;
1071
328k
      case 8:
1072
328k
        CRCsinglet(crc0, next, -8 * 8);
1073
328k
        FALLTHROUGH_INTENDED;
1074
369k
      case 7:
1075
369k
        CRCsinglet(crc0, next, -7 * 8);
1076
369k
        FALLTHROUGH_INTENDED;
1077
408k
      case 6:
1078
408k
        CRCsinglet(crc0, next, -6 * 8);
1079
408k
        FALLTHROUGH_INTENDED;
1080
496k
      case 5:
1081
496k
        CRCsinglet(crc0, next, -5 * 8);
1082
496k
        FALLTHROUGH_INTENDED;
1083
595k
      case 4:
1084
595k
        CRCsinglet(crc0, next, -4 * 8);
1085
595k
        FALLTHROUGH_INTENDED;
1086
742k
      case 3:
1087
742k
        CRCsinglet(crc0, next, -3 * 8);
1088
742k
        FALLTHROUGH_INTENDED;
1089
1.91M
      case 2:
1090
1.91M
        CRCsinglet(crc0, next, -2 * 8);
1091
1.91M
        FALLTHROUGH_INTENDED;
1092
2.66M
      case 1:
1093
2.66M
        CRCsinglet(crc0, next, -1 * 8);
1094
2.66M
        FALLTHROUGH_INTENDED;
1095
2.76M
      case 0:;
1096
2.76M
    }
1097
2.76M
  }
1098
4.16M
  {
1099
4.16M
    align_to_8(len, crc0, next);
1100
4.16M
    return (uint32_t)crc0 ^ 0xffffffffu;
1101
4.16M
  }
1102
4.16M
}
1103
1104
#endif //__SSE4_2__ && __PCLMUL__
1105
1106
2
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
2
  (void)ExtendImpl<DefaultCRC32>; // suppress unused warning
1122
#ifdef _MSC_VER
1123
#pragma warning(default: 4551)
1124
#endif
1125
2
  return crc32c_3way;
1126
#else
1127
  return ExtendImpl<DefaultCRC32>;
1128
#endif
1129
2
}
1130
1131
static Function ChosenExtend = Choose_Extend();
1132
4.16M
uint32_t Extend(uint32_t crc, const char* buf, size_t size) {
1133
4.16M
  return ChosenExtend(crc, buf, size);
1134
4.16M
}
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
102M
    size_t i, uint32_t p, uint32_t a, uint32_t b, uint32_t m) {
1144
  // clang-format off
1145
102M
  return i == 32 ? p : gf_multiply_sw_1(
1146
99.4M
      /* i = */ i + 1,
1147
99.4M
      /* p = */ p ^ ((0u-((b >> 31) & 1)) & a),
1148
99.4M
      /* a = */ (a >> 1) ^ ((0u-(a & 1)) & m),
1149
99.4M
      /* b = */ b << 1,
1150
99.4M
      /* m = */ m);
1151
  // clang-format on
1152
102M
}
1153
3.10M
static constexpr uint32_t gf_multiply_sw(uint32_t a, uint32_t b, uint32_t m) {
1154
3.10M
  return gf_multiply_sw_1(/* i = */ 0, /* p = */ 0, a, b, m);
1155
3.10M
}
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.42M
    std::array<uint32_t, 62> const& powers_array) {
1206
1.42M
  auto powers = powers_array.data();
1207
  // Append by multiplying by consecutive powers of two of the zeroes
1208
  // array
1209
1.42M
  size_t len_bits = len_over_4;
1210
1211
4.52M
  while (len_bits) {
1212
    // Advance directly to next bit set.
1213
3.10M
    auto r = CountTrailingZeroBits(len_bits);
1214
3.10M
    len_bits >>= r;
1215
3.10M
    powers += r;
1216
1217
3.10M
    crc = gf_multiply_sw(crc, *powers, polynomial);
1218
1219
3.10M
    len_bits >>= 1;
1220
3.10M
    powers++;
1221
3.10M
  }
1222
1223
1.42M
  return crc;
1224
1.42M
}
1225
1226
3.92M
static inline uint32_t InvertedToPure(uint32_t crc) { return ~crc; }
1227
1228
2.50M
static inline uint32_t PureToInverted(uint32_t crc) { return ~crc; }
1229
1230
1.07M
static inline uint32_t PureExtend(uint32_t crc, const char* buf, size_t size) {
1231
1.07M
  return InvertedToPure(Extend(PureToInverted(crc), buf, size));
1232
1.07M
}
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.42M
uint32_t Crc32cCombine(uint32_t crc1, uint32_t crc2, size_t crc2len) {
1279
1.42M
  uint32_t pure_crc1_with_init = InvertedToPure(crc1);
1280
1.42M
  uint32_t pure_crc2_with_init = InvertedToPure(crc2);
1281
1.42M
  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.42M
  char zeros[4] = {0, 0, 0, 0};
1285
1.42M
  auto len = crc2len & 3;
1286
1.42M
  uint32_t tmp = pure_crc1_with_init ^ pure_crc2_init;
1287
1.42M
  if (len) {
1288
1.07M
    tmp = PureExtend(tmp, zeros, len);
1289
1.07M
  }
1290
1.42M
  return PureToInverted(
1291
1.42M
      Crc32AppendZeroes(tmp, crc2len / 4, crc32c_m, crc32c_powers) ^
1292
1.42M
      pure_crc2_with_init);
1293
1.42M
}
1294
1295
}  // namespace ROCKSDB_NAMESPACE::crc32c