#include <folly/hash/Checksum.h>
#include <algorithm>
#include <stdexcept>
#include <boost/crc.hpp>
#include <folly/CpuId.h>
#include <folly/detail/TrapOnAvx512.h>
#include <folly/external/fast-crc32/avx512_crc32c_v8s3x4.h>
#include <folly/external/fast-crc32/sse_crc32c_v8s3x3.h>
#include <folly/hash/detail/ChecksumDetail.h>
#if FOLLY_SSE_PREREQ(4, 2)
#include <emmintrin.h>
#include <nmmintrin.h>
#endif
namespace folly {
namespace detail {
uint32_t crc32c_sw(
const uint8_t* data, size_t nbytes, uint32_t startingChecksum);
#if FOLLY_SSE_PREREQ(4, 2)
uint32_t crc32_sw(
const uint8_t* data, size_t nbytes, uint32_t startingChecksum);
uint32_t crc32_hw(
const uint8_t* data, size_t nbytes, uint32_t startingChecksum) {
uint32_t sum = startingChecksum;
size_t offset = 0;
if ((uintptr_t)data & 15) {
size_t limit = std::min(nbytes, -(uintptr_t)data & 15);
sum = crc32_sw(data, limit, sum);
offset += limit;
nbytes -= limit;
}
if (nbytes >= 16) {
sum = crc32_hw_aligned(sum, (const __m128i*)(data + offset), nbytes / 16);
offset += nbytes & ~15;
nbytes &= 15;
}
if (nbytes == 0) {
return sum;
}
return crc32_sw(data + offset, nbytes, sum);
}
bool crc32c_hw_supported() {
static folly::CpuId id;
return id.sse42();
}
bool crc32c_hw_supported_avx512() {
static folly::CpuId id;
static bool supported = id.avx512vl() && !detail::hasTrapOnAvx512();
return supported;
}
bool crc32_hw_supported() {
static folly::CpuId id;
return id.sse42();
}
#else
uint32_t crc32_hw(
const uint8_t* ,
size_t ,
uint32_t ) { … }
bool crc32c_hw_supported() { … }
bool crc32c_hw_supported_avx512() { … }
bool crc32_hw_supported() { … }
#endif
template <uint32_t CRC_POLYNOMIAL>
uint32_t crc_sw(const uint8_t* data, size_t nbytes, uint32_t startingChecksum) { … }
uint32_t crc32c_sw(
const uint8_t* data, size_t nbytes, uint32_t startingChecksum) { … }
uint32_t crc32_sw(
const uint8_t* data, size_t nbytes, uint32_t startingChecksum) { … }
}
uint32_t crc32c(const uint8_t* data, size_t nbytes, uint32_t startingChecksum) { … }
uint32_t crc32(const uint8_t* data, size_t nbytes, uint32_t startingChecksum) { … }
uint32_t crc32_type(
const uint8_t* data, size_t nbytes, uint32_t startingChecksum) { … }
uint32_t crc32_combine(uint32_t crc1, uint32_t crc2, size_t crc2len) { … }
uint32_t crc32c_combine(uint32_t crc1, uint32_t crc2, size_t crc2len) { … }
}