crc32c.cmake raw
1 # Copyright (c) 2023-present The Bitcoin Core developers
2 # Distributed under the MIT software license, see the accompanying
3 # file COPYING or https://opensource.org/license/mit/.
4
5 # This file is part of the transition from Autotools to CMake. Once CMake
6 # support has been merged we should switch to using the upstream CMake
7 # buildsystem.
8
9 include(CheckCXXSourceCompiles)
10 include(CheckSourceCompilesWithFlags)
11
12 # Check for __builtin_prefetch support in the compiler.
13 check_cxx_source_compiles("
14 int main() {
15 char data = 0;
16 const char* address = &data;
17 __builtin_prefetch(address, 0, 0);
18 return 0;
19 }
20 " HAVE_BUILTIN_PREFETCH
21 )
22
23 # Check for _mm_prefetch support in the compiler.
24 check_cxx_source_compiles("
25 #if defined(_MSC_VER)
26 #include <intrin.h>
27 #else
28 #include <xmmintrin.h>
29 #endif
30
31 int main() {
32 char data = 0;
33 const char* address = &data;
34 _mm_prefetch(address, _MM_HINT_NTA);
35 return 0;
36 }
37 " HAVE_MM_PREFETCH
38 )
39
40 # Check for SSE4.2 support in the compiler.
41 if(MSVC)
42 set(SSE42_CXXFLAGS /arch:AVX)
43 else()
44 set(SSE42_CXXFLAGS -msse4.2)
45 endif()
46 check_cxx_source_compiles_with_flags("
47 #include <cstdint>
48 #if defined(_MSC_VER)
49 #include <intrin.h>
50 #elif defined(__GNUC__) && defined(__SSE4_2__)
51 #include <nmmintrin.h>
52 #endif
53
54 int main() {
55 uint64_t l = 0;
56 l = _mm_crc32_u8(l, 0);
57 l = _mm_crc32_u32(l, 0);
58 l = _mm_crc32_u64(l, 0);
59 return l;
60 }
61 " HAVE_SSE42
62 CXXFLAGS ${SSE42_CXXFLAGS}
63 )
64
65 # Check for ARMv8 w/ CRC and CRYPTO extensions support in the compiler.
66 set(ARM64_CRC_CXXFLAGS -march=armv8-a+crc+crypto)
67 check_cxx_source_compiles_with_flags("
68 #include <arm_acle.h>
69 #include <arm_neon.h>
70
71 int main() {
72 #ifdef __aarch64__
73 __crc32cb(0, 0); __crc32ch(0, 0); __crc32cw(0, 0); __crc32cd(0, 0);
74 vmull_p64(0, 0);
75 #else
76 #error crc32c library does not support hardware acceleration on 32-bit ARM
77 #endif
78 return 0;
79 }
80 " HAVE_ARM64_CRC32C
81 CXXFLAGS ${ARM64_CRC_CXXFLAGS}
82 )
83
84 add_library(crc32c STATIC EXCLUDE_FROM_ALL
85 ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c.cc
86 ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_portable.cc
87 )
88 target_compile_definitions(crc32c PRIVATE
89 HAVE_BUILTIN_PREFETCH=$<BOOL:${HAVE_BUILTIN_PREFETCH}>
90 HAVE_MM_PREFETCH=$<BOOL:${HAVE_MM_PREFETCH}>
91 HAVE_STRONG_GETAUXVAL=$<BOOL:${HAVE_STRONG_GETAUXVAL}>
92 BYTE_ORDER_BIG_ENDIAN=$<STREQUAL:${CMAKE_CXX_BYTE_ORDER},BIG_ENDIAN>
93 HAVE_SSE42=$<BOOL:${HAVE_SSE42}>
94 HAVE_ARM64_CRC32C=$<BOOL:${HAVE_ARM64_CRC32C}>
95 )
96 target_include_directories(crc32c
97 PUBLIC
98 $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/crc32c/include>
99 )
100 target_link_libraries(crc32c PRIVATE core_interface)
101 set_target_properties(crc32c PROPERTIES EXPORT_COMPILE_COMMANDS OFF)
102
103 if(HAVE_SSE42)
104 set(_crc32_src ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_sse42.cc)
105 target_sources(crc32c PRIVATE ${_crc32_src})
106 set_property(SOURCE ${_crc32_src} PROPERTY COMPILE_OPTIONS ${SSE42_CXXFLAGS})
107 endif()
108
109 if(HAVE_ARM64_CRC32C)
110 set(_crc32_src ${PROJECT_SOURCE_DIR}/src/crc32c/src/crc32c_arm64.cc)
111 target_sources(crc32c PRIVATE ${_crc32_src})
112 set_property(SOURCE ${_crc32_src} PROPERTY COMPILE_OPTIONS ${ARM64_CRC_CXXFLAGS})
113 endif()
114
115 unset(_crc32_src)
116