1 //===-- scudo_crc32.cpp -----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// CRC32 function leveraging hardware specific instructions. This has to be
11 /// kept separated to restrict the use of compiler specific flags to this file.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 // Hardware CRC32 is supported at compilation via the following:
16 // - for i386 & x86_64: -msse4.2
17 // - for ARM & AArch64: -march=armv8-a+crc or -mcrc
18 // An additional check must be performed at runtime as well to make sure the
19 // emitted instructions are valid on the target host.
20 #include "scudo_crc32.h"
21 #include "scudo_utils.h"
22 
23 #if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
24 # ifdef __SSE4_2__
25 #  include <smmintrin.h>
26 #  define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
27 # endif
28 # ifdef __ARM_FEATURE_CRC32
29 #  include <arm_acle.h>
30 #  define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd)
31 # endif
32 #endif  // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
33 
34 namespace __scudo {
35 
36 #if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
37 INLINE u32 computeHardwareCRC32(u32 Crc, uptr Data) {
38   return CRC32_INTRINSIC(Crc, Data);
39 }
40 
41 u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
42   if (HashType == CRC32Hardware) {
43     return computeHardwareCRC32(Crc, Data);
44   }
45   return computeSoftwareCRC32(Crc, Data);
46 }
47 #else
48 u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
49   return computeSoftwareCRC32(Crc, Data);
50 }
51 #endif  // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
52 
53 }  // namespace __scudo
54