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 #include "crc32c/crc32c_config.h" 14 15 #if HAVE_ARM64_CRC32C 16 17 #ifdef __linux__ 18 #if HAVE_STRONG_GETAUXVAL 19 #include <sys/auxv.h> 20 #elif HAVE_WEAK_GETAUXVAL 21 // getauxval() is not available on Android until API level 20. Link it as a weak 22 // symbol. 23 extern "C" unsigned long getauxval(unsigned long type) __attribute__((weak)); 24 25 #define AT_HWCAP 16 26 #endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL 27 #endif // defined (__linux__) 28 29 #ifdef __APPLE__ 30 #include <sys/types.h> 31 #include <sys/sysctl.h> 32 #endif // defined (__APPLE__) 33 34 namespace crc32c { 35 CanUseArm64Crc32()36inline bool CanUseArm64Crc32() { 37 #if defined (__linux__) && (HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL) 38 // From 'arch/arm64/include/uapi/asm/hwcap.h' in Linux kernel source code. 39 constexpr unsigned long kHWCAP_PMULL = 1 << 4; 40 constexpr unsigned long kHWCAP_CRC32 = 1 << 7; 41 unsigned long hwcap = 42 #if HAVE_STRONG_GETAUXVAL 43 // Some compilers warn on (&getauxval != nullptr) in the block below. 44 getauxval(AT_HWCAP); 45 #elif HAVE_WEAK_GETAUXVAL 46 (&getauxval != nullptr) ? getauxval(AT_HWCAP) : 0; 47 #else 48 #error This is supposed to be nested inside a check for HAVE_*_GETAUXVAL. 49 #endif // HAVE_STRONG_GETAUXVAL 50 return (hwcap & (kHWCAP_PMULL | kHWCAP_CRC32)) == 51 (kHWCAP_PMULL | kHWCAP_CRC32); 52 #elif defined(__APPLE__) 53 int val = 0; 54 size_t len = sizeof(val); 55 return sysctlbyname("hw.optional.armv8_crc32", &val, &len, nullptr, 0) == 0 56 && val != 0; 57 #else 58 return false; 59 #endif // HAVE_STRONG_GETAUXVAL || HAVE_WEAK_GETAUXVAL 60 } 61 62 } // namespace crc32c 63 64 #endif // HAVE_ARM64_CRC32C 65 66 #endif // CRC32C_CRC32C_ARM_CHECK_H_ 67