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