File: CRC.cpp

package info (click to toggle)
llvm-toolchain-9 1%3A9.0.1-16.1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 882,388 kB
  • sloc: cpp: 4,167,636; ansic: 714,256; asm: 457,610; python: 155,927; objc: 65,094; sh: 42,856; lisp: 26,908; perl: 7,786; pascal: 7,722; makefile: 6,881; ml: 5,581; awk: 3,648; cs: 2,027; xml: 888; javascript: 381; ruby: 156
file content (68 lines) | stat: -rw-r--r-- 2,071 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
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