Skip to content

Commit 620ce4b

Browse files
MarcoFalkejanus
MarcoFalke
authored andcommitted
Squashed 'src/crc32c/' changes from 224988680f..b5ef9be675
b5ef9be675 Merge #1: Merge changes from upstream 9e7f512430 Merge remote-tracking branch 'origin/master' into bitcoin-fork 1f85030246 Add support for ARM64 darwin (#43) 3bb959c982 Remove unnecessary reinterpret_cast (#42) 2e97ab26b1 Fix (unused) ReadUint64LE for BE machines (#41) 47b40d2209 Bump dependencies. (#40) ba74185625 Move CI to Visual Studio 2019. efa301a7e5 Allow different C/C++ standards when this is used as a subproject. cc6d71465e CMake: Use configure_package_config_file() git-subtree-dir: src/crc32c git-subtree-split: b5ef9be6755a2e61e2988bb238f13d1c0ee1fa0a
1 parent 437d7e3 commit 620ce4b

11 files changed

+150
-55
lines changed

Crc32cConfig.cmake.in

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright 2017 The CRC32C Authors. All rights reserved.
2+
# Use of this source code is governed by a BSD-style license that can be
3+
# found in the LICENSE file. See the AUTHORS file for names of contributors.
4+
5+
@PACKAGE_INIT@
6+
7+
include("${CMAKE_CURRENT_LIST_DIR}/Crc32cTargets.cmake")
8+
9+
check_required_components(Crc32c)

src/crc32c/AUTHORS

+2
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,5 @@ Google Inc.
77

88
Fangming Fang <[email protected]>
99
Vadim Skipin <[email protected]>
10+
Rodrigo Tobar <[email protected]>
11+
Harry Mallon <[email protected]>

src/crc32c/CMakeLists.txt

+27-16
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,21 @@
55
cmake_minimum_required(VERSION 3.1)
66
project(Crc32c VERSION 1.1.0 LANGUAGES C CXX)
77

8-
# This project can use C11, but will gracefully decay down to C89.
9-
set(CMAKE_C_STANDARD 11)
10-
set(CMAKE_C_STANDARD_REQUIRED OFF)
11-
set(CMAKE_C_EXTENSIONS OFF)
12-
13-
# This project requires C++11.
14-
set(CMAKE_CXX_STANDARD 11)
15-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
16-
set(CMAKE_CXX_EXTENSIONS OFF)
8+
# C standard can be overridden when this is used as a sub-project.
9+
if(NOT CMAKE_C_STANDARD)
10+
# This project can use C11, but will gracefully decay down to C89.
11+
set(CMAKE_C_STANDARD 11)
12+
set(CMAKE_C_STANDARD_REQUIRED OFF)
13+
set(CMAKE_C_EXTENSIONS OFF)
14+
endif(NOT CMAKE_C_STANDARD)
15+
16+
# C++ standard can be overridden when this is used as a sub-project.
17+
if(NOT CMAKE_CXX_STANDARD)
18+
# This project requires C++11.
19+
set(CMAKE_CXX_STANDARD 11)
20+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
21+
set(CMAKE_CXX_EXTENSIONS OFF)
22+
endif(NOT CMAKE_CXX_STANDARD)
1723

1824
# https://github.com/izenecloud/cmake/blob/master/SetCompilerWarningAll.cmake
1925
if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
@@ -269,7 +275,7 @@ target_sources(crc32c
269275
PRIVATE
270276
"${PROJECT_BINARY_DIR}/include/crc32c/crc32c_config.h"
271277
"src/crc32c_arm64.h"
272-
"src/crc32c_arm64_linux_check.h"
278+
"src/crc32c_arm64_check.h"
273279
"src/crc32c_internal.h"
274280
"src/crc32c_portable.cc"
275281
"src/crc32c_prefetch.h"
@@ -405,19 +411,24 @@ if(CRC32C_INSTALL)
405411
)
406412

407413
include(CMakePackageConfigHelpers)
414+
configure_package_config_file(
415+
"${PROJECT_NAME}Config.cmake.in"
416+
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
417+
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
418+
)
408419
write_basic_package_version_file(
409-
"${PROJECT_BINARY_DIR}/Crc32cConfigVersion.cmake"
410-
COMPATIBILITY SameMajorVersion
420+
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
421+
COMPATIBILITY SameMajorVersion
411422
)
412423
install(
413424
EXPORT Crc32cTargets
414425
NAMESPACE Crc32c::
415-
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Crc32c"
426+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
416427
)
417428
install(
418429
FILES
419-
"Crc32cConfig.cmake"
420-
"${PROJECT_BINARY_DIR}/Crc32cConfigVersion.cmake"
421-
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/Crc32c"
430+
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
431+
"${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
432+
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
422433
)
423434
endif(CRC32C_INSTALL)

src/crc32c/Crc32cConfig.cmake

+4
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@
22
# Use of this source code is governed by a BSD-style license that can be
33
# found in the LICENSE file. See the AUTHORS file for names of contributors.
44

5+
@PACKAGE_INIT@
6+
57
include("${CMAKE_CURRENT_LIST_DIR}/Crc32cTargets.cmake")
8+
9+
check_required_components(Crc32c)

src/crc32c/src/crc32c.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
#include <cstdint>
99

1010
#include "./crc32c_arm64.h"
11-
#include "./crc32c_arm64_linux_check.h"
11+
#include "./crc32c_arm64_check.h"
1212
#include "./crc32c_internal.h"
1313
#include "./crc32c_sse42.h"
1414
#include "./crc32c_sse42_check.h"
@@ -20,8 +20,8 @@ uint32_t Extend(uint32_t crc, const uint8_t* data, size_t count) {
2020
static bool can_use_sse42 = CanUseSse42();
2121
if (can_use_sse42) return ExtendSse42(crc, data, count);
2222
#elif HAVE_ARM64_CRC32C
23-
static bool can_use_arm_linux = CanUseArm64Linux();
24-
if (can_use_arm_linux) return ExtendArm64(crc, data, count);
23+
static bool can_use_arm64_crc32 = CanUseArm64Crc32();
24+
if (can_use_arm64_crc32) return ExtendArm64(crc, data, count);
2525
#endif // HAVE_SSE42 && (defined(_M_X64) || defined(__x86_64__))
2626

2727
return ExtendPortable(crc, data, count);

src/crc32c/src/crc32c_arm64.cc

+11-12
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464

6565
namespace crc32c {
6666

67-
uint32_t ExtendArm64(uint32_t crc, const uint8_t *buf, size_t size) {
67+
uint32_t ExtendArm64(uint32_t crc, const uint8_t *data, size_t size) {
6868
int64_t length = size;
6969
uint32_t crc0, crc1, crc2, crc3;
7070
uint64_t t0, t1, t2;
@@ -74,7 +74,6 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *buf, size_t size) {
7474
const poly64_t k0 = 0x8d96551c, k1 = 0xbd6f81f8, k2 = 0xdcb17aa4;
7575

7676
crc = crc ^ kCRC32Xor;
77-
const uint8_t *p = reinterpret_cast<const uint8_t *>(buf);
7877

7978
while (length >= KBYTES) {
8079
crc0 = crc;
@@ -83,14 +82,14 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *buf, size_t size) {
8382
crc3 = 0;
8483

8584
// Process 1024 bytes in parallel.
86-
CRC32C1024BYTES(p);
85+
CRC32C1024BYTES(data);
8786

8887
// Merge the 4 partial CRC32C values.
8988
t2 = (uint64_t)vmull_p64(crc2, k2);
9089
t1 = (uint64_t)vmull_p64(crc1, k1);
9190
t0 = (uint64_t)vmull_p64(crc0, k0);
92-
crc = __crc32cd(crc3, *(uint64_t *)p);
93-
p += sizeof(uint64_t);
91+
crc = __crc32cd(crc3, *(uint64_t *)data);
92+
data += sizeof(uint64_t);
9493
crc ^= __crc32cd(0, t2);
9594
crc ^= __crc32cd(0, t1);
9695
crc ^= __crc32cd(0, t0);
@@ -99,23 +98,23 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t *buf, size_t size) {
9998
}
10099

101100
while (length >= 8) {
102-
crc = __crc32cd(crc, *(uint64_t *)p);
103-
p += 8;
101+
crc = __crc32cd(crc, *(uint64_t *)data);
102+
data += 8;
104103
length -= 8;
105104
}
106105

107106
if (length & 4) {
108-
crc = __crc32cw(crc, *(uint32_t *)p);
109-
p += 4;
107+
crc = __crc32cw(crc, *(uint32_t *)data);
108+
data += 4;
110109
}
111110

112111
if (length & 2) {
113-
crc = __crc32ch(crc, *(uint16_t *)p);
114-
p += 2;
112+
crc = __crc32ch(crc, *(uint16_t *)data);
113+
data += 2;
115114
}
116115

117116
if (length & 1) {
118-
crc = __crc32cb(crc, *p);
117+
crc = __crc32cb(crc, *data);
119118
}
120119

121120
return crc ^ kCRC32Xor;

src/crc32c/src/crc32c_arm64.h

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file. See the AUTHORS file for names of contributors.
44

5-
// Linux-specific code checking the availability for ARM CRC32C instructions.
5+
// ARM-specific code
66

7-
#ifndef CRC32C_CRC32C_ARM_LINUX_H_
8-
#define CRC32C_CRC32C_ARM_LINUX_H_
7+
#ifndef CRC32C_CRC32C_ARM_H_
8+
#define CRC32C_CRC32C_ARM_H_
99

1010
#include <cstddef>
1111
#include <cstdint>
@@ -24,4 +24,4 @@ uint32_t ExtendArm64(uint32_t crc, const uint8_t* data, size_t count);
2424

2525
#endif // HAVE_ARM64_CRC32C
2626

27-
#endif // CRC32C_CRC32C_ARM_LINUX_H_
27+
#endif // CRC32C_CRC32C_ARM_H_

src/crc32c/src/crc32c_arm64_linux_check.h

+18-8
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22
// Use of this source code is governed by a BSD-style license that can be
33
// found in the LICENSE file. See the AUTHORS file for names of contributors.
44

5-
// ARM Linux-specific code checking for the availability of CRC32C instructions.
5+
// ARM-specific code checking for the availability of CRC32C instructions.
66

7-
#ifndef CRC32C_CRC32C_ARM_LINUX_CHECK_H_
8-
#define CRC32C_CRC32C_ARM_LINUX_CHECK_H_
9-
10-
// X86-specific code checking for the availability of SSE4.2 instructions.
7+
#ifndef CRC32C_CRC32C_ARM_CHECK_H_
8+
#define CRC32C_CRC32C_ARM_CHECK_H_
119

1210
#include <cstddef>
1311
#include <cstdint>
@@ -18,6 +16,7 @@
1816

1917
#if HAVE_ARM64_CRC32C
2018

19+
#ifdef __linux__
2120
#if HAVE_STRONG_GETAUXVAL
2221
#include <sys/auxv.h>
2322
#elif HAVE_WEAK_GETAUXVAL
@@ -27,17 +26,28 @@ extern "C" unsigned long getauxval(unsigned long type) __attribute__((weak));
2726

2827
#define AT_HWCAP 16
2928
#endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL
29+
#endif // defined (__linux__)
30+
31+
#ifdef __APPLE__
32+
#include <sys/types.h>
33+
#include <sys/sysctl.h>
34+
#endif // defined (__APPLE__)
3035

3136
namespace crc32c {
3237

33-
inline bool CanUseArm64Linux() {
34-
#if HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL
38+
inline bool CanUseArm64Crc32() {
39+
#if defined (__linux__) && (HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL)
3540
// From 'arch/arm64/include/uapi/asm/hwcap.h' in Linux kernel source code.
3641
constexpr unsigned long kHWCAP_PMULL = 1 << 4;
3742
constexpr unsigned long kHWCAP_CRC32 = 1 << 7;
3843
unsigned long hwcap = (&getauxval != nullptr) ? getauxval(AT_HWCAP) : 0;
3944
return (hwcap & (kHWCAP_PMULL | kHWCAP_CRC32)) ==
4045
(kHWCAP_PMULL | kHWCAP_CRC32);
46+
#elif defined(__APPLE__)
47+
int val = 0;
48+
size_t len = sizeof(val);
49+
return sysctlbyname("hw.optional.armv8_crc32", &val, &len, nullptr, 0) == 0
50+
&& val != 0;
4151
#else
4252
return false;
4353
#endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL
@@ -47,4 +57,4 @@ inline bool CanUseArm64Linux() {
4757

4858
#endif // HAVE_ARM64_CRC32C
4959

50-
#endif // CRC32C_CRC32C_ARM_LINUX_CHECK_H_
60+
#endif // CRC32C_CRC32C_ARM_CHECK_H_

src/crc32c/src/crc32c_benchmark.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
#endif // CRC32C_TESTS_BUILT_WITH_GLOG
1717

1818
#include "./crc32c_arm64.h"
19-
#include "./crc32c_arm64_linux_check.h"
19+
#include "./crc32c_arm64_check.h"
2020
#include "./crc32c_internal.h"
2121
#include "./crc32c_sse42.h"
2222
#include "./crc32c_sse42_check.h"
@@ -58,8 +58,8 @@ BENCHMARK_REGISTER_F(CRC32CBenchmark, Portable)
5858

5959
#if HAVE_ARM64_CRC32C
6060

61-
BENCHMARK_DEFINE_F(CRC32CBenchmark, ArmLinux)(benchmark::State& state) {
62-
if (!crc32c::CanUseArm64Linux()) {
61+
BENCHMARK_DEFINE_F(CRC32CBenchmark, ArmCRC32C)(benchmark::State& state) {
62+
if (!crc32c::CanUseArm64Crc32()) {
6363
state.SkipWithError("ARM CRC32C instructions not available or not enabled");
6464
return;
6565
}
@@ -69,7 +69,7 @@ BENCHMARK_DEFINE_F(CRC32CBenchmark, ArmLinux)(benchmark::State& state) {
6969
crc = crc32c::ExtendArm64(crc, block_buffer_, block_size_);
7070
state.SetBytesProcessed(state.iterations() * block_size_);
7171
}
72-
BENCHMARK_REGISTER_F(CRC32CBenchmark, ArmLinux)
72+
BENCHMARK_REGISTER_F(CRC32CBenchmark, ArmCRC32C)
7373
->RangeMultiplier(16)
7474
->Range(256, 16777216); // Block size.
7575

src/crc32c/src/crc32c_read_le.h

+8-8
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,14 @@ inline uint32_t ReadUint32LE(const uint8_t* buffer) {
3232
// Reads a little-endian 64-bit integer from a 64-bit-aligned buffer.
3333
inline uint64_t ReadUint64LE(const uint8_t* buffer) {
3434
#if BYTE_ORDER_BIG_ENDIAN
35-
return ((static_cast<uint32_t>(static_cast<uint8_t>(buffer[0]))) |
36-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[1])) << 8) |
37-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[2])) << 16) |
38-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[3])) << 24) |
39-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[4])) << 32) |
40-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[5])) << 40) |
41-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[6])) << 48) |
42-
(static_cast<uint32_t>(static_cast<uint8_t>(buffer[7])) << 56));
35+
return ((static_cast<uint64_t>(static_cast<uint8_t>(buffer[0]))) |
36+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[1])) << 8) |
37+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[2])) << 16) |
38+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[3])) << 24) |
39+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[4])) << 32) |
40+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[5])) << 40) |
41+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[6])) << 48) |
42+
(static_cast<uint64_t>(static_cast<uint8_t>(buffer[7])) << 56));
4343
#else // !BYTE_ORDER_BIG_ENDIAN
4444
uint64_t result;
4545
// This should be optimized to a single instruction.

src/crc32c_arm64_check.h

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright 2017 The CRC32C Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file. See the AUTHORS file for names of contributors.
4+
5+
// ARM-specific code checking for the availability of CRC32C instructions.
6+
7+
#ifndef CRC32C_CRC32C_ARM_CHECK_H_
8+
#define CRC32C_CRC32C_ARM_CHECK_H_
9+
10+
#include <cstddef>
11+
#include <cstdint>
12+
13+
#ifdef CRC32C_HAVE_CONFIG_H
14+
#include "crc32c/crc32c_config.h"
15+
#endif
16+
17+
#if HAVE_ARM64_CRC32C
18+
19+
#ifdef __linux__
20+
#if HAVE_STRONG_GETAUXVAL
21+
#include <sys/auxv.h>
22+
#elif HAVE_WEAK_GETAUXVAL
23+
// getauxval() is not available on Android until API level 20. Link it as a weak
24+
// symbol.
25+
extern "C" unsigned long getauxval(unsigned long type) __attribute__((weak));
26+
27+
#define AT_HWCAP 16
28+
#endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL
29+
#endif // defined (__linux__)
30+
31+
#ifdef __APPLE__
32+
#include <sys/types.h>
33+
#include <sys/sysctl.h>
34+
#endif // defined (__APPLE__)
35+
36+
namespace crc32c {
37+
38+
inline bool CanUseArm64Crc32() {
39+
#if defined (__linux__) && (HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL)
40+
// From 'arch/arm64/include/uapi/asm/hwcap.h' in Linux kernel source code.
41+
constexpr unsigned long kHWCAP_PMULL = 1 << 4;
42+
constexpr unsigned long kHWCAP_CRC32 = 1 << 7;
43+
unsigned long hwcap = (&getauxval != nullptr) ? getauxval(AT_HWCAP) : 0;
44+
return (hwcap & (kHWCAP_PMULL | kHWCAP_CRC32)) ==
45+
(kHWCAP_PMULL | kHWCAP_CRC32);
46+
#elif defined(__APPLE__)
47+
int val = 0;
48+
size_t len = sizeof(val);
49+
return sysctlbyname("hw.optional.armv8_crc32", &val, &len, nullptr, 0) == 0
50+
&& val != 0;
51+
#else
52+
return false;
53+
#endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL
54+
}
55+
56+
} // namespace crc32c
57+
58+
#endif // HAVE_ARM64_CRC32C
59+
60+
#endif // CRC32C_CRC32C_ARM_CHECK_H_

0 commit comments

Comments
 (0)