aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/CRC.cpp
diff options
context:
space:
mode:
authorEugene Leviant <eleviant@accesssoftek.com>2019-04-08 11:25:48 +0000
committerEugene Leviant <eleviant@accesssoftek.com>2019-04-08 11:25:48 +0000
commitad69bd687008c2daa46cd6dafb58cb9e95e7eedb (patch)
tree5a18dfd3d0601f08e480249cfdb5ea4cc8a7b5a9 /llvm/lib/Support/CRC.cpp
parenteb1a156d7f7ba56ea8f9a26da36e6a93d1e98bda (diff)
downloadllvm-ad69bd687008c2daa46cd6dafb58cb9e95e7eedb.zip
llvm-ad69bd687008c2daa46cd6dafb58cb9e95e7eedb.tar.gz
llvm-ad69bd687008c2daa46cd6dafb58cb9e95e7eedb.tar.bz2
[Support] Add zlib independent CRC32
Differential revision: https://reviews.llvm.org/D59816 llvm-svn: 357901
Diffstat (limited to 'llvm/lib/Support/CRC.cpp')
-rw-r--r--llvm/lib/Support/CRC.cpp68
1 files changed, 68 insertions, 0 deletions
diff --git a/llvm/lib/Support/CRC.cpp b/llvm/lib/Support/CRC.cpp
new file mode 100644
index 0000000..6f8edf6
--- /dev/null
+++ b/llvm/lib/Support/CRC.cpp
@@ -0,0 +1,68 @@
+//===--- 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 <array>
+
+using namespace llvm;
+
+#if LLVM_ENABLE_ZLIB == 0 || !HAVE_ZLIB_H
+using CRC32Table = std::array<uint32_t, 256>;
+
+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<const uint8_t *>(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 <zlib.h>
+uint32_t llvm::crc32(uint32_t CRC, StringRef S) {
+ return ::crc32(CRC, (const Bytef *)S.data(), S.size());
+}
+#endif