// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
// This source code is licensed under both the GPLv2 (found in the
// COPYING file in the root directory) and Apache 2.0 License
// (found in the LICENSE.Apache file in the root directory).
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
//
// A portable implementation of crc32c, optimized to handle
// four bytes at a time.
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <stddef.h>
#include <stdint.h>
#include <my_global.h>
#ifdef __powerpc64__
# include "crc32c_ppc.h"
# ifdef __linux__
# include <sys/auxv.h>
# ifndef PPC_FEATURE2_VEC_CRYPTO
# define PPC_FEATURE2_VEC_CRYPTO 0 x02000000
# endif
# ifndef AT_HWCAP2
# define AT_HWCAP2 26
# endif
# endif
#endif
typedef unsigned (*my_crc32_t)(unsigned , const void *, size_t);
namespace mysys_namespace {
namespace crc32c {
#if defined (HAVE_POWER8) && defined (HAS_ALTIVEC)
#ifdef __powerpc64__
static int arch_ppc_crc32 = 0 ;
#endif /* __powerpc64__ */
#endif
alignas(CPU_LEVEL1_DCACHE_LINESIZE)
static const uint32_t table0_[256 ] = {
0 x00000000, 0 xf26b8303, 0 xe13b70f7, 0 x1350f3f4,
0 xc79a971f, 0 x35f1141c, 0 x26a1e7e8, 0 xd4ca64eb,
0 x8ad958cf, 0 x78b2dbcc, 0 x6be22838, 0 x9989ab3b,
0 x4d43cfd0, 0 xbf284cd3, 0 xac78bf27, 0 x5e133c24,
0 x105ec76f, 0 xe235446c, 0 xf165b798, 0 x030e349b,
0 xd7c45070, 0 x25afd373, 0 x36ff2087, 0 xc494a384,
0 x9a879fa0, 0 x68ec1ca3, 0 x7bbcef57, 0 x89d76c54,
0 x5d1d08bf, 0 xaf768bbc, 0 xbc267848, 0 x4e4dfb4b,
0 x20bd8ede, 0 xd2d60ddd, 0 xc186fe29, 0 x33ed7d2a,
0 xe72719c1, 0 x154c9ac2, 0 x061c6936, 0 xf477ea35,
0 xaa64d611, 0 x580f5512, 0 x4b5fa6e6, 0 xb93425e5,
0 x6dfe410e, 0 x9f95c20d, 0 x8cc531f9, 0 x7eaeb2fa,
0 x30e349b1, 0 xc288cab2, 0 xd1d83946, 0 x23b3ba45,
0 xf779deae, 0 x05125dad, 0 x1642ae59, 0 xe4292d5a,
0 xba3a117e, 0 x4851927d, 0 x5b016189, 0 xa96ae28a,
0 x7da08661, 0 x8fcb0562, 0 x9c9bf696, 0 x6ef07595,
0 x417b1dbc, 0 xb3109ebf, 0 xa0406d4b, 0 x522bee48,
0 x86e18aa3, 0 x748a09a0, 0 x67dafa54, 0 x95b17957,
0 xcba24573, 0 x39c9c670, 0 x2a993584, 0 xd8f2b687,
0 x0c38d26c, 0 xfe53516f, 0 xed03a29b, 0 x1f682198,
0 x5125dad3, 0 xa34e59d0, 0 xb01eaa24, 0 x42752927,
0 x96bf4dcc, 0 x64d4cecf, 0 x77843d3b, 0 x85efbe38,
0 xdbfc821c, 0 x2997011f, 0 x3ac7f2eb, 0 xc8ac71e8,
0 x1c661503, 0 xee0d9600, 0 xfd5d65f4, 0 x0f36e6f7,
0 x61c69362, 0 x93ad1061, 0 x80fde395, 0 x72966096,
0 xa65c047d, 0 x5437877e, 0 x4767748a, 0 xb50cf789,
0 xeb1fcbad, 0 x197448ae, 0 x0a24bb5a, 0 xf84f3859,
0 x2c855cb2, 0 xdeeedfb1, 0 xcdbe2c45, 0 x3fd5af46,
0 x7198540d, 0 x83f3d70e, 0 x90a324fa, 0 x62c8a7f9,
0 xb602c312, 0 x44694011, 0 x5739b3e5, 0 xa55230e6,
0 xfb410cc2, 0 x092a8fc1, 0 x1a7a7c35, 0 xe811ff36,
0 x3cdb9bdd, 0 xceb018de, 0 xdde0eb2a, 0 x2f8b6829,
0 x82f63b78, 0 x709db87b, 0 x63cd4b8f, 0 x91a6c88c,
0 x456cac67, 0 xb7072f64, 0 xa457dc90, 0 x563c5f93,
0 x082f63b7, 0 xfa44e0b4, 0 xe9141340, 0 x1b7f9043,
0 xcfb5f4a8, 0 x3dde77ab, 0 x2e8e845f, 0 xdce5075c,
0 x92a8fc17, 0 x60c37f14, 0 x73938ce0, 0 x81f80fe3,
0 x55326b08, 0 xa759e80b, 0 xb4091bff, 0 x466298fc,
0 x1871a4d8, 0 xea1a27db, 0 xf94ad42f, 0 x0b21572c,
0 xdfeb33c7, 0 x2d80b0c4, 0 x3ed04330, 0 xccbbc033,
0 xa24bb5a6, 0 x502036a5, 0 x4370c551, 0 xb11b4652,
0 x65d122b9, 0 x97baa1ba, 0 x84ea524e, 0 x7681d14d,
0 x2892ed69, 0 xdaf96e6a, 0 xc9a99d9e, 0 x3bc21e9d,
0 xef087a76, 0 x1d63f975, 0 x0e330a81, 0 xfc588982,
0 xb21572c9, 0 x407ef1ca, 0 x532e023e, 0 xa145813d,
0 x758fe5d6, 0 x87e466d5, 0 x94b49521, 0 x66df1622,
0 x38cc2a06, 0 xcaa7a905, 0 xd9f75af1, 0 x2b9cd9f2,
0 xff56bd19, 0 x0d3d3e1a, 0 x1e6dcdee, 0 xec064eed,
0 xc38d26c4, 0 x31e6a5c7, 0 x22b65633, 0 xd0ddd530,
0 x0417b1db, 0 xf67c32d8, 0 xe52cc12c, 0 x1747422f,
0 x49547e0b, 0 xbb3ffd08, 0 xa86f0efc, 0 x5a048dff,
0 x8ecee914, 0 x7ca56a17, 0 x6ff599e3, 0 x9d9e1ae0,
0 xd3d3e1ab, 0 x21b862a8, 0 x32e8915c, 0 xc083125f,
0 x144976b4, 0 xe622f5b7, 0 xf5720643, 0 x07198540,
0 x590ab964, 0 xab613a67, 0 xb831c993, 0 x4a5a4a90,
0 x9e902e7b, 0 x6cfbad78, 0 x7fab5e8c, 0 x8dc0dd8f,
0 xe330a81a, 0 x115b2b19, 0 x020bd8ed, 0 xf0605bee,
0 x24aa3f05, 0 xd6c1bc06, 0 xc5914ff2, 0 x37faccf1,
0 x69e9f0d5, 0 x9b8273d6, 0 x88d28022, 0 x7ab90321,
0 xae7367ca, 0 x5c18e4c9, 0 x4f48173d, 0 xbd23943e,
0 xf36e6f75, 0 x0105ec76, 0 x12551f82, 0 xe03e9c81,
0 x34f4f86a, 0 xc69f7b69, 0 xd5cf889d, 0 x27a40b9e,
0 x79b737ba, 0 x8bdcb4b9, 0 x988c474d, 0 x6ae7c44e,
0 xbe2da0a5, 0 x4c4623a6, 0 x5f16d052, 0 xad7d5351
};
static const uint32_t table1_[256 ] = {
0 x00000000, 0 x13a29877, 0 x274530ee, 0 x34e7a899,
0 x4e8a61dc, 0 x5d28f9ab, 0 x69cf5132, 0 x7a6dc945,
0 x9d14c3b8, 0 x8eb65bcf, 0 xba51f356, 0 xa9f36b21,
0 xd39ea264, 0 xc03c3a13, 0 xf4db928a, 0 xe7790afd,
0 x3fc5f181, 0 x2c6769f6, 0 x1880c16f, 0 x0b225918,
0 x714f905d, 0 x62ed082a, 0 x560aa0b3, 0 x45a838c4,
0 xa2d13239, 0 xb173aa4e, 0 x859402d7, 0 x96369aa0,
0 xec5b53e5, 0 xfff9cb92, 0 xcb1e630b, 0 xd8bcfb7c,
0 x7f8be302, 0 x6c297b75, 0 x58ced3ec, 0 x4b6c4b9b,
0 x310182de, 0 x22a31aa9, 0 x1644b230, 0 x05e62a47,
0 xe29f20ba, 0 xf13db8cd, 0 xc5da1054, 0 xd6788823,
0 xac154166, 0 xbfb7d911, 0 x8b507188, 0 x98f2e9ff,
0 x404e1283, 0 x53ec8af4, 0 x670b226d, 0 x74a9ba1a,
0 x0ec4735f, 0 x1d66eb28, 0 x298143b1, 0 x3a23dbc6,
0 xdd5ad13b, 0 xcef8494c, 0 xfa1fe1d5, 0 xe9bd79a2,
0 x93d0b0e7, 0 x80722890, 0 xb4958009, 0 xa737187e,
0 xff17c604, 0 xecb55e73, 0 xd852f6ea, 0 xcbf06e9d,
0 xb19da7d8, 0 xa23f3faf, 0 x96d89736, 0 x857a0f41,
0 x620305bc, 0 x71a19dcb, 0 x45463552, 0 x56e4ad25,
0 x2c896460, 0 x3f2bfc17, 0 x0bcc548e, 0 x186eccf9,
0 xc0d23785, 0 xd370aff2, 0 xe797076b, 0 xf4359f1c,
0 x8e585659, 0 x9dface2e, 0 xa91d66b7, 0 xbabffec0,
0 x5dc6f43d, 0 x4e646c4a, 0 x7a83c4d3, 0 x69215ca4,
0 x134c95e1, 0 x00ee0d96, 0 x3409a50f, 0 x27ab3d78,
0 x809c2506, 0 x933ebd71, 0 xa7d915e8, 0 xb47b8d9f,
0 xce1644da, 0 xddb4dcad, 0 xe9537434, 0 xfaf1ec43,
0 x1d88e6be, 0 x0e2a7ec9, 0 x3acdd650, 0 x296f4e27,
0 x53028762, 0 x40a01f15, 0 x7447b78c, 0 x67e52ffb,
0 xbf59d487, 0 xacfb4cf0, 0 x981ce469, 0 x8bbe7c1e,
0 xf1d3b55b, 0 xe2712d2c, 0 xd69685b5, 0 xc5341dc2,
0 x224d173f, 0 x31ef8f48, 0 x050827d1, 0 x16aabfa6,
0 x6cc776e3, 0 x7f65ee94, 0 x4b82460d, 0 x5820de7a,
0 xfbc3faf9, 0 xe861628e, 0 xdc86ca17, 0 xcf245260,
0 xb5499b25, 0 xa6eb0352, 0 x920cabcb, 0 x81ae33bc,
0 x66d73941, 0 x7575a136, 0 x419209af, 0 x523091d8,
0 x285d589d, 0 x3bffc0ea, 0 x0f186873, 0 x1cbaf004,
0 xc4060b78, 0 xd7a4930f, 0 xe3433b96, 0 xf0e1a3e1,
0 x8a8c6aa4, 0 x992ef2d3, 0 xadc95a4a, 0 xbe6bc23d,
0 x5912c8c0, 0 x4ab050b7, 0 x7e57f82e, 0 x6df56059,
0 x1798a91c, 0 x043a316b, 0 x30dd99f2, 0 x237f0185,
0 x844819fb, 0 x97ea818c, 0 xa30d2915, 0 xb0afb162,
0 xcac27827, 0 xd960e050, 0 xed8748c9, 0 xfe25d0be,
0 x195cda43, 0 x0afe4234, 0 x3e19eaad, 0 x2dbb72da,
0 x57d6bb9f, 0 x447423e8, 0 x70938b71, 0 x63311306,
0 xbb8de87a, 0 xa82f700d, 0 x9cc8d894, 0 x8f6a40e3,
0 xf50789a6, 0 xe6a511d1, 0 xd242b948, 0 xc1e0213f,
0 x26992bc2, 0 x353bb3b5, 0 x01dc1b2c, 0 x127e835b,
0 x68134a1e, 0 x7bb1d269, 0 x4f567af0, 0 x5cf4e287,
0 x04d43cfd, 0 x1776a48a, 0 x23910c13, 0 x30339464,
0 x4a5e5d21, 0 x59fcc556, 0 x6d1b6dcf, 0 x7eb9f5b8,
0 x99c0ff45, 0 x8a626732, 0 xbe85cfab, 0 xad2757dc,
0 xd74a9e99, 0 xc4e806ee, 0 xf00fae77, 0 xe3ad3600,
0 x3b11cd7c, 0 x28b3550b, 0 x1c54fd92, 0 x0ff665e5,
0 x759baca0, 0 x663934d7, 0 x52de9c4e, 0 x417c0439,
0 xa6050ec4, 0 xb5a796b3, 0 x81403e2a, 0 x92e2a65d,
0 xe88f6f18, 0 xfb2df76f, 0 xcfca5ff6, 0 xdc68c781,
0 x7b5fdfff, 0 x68fd4788, 0 x5c1aef11, 0 x4fb87766,
0 x35d5be23, 0 x26772654, 0 x12908ecd, 0 x013216ba,
0 xe64b1c47, 0 xf5e98430, 0 xc10e2ca9, 0 xd2acb4de,
0 xa8c17d9b, 0 xbb63e5ec, 0 x8f844d75, 0 x9c26d502,
0 x449a2e7e, 0 x5738b609, 0 x63df1e90, 0 x707d86e7,
0 x0a104fa2, 0 x19b2d7d5, 0 x2d557f4c, 0 x3ef7e73b,
0 xd98eedc6, 0 xca2c75b1, 0 xfecbdd28, 0 xed69455f,
0 x97048c1a, 0 x84a6146d, 0 xb041bcf4, 0 xa3e32483
};
static const uint32_t table2_[256 ] = {
0 x00000000, 0 xa541927e, 0 x4f6f520d, 0 xea2ec073,
0 x9edea41a, 0 x3b9f3664, 0 xd1b1f617, 0 x74f06469,
0 x38513ec5, 0 x9d10acbb, 0 x773e6cc8, 0 xd27ffeb6,
0 xa68f9adf, 0 x03ce08a1, 0 xe9e0c8d2, 0 x4ca15aac,
0 x70a27d8a, 0 xd5e3eff4, 0 x3fcd2f87, 0 x9a8cbdf9,
0 xee7cd990, 0 x4b3d4bee, 0 xa1138b9d, 0 x045219e3,
0 x48f3434f, 0 xedb2d131, 0 x079c1142, 0 xa2dd833c,
0 xd62de755, 0 x736c752b, 0 x9942b558, 0 x3c032726,
0 xe144fb14, 0 x4405696a, 0 xae2ba919, 0 x0b6a3b67,
0 x7f9a5f0e, 0 xdadbcd70, 0 x30f50d03, 0 x95b49f7d,
0 xd915c5d1, 0 x7c5457af, 0 x967a97dc, 0 x333b05a2,
0 x47cb61cb, 0 xe28af3b5, 0 x08a433c6, 0 xade5a1b8,
0 x91e6869e, 0 x34a714e0, 0 xde89d493, 0 x7bc846ed,
0 x0f382284, 0 xaa79b0fa, 0 x40577089, 0 xe516e2f7,
0 xa9b7b85b, 0 x0cf62a25, 0 xe6d8ea56, 0 x43997828,
0 x37691c41, 0 x92288e3f, 0 x78064e4c, 0 xdd47dc32,
0 xc76580d9, 0 x622412a7, 0 x880ad2d4, 0 x2d4b40aa,
0 x59bb24c3, 0 xfcfab6bd, 0 x16d476ce, 0 xb395e4b0,
0 xff34be1c, 0 x5a752c62, 0 xb05bec11, 0 x151a7e6f,
0 x61ea1a06, 0 xc4ab8878, 0 x2e85480b, 0 x8bc4da75,
0 xb7c7fd53, 0 x12866f2d, 0 xf8a8af5e, 0 x5de93d20,
0 x29195949, 0 x8c58cb37, 0 x66760b44, 0 xc337993a,
0 x8f96c396, 0 x2ad751e8, 0 xc0f9919b, 0 x65b803e5,
0 x1148678c, 0 xb409f5f2, 0 x5e273581, 0 xfb66a7ff,
0 x26217bcd, 0 x8360e9b3, 0 x694e29c0, 0 xcc0fbbbe,
0 xb8ffdfd7, 0 x1dbe4da9, 0 xf7908dda, 0 x52d11fa4,
0 x1e704508, 0 xbb31d776, 0 x511f1705, 0 xf45e857b,
0 x80aee112, 0 x25ef736c, 0 xcfc1b31f, 0 x6a802161,
0 x56830647, 0 xf3c29439, 0 x19ec544a, 0 xbcadc634,
0 xc85da25d, 0 x6d1c3023, 0 x8732f050, 0 x2273622e,
0 x6ed23882, 0 xcb93aafc, 0 x21bd6a8f, 0 x84fcf8f1,
0 xf00c9c98, 0 x554d0ee6, 0 xbf63ce95, 0 x1a225ceb,
0 x8b277743, 0 x2e66e53d, 0 xc448254e, 0 x6109b730,
0 x15f9d359, 0 xb0b84127, 0 x5a968154, 0 xffd7132a,
0 xb3764986, 0 x1637dbf8, 0 xfc191b8b, 0 x595889f5,
0 x2da8ed9c, 0 x88e97fe2, 0 x62c7bf91, 0 xc7862def,
0 xfb850ac9, 0 x5ec498b7, 0 xb4ea58c4, 0 x11abcaba,
0 x655baed3, 0 xc01a3cad, 0 x2a34fcde, 0 x8f756ea0,
0 xc3d4340c, 0 x6695a672, 0 x8cbb6601, 0 x29faf47f,
0 x5d0a9016, 0 xf84b0268, 0 x1265c21b, 0 xb7245065,
0 x6a638c57, 0 xcf221e29, 0 x250cde5a, 0 x804d4c24,
0 xf4bd284d, 0 x51fcba33, 0 xbbd27a40, 0 x1e93e83e,
0 x5232b292, 0 xf77320ec, 0 x1d5de09f, 0 xb81c72e1,
0 xccec1688, 0 x69ad84f6, 0 x83834485, 0 x26c2d6fb,
0 x1ac1f1dd, 0 xbf8063a3, 0 x55aea3d0, 0 xf0ef31ae,
0 x841f55c7, 0 x215ec7b9, 0 xcb7007ca, 0 x6e3195b4,
0 x2290cf18, 0 x87d15d66, 0 x6dff9d15, 0 xc8be0f6b,
0 xbc4e6b02, 0 x190ff97c, 0 xf321390f, 0 x5660ab71,
0 x4c42f79a, 0 xe90365e4, 0 x032da597, 0 xa66c37e9,
0 xd29c5380, 0 x77ddc1fe, 0 x9df3018d, 0 x38b293f3,
0 x7413c95f, 0 xd1525b21, 0 x3b7c9b52, 0 x9e3d092c,
0 xeacd6d45, 0 x4f8cff3b, 0 xa5a23f48, 0 x00e3ad36,
0 x3ce08a10, 0 x99a1186e, 0 x738fd81d, 0 xd6ce4a63,
0 xa23e2e0a, 0 x077fbc74, 0 xed517c07, 0 x4810ee79,
0 x04b1b4d5, 0 xa1f026ab, 0 x4bdee6d8, 0 xee9f74a6,
0 x9a6f10cf, 0 x3f2e82b1, 0 xd50042c2, 0 x7041d0bc,
0 xad060c8e, 0 x08479ef0, 0 xe2695e83, 0 x4728ccfd,
0 x33d8a894, 0 x96993aea, 0 x7cb7fa99, 0 xd9f668e7,
0 x9557324b, 0 x3016a035, 0 xda386046, 0 x7f79f238,
0 x0b899651, 0 xaec8042f, 0 x44e6c45c, 0 xe1a75622,
0 xdda47104, 0 x78e5e37a, 0 x92cb2309, 0 x378ab177,
0 x437ad51e, 0 xe63b4760, 0 x0c158713, 0 xa954156d,
0 xe5f54fc1, 0 x40b4ddbf, 0 xaa9a1dcc, 0 x0fdb8fb2,
0 x7b2bebdb, 0 xde6a79a5, 0 x3444b9d6, 0 x91052ba8
};
static const uint32_t table3_[256 ] = {
0 x00000000, 0 xdd45aab8, 0 xbf672381, 0 x62228939,
0 x7b2231f3, 0 xa6679b4b, 0 xc4451272, 0 x1900b8ca,
0 xf64463e6, 0 x2b01c95e, 0 x49234067, 0 x9466eadf,
0 x8d665215, 0 x5023f8ad, 0 x32017194, 0 xef44db2c,
0 xe964b13d, 0 x34211b85, 0 x560392bc, 0 x8b463804,
0 x924680ce, 0 x4f032a76, 0 x2d21a34f, 0 xf06409f7,
0 x1f20d2db, 0 xc2657863, 0 xa047f15a, 0 x7d025be2,
0 x6402e328, 0 xb9474990, 0 xdb65c0a9, 0 x06206a11,
0 xd725148b, 0 x0a60be33, 0 x6842370a, 0 xb5079db2,
0 xac072578, 0 x71428fc0, 0 x136006f9, 0 xce25ac41,
0 x2161776d, 0 xfc24ddd5, 0 x9e0654ec, 0 x4343fe54,
0 x5a43469e, 0 x8706ec26, 0 xe524651f, 0 x3861cfa7,
0 x3e41a5b6, 0 xe3040f0e, 0 x81268637, 0 x5c632c8f,
0 x45639445, 0 x98263efd, 0 xfa04b7c4, 0 x27411d7c,
0 xc805c650, 0 x15406ce8, 0 x7762e5d1, 0 xaa274f69,
0 xb327f7a3, 0 x6e625d1b, 0 x0c40d422, 0 xd1057e9a,
0 xaba65fe7, 0 x76e3f55f, 0 x14c17c66, 0 xc984d6de,
0 xd0846e14, 0 x0dc1c4ac, 0 x6fe34d95, 0 xb2a6e72d,
0 x5de23c01, 0 x80a796b9, 0 xe2851f80, 0 x3fc0b538,
0 x26c00df2, 0 xfb85a74a, 0 x99a72e73, 0 x44e284cb,
0 x42c2eeda, 0 x9f874462, 0 xfda5cd5b, 0 x20e067e3,
0 x39e0df29, 0 xe4a57591, 0 x8687fca8, 0 x5bc25610,
0 xb4868d3c, 0 x69c32784, 0 x0be1aebd, 0 xd6a40405,
0 xcfa4bccf, 0 x12e11677, 0 x70c39f4e, 0 xad8635f6,
0 x7c834b6c, 0 xa1c6e1d4, 0 xc3e468ed, 0 x1ea1c255,
0 x07a17a9f, 0 xdae4d027, 0 xb8c6591e, 0 x6583f3a6,
0 x8ac7288a, 0 x57828232, 0 x35a00b0b, 0 xe8e5a1b3,
0 xf1e51979, 0 x2ca0b3c1, 0 x4e823af8, 0 x93c79040,
0 x95e7fa51, 0 x48a250e9, 0 x2a80d9d0, 0 xf7c57368,
0 xeec5cba2, 0 x3380611a, 0 x51a2e823, 0 x8ce7429b,
0 x63a399b7, 0 xbee6330f, 0 xdcc4ba36, 0 x0181108e,
0 x1881a844, 0 xc5c402fc, 0 xa7e68bc5, 0 x7aa3217d,
0 x52a0c93f, 0 x8fe56387, 0 xedc7eabe, 0 x30824006,
0 x2982f8cc, 0 xf4c75274, 0 x96e5db4d, 0 x4ba071f5,
0 xa4e4aad9, 0 x79a10061, 0 x1b838958, 0 xc6c623e0,
0 xdfc69b2a, 0 x02833192, 0 x60a1b8ab, 0 xbde41213,
0 xbbc47802, 0 x6681d2ba, 0 x04a35b83, 0 xd9e6f13b,
0 xc0e649f1, 0 x1da3e349, 0 x7f816a70, 0 xa2c4c0c8,
0 x4d801be4, 0 x90c5b15c, 0 xf2e73865, 0 x2fa292dd,
0 x36a22a17, 0 xebe780af, 0 x89c50996, 0 x5480a32e,
0 x8585ddb4, 0 x58c0770c, 0 x3ae2fe35, 0 xe7a7548d,
0 xfea7ec47, 0 x23e246ff, 0 x41c0cfc6, 0 x9c85657e,
0 x73c1be52, 0 xae8414ea, 0 xcca69dd3, 0 x11e3376b,
0 x08e38fa1, 0 xd5a62519, 0 xb784ac20, 0 x6ac10698,
0 x6ce16c89, 0 xb1a4c631, 0 xd3864f08, 0 x0ec3e5b0,
0 x17c35d7a, 0 xca86f7c2, 0 xa8a47efb, 0 x75e1d443,
0 x9aa50f6f, 0 x47e0a5d7, 0 x25c22cee, 0 xf8878656,
0 xe1873e9c, 0 x3cc29424, 0 x5ee01d1d, 0 x83a5b7a5,
0 xf90696d8, 0 x24433c60, 0 x4661b559, 0 x9b241fe1,
0 x8224a72b, 0 x5f610d93, 0 x3d4384aa, 0 xe0062e12,
0 x0f42f53e, 0 xd2075f86, 0 xb025d6bf, 0 x6d607c07,
0 x7460c4cd, 0 xa9256e75, 0 xcb07e74c, 0 x16424df4,
0 x106227e5, 0 xcd278d5d, 0 xaf050464, 0 x7240aedc,
0 x6b401616, 0 xb605bcae, 0 xd4273597, 0 x09629f2f,
0 xe6264403, 0 x3b63eebb, 0 x59416782, 0 x8404cd3a,
0 x9d0475f0, 0 x4041df48, 0 x22635671, 0 xff26fcc9,
0 x2e238253, 0 xf36628eb, 0 x9144a1d2, 0 x4c010b6a,
0 x5501b3a0, 0 x88441918, 0 xea669021, 0 x37233a99,
0 xd867e1b5, 0 x05224b0d, 0 x6700c234, 0 xba45688c,
0 xa345d046, 0 x7e007afe, 0 x1c22f3c7, 0 xc167597f,
0 xc747336e, 0 x1a0299d6, 0 x782010ef, 0 xa565ba57,
0 xbc65029d, 0 x6120a825, 0 x0302211c, 0 xde478ba4,
0 x31035088, 0 xec46fa30, 0 x8e647309, 0 x5321d9b1,
0 x4a21617b, 0 x9764cbc3, 0 xf54642fa, 0 x2803e842
};
// Used to fetch a naturally-aligned 32-bit word in little endian byte-order
static inline uint32_t LE_LOAD32(const uint8_t *p)
{
return uint4korr(reinterpret_cast <const char *>(p));
}
static inline void Slow_CRC32(uint64_t* l, uint8_t const **p)
{
uint32_t c = static_cast <uint32_t>(*l ^ LE_LOAD32(*p));
*p += 4 ;
*l = table3_[c & 0 xff] ^
table2_[(c >> 8 ) & 0 xff] ^
table1_[(c >> 16 ) & 0 xff] ^
table0_[c >> 24 ];
// DO it twice.
c = static_cast <uint32_t>(*l ^ LE_LOAD32(*p));
*p += 4 ;
*l = table3_[c & 0 xff] ^
table2_[(c >> 8 ) & 0 xff] ^
table1_[(c >> 16 ) & 0 xff] ^
table0_[c >> 24 ];
}
#undef ALIGN
// Align n to (1 << m) byte boundary
#define ALIGN(n, m) ((n + ((1 << m) - 1 )) & ~((1 << m) - 1 ))
#define STEP1 do { \
int c = (l & 0 xff) ^ *p++; \
l = table0_[c] ^ (l >> 8 ); \
} while (0 )
#undef USE_SSE42
#if defined _MSC_VER && (defined _M_X64 || defined _M_IX86)
# include <intrin.h>
# include <immintrin.h>
# define USE_SSE42 /* nothing */
#elif defined __GNUC__ && (defined __i386__||defined __x86_64__)
# if __GNUC__ < 5 && !defined __clang_major__
/* the headers do not really work in GCC before version 5 */
# define _mm_crc32_u8(crc,data) __builtin_ia32_crc32qi(crc,data)
# define _mm_crc32_u32(crc,data) __builtin_ia32_crc32si(crc,data)
# define _mm_crc32_u64(crc,data) __builtin_ia32_crc32di(crc,data)
# else
# include <nmmintrin.h>
# endif
# define USE_SSE42 __attribute__((target("sse4.2" )))
#endif
#ifdef USE_SSE42
# if SIZEOF_SIZE_T == 8
static inline uint64_t LE_LOAD64(const uint8_t *ptr)
{
return uint8korr(reinterpret_cast <const char *>(ptr));
}
# endif
USE_SSE42
static inline void Fast_CRC32(uint64_t* l, uint8_t const **p)
{
# if (SIZEOF_SIZE_T == 8 )
*l = _mm_crc32_u64(*l, LE_LOAD64(*p));
*p += 8 ;
# else
*l = _mm_crc32_u32(static_cast <unsigned int >(*l), LE_LOAD32(*p));
*p += 4 ;
*l = _mm_crc32_u32(static_cast <unsigned int >(*l), LE_LOAD32(*p));
*p += 4 ;
# endif
}
extern "C"
USE_SSE42
unsigned crc32c_sse42(unsigned crc, const void * buf, size_t size)
{
const uint8_t *p = static_cast <const uint8_t *>(buf);
const uint8_t *e = p + size;
uint64_t l = crc ^ 0 xffffffffu;
// Point x at first 16-byte aligned byte in string. This might be
// just past the end of the string.
const uintptr_t pval = reinterpret_cast <uintptr_t>(p);
const uint8_t* x = reinterpret_cast <const uint8_t*>(ALIGN(pval, 4 ));
if (x <= e)
// Process bytes until finished or p is 16-byte aligned
while (p != x)
STEP1;
// Process bytes 16 at a time
while ((e-p) >= 16 )
{
Fast_CRC32(&l, &p);
Fast_CRC32(&l, &p);
}
// Process bytes 8 at a time
while ((e-p) >= 8 )
Fast_CRC32(&l, &p);
// Process the last few bytes
while (p != e)
STEP1;
return static_cast <uint32_t>(l ^ 0 xffffffffu);
}
#endif
static unsigned crc32c_slow(unsigned crc, const void * buf, size_t size)
{
const uint8_t *p = static_cast <const uint8_t *>(buf);
const uint8_t *e = p + size;
uint64_t l = crc ^ 0 xffffffffu;
// Point x at first 16-byte aligned byte in string. This might be
// just past the end of the string.
const uintptr_t pval = reinterpret_cast <uintptr_t>(p);
const uint8_t* x = reinterpret_cast <const uint8_t*>(ALIGN(pval, 4 ));
if (x <= e)
// Process bytes until finished or p is 16-byte aligned
while (p != x)
STEP1;
// Process bytes 16 at a time
while ((e-p) >= 16 )
{
Slow_CRC32(&l, &p);
Slow_CRC32(&l, &p);
}
// Process bytes 8 at a time
while ((e-p) >= 8 )
Slow_CRC32(&l, &p);
// Process the last few bytes
while (p != e)
STEP1;
return static_cast <uint32_t>(l ^ 0 xffffffffu);
}
#if defined (HAVE_POWER8) && defined (HAS_ALTIVEC)
# ifdef __linux__
static int arch_ppc_probe(void ) {
arch_ppc_crc32 = 0 ;
# if defined (__powerpc64__)
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_VEC_CRYPTO) arch_ppc_crc32 = 1 ;
# endif /* __powerpc64__ */
return arch_ppc_crc32;
}
# elif defined (__FreeBSD__) || defined (__OpenBSD__)
# include <sys/auxv.h>
# ifdef __FreeBSD__
# include <machine/cpu.h>
# include <sys/elf_common.h>
# endif
static int arch_ppc_probe(void ) {
unsigned long cpufeatures;
arch_ppc_crc32 = 0 ;
# if defined (__powerpc64__)
elf_aux_info(AT_HWCAP2, &cpufeatures, sizeof (cpufeatures));
if (cpufeatures & PPC_FEATURE2_HAS_VEC_CRYPTO) arch_ppc_crc32 = 1 ;
# endif /* __powerpc64__ */
return arch_ppc_crc32;
}
# elif defined (_AIX)
static int arch_ppc_probe(void ) {
arch_ppc_crc32 = 0 ;
# if defined (__powerpc64__)
// AIX 7.1+ has vector crypto features on all POWER 8+
arch_ppc_crc32 = 1 ;
# endif /* __powerpc64__ */
return arch_ppc_crc32;
}
# endif
#endif
#if defined (HAVE_ARMV8_CRC)
extern "C" my_crc32_t crc32c_aarch64_available(void );
extern "C" const char *crc32c_aarch64_impl(my_crc32_t);
#elif defined HAVE_RISCV_ZBC
extern "C" unsigned crc32c_riscv_zbc(unsigned , const void *, size_t);
# ifdef HAVE_RISCV_ZVBC
extern "C" unsigned crc32c_riscv_zvbc(unsigned , const void *, size_t);
# endif
extern "C" unsigned rv_riscv_crc_ext(void *);
extern "C" const char *crc32c_riscv_impl(my_crc32_t);
#elif defined __i386__||defined __x86_64__||defined _M_X64||defined _M_IX86
extern "C" my_crc32_t crc32c_x86_available(void );
extern "C" const char *crc32c_x86_impl(my_crc32_t);
#endif
#if defined HAVE_RISCV_ZBC
static my_crc32_t crc32c_riscv_choose(void *hwprobe)
{
unsigned ext= rv_riscv_crc_ext(hwprobe);
/* Where scalar Zbc is available, prefer it over the Zvbc vector core.
The vector core does not buy extra parallelism here . To stay
bit - exact with the scalar core it reuses exactly the same fold :
four 128 - bit lanes over a fixed 64 - byte span , with the same
constants k1 . . k4 and the same Barrett step . It therefore caps vl
at 4 and folds 64 bytes per iteration however wide VLEN is , and it
issues the same number of carry - less multiplies . Its only edge is
a single de - interleaving segment load per 64 bytes , which on large
input is offset by its per - call overhead ( vsetvl , and injecting
the CRC into lane 0 through a store / load round trip ) : on Spacemit
X100 ( VLEN = 256 ) it ties the scalar fold at 64 KiB ( 11398 vs 11687
MB / s ) and loses on small input ( 128 B : 1147 vs 5540 MB / s ,
1 KiB : 5466 vs 10277 MB / s ) .
Its reason to exist is cores that implement Zvbc but not scalar
Zbc , where the only alternative is the slicing - by - 4 crc32c_slow .
Where Zbc is present , selecting it would only touch the vector
register file for no gain. */
if (ext & 1 )
return crc32c_riscv_zbc;
#ifdef HAVE_RISCV_ZVBC
if (ext & 2 ) /* Zvbc only (no scalar Zbc) */
return crc32c_riscv_zvbc;
#endif
return crc32c_slow;
}
/* The RISC-V resolver. Unlike the other architectures, the implementation is
selected by an indirect function instead of at the first call , because the
target operating systems of RISC - V ( Linux and FreeBSD ) support that .
The dynamic linker calls this at load time , before main ( ) , so it may only
run code that is safe there . rv_riscv_crc_ext ( ) is : it uses the
riscv_hwprobe system call and nothing else .
The resolver must never return NULL . Whereas the * _ available ( ) functions
used elsewhere return NULL to mean " the extension is not present " , an ifunc
resolver that returns NULL crashes at the first call . crc32c_slow ( ) is
therefore returned instead; it is linked unconditionally anyway. */
extern "C" { static my_crc32_t rv_crc32c_resolver(unsigned long long ,
void *hwprobe, void *)
{
return crc32c_riscv_choose(hwprobe);
} }
#else
static inline my_crc32_t Choose_Extend()
{
#if defined HAVE_POWER8 && defined HAS_ALTIVEC
if (arch_ppc_probe())
return crc32c_ppc;
#elif defined HAVE_ARMV8_CRC
if (my_crc32_t crc= crc32c_aarch64_available())
return crc;
#elif defined __i386__||defined __x86_64__||defined _M_X64||defined _M_IX86
if (my_crc32_t crc= crc32c_x86_available())
return crc;
#endif
return crc32c_slow;
}
static const my_crc32_t ChosenExtend= Choose_Extend();
#endif
extern "C" const char *my_crc32c_implementation()
{
#if defined HAVE_RISCV_ZBC
/* The address of an ifunc symbol is the address of the selected
implementation , so it cannot be compared against a specific one from
here . The probe is repeated instead ; that is what the resolver uses to
make the same choice. */
if (const char *ret= crc32c_riscv_impl(crc32c_riscv_choose(NULL)))
return ret;
#elif defined HAVE_POWER8 && defined HAS_ALTIVEC
if (ChosenExtend == crc32c_ppc)
return "Using POWER8 crc32 instructions" ;
#elif defined HAVE_ARMV8_CRC
if (const char *ret= crc32c_aarch64_impl(ChosenExtend))
return ret;
#elif defined __i386__||defined __x86_64__||defined _M_X64||defined _M_IX86
if (const char *ret= crc32c_x86_impl(ChosenExtend))
return ret;
#endif
return "Using generic crc32 instructions" ;
}
} // namespace crc32c
} // namespace mysys_namespace
#if defined HAVE_RISCV_ZBC
extern "C" uint32 my_crc32c(uint32, const void *, size_t)
__attribute__((ifunc("rv_crc32c_resolver" )));
#else
extern "C" uint32 my_crc32c(uint32 crc, const void *buf, size_t size)
{
return mysys_namespace::crc32c::ChosenExtend(crc,buf, size);
}
#endif
Messung V0.5 in Prozent C=93 H=92 G=92
¤ Dauer der Verarbeitung: 0.15 Sekunden
(vorverarbeitet am 2026-10-08)
¤
*© Formatika GbR, Deutschland