//===--- CRC.cpp - Cyclic Redundancy Check implementation -----------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file implements llvm::crc32 function. // //===----------------------------------------------------------------------===// #include "llvm/Support/CRC.h" #include "llvm/Config/config.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Threading.h" #include using namespace llvm; #if LLVM_ENABLE_ZLIB == 0 || !HAVE_ZLIB_H using CRC32Table = std::array; static void initCRC32Table(CRC32Table *Tbl) { auto Shuffle = [](uint32_t V) { return (V & 1) ? (V >> 1) ^ 0xEDB88320U : V >> 1; }; for (size_t I = 0; I < Tbl->size(); ++I) { uint32_t V = Shuffle(I); V = Shuffle(V); V = Shuffle(V); V = Shuffle(V); V = Shuffle(V); V = Shuffle(V); V = Shuffle(V); (*Tbl)[I] = Shuffle(V); } } uint32_t llvm::crc32(uint32_t CRC, StringRef S) { static llvm::once_flag InitFlag; static CRC32Table Tbl; llvm::call_once(InitFlag, initCRC32Table, &Tbl); const uint8_t *P = reinterpret_cast(S.data()); size_t Len = S.size(); CRC ^= 0xFFFFFFFFU; for (; Len >= 8; Len -= 8) { CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); } while (Len--) CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); return CRC ^ 0xFFFFFFFFU; } #else #include uint32_t llvm::crc32(uint32_t CRC, StringRef S) { return ::crc32(CRC, (const Bytef *)S.data(), S.size()); } #endif