1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- /*
- * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License").
- * You may not use this file except in compliance with the License.
- * A copy of the License is located at
- *
- * http://aws.amazon.com/apache2.0
- *
- * or in the "license" file accompanying this file. This file is distributed
- * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
- * express or implied. See the License for the specific language governing
- * permissions and limitations under the License.
- */
- #include <aws/common/cpuid.h>
- #include <stdlib.h>
- #if defined(__linux__) || defined(__FreeBSD__)
- # include <sys/auxv.h>
- static unsigned long s_hwcap[2];
- static bool s_hwcap_cached;
- struct cap_bits {
- unsigned long cap;
- unsigned long bit;
- };
- # if (defined(__aarch64__))
- struct cap_bits s_check_cap[AWS_CPU_FEATURE_COUNT] = {
- [AWS_CPU_FEATURE_ARM_CRC] = {0, 1 << 7 /* HWCAP_CRC */},
- };
- # else
- struct cap_bits s_check_cap[AWS_CPU_FEATURE_COUNT] = {
- [AWS_CPU_FEATURE_ARM_CRC] = {1, 1 << 4 /* HWCAP_CRC */},
- };
- # endif
- # if (defined(__linux__))
- static void s_cache_hwcap(void) {
- s_hwcap[0] = getauxval(AT_HWCAP);
- s_hwcap[1] = getauxval(AT_HWCAP2);
- s_hwcap_cached = true;
- }
- # elif (defined(__FreeBSD__))
- static void s_cache_hwcap(void) {
- int ret;
- ret = elf_aux_info(AT_HWCAP, &s_hwcap[0], sizeof(unsigned long));
- if (ret)
- s_hwcap[0] = 0;
- ret = elf_aux_info(AT_HWCAP2, &s_hwcap[1], sizeof(unsigned long));
- if (ret)
- s_hwcap[1] = 0;
- s_hwcap_cached = true;
- }
- # else
- # error "Unknown method"
- # endif
- bool aws_cpu_has_feature(enum aws_cpu_feature_name feature_name) {
- if (!s_hwcap_cached)
- s_cache_hwcap();
- switch (feature_name) {
- case AWS_CPU_FEATURE_ARM_CRC:
- return s_hwcap[s_check_cap[feature_name].cap] & s_check_cap[feature_name].bit;
- default:
- return false;
- }
- }
- #else /* defined(__linux__) || defined(__FreeBSD__) */
- bool aws_cpu_has_feature(enum aws_cpu_feature_name feature_name) {
- return false;
- }
- #endif /* defined(__linux__) || defined(__FreeBSD__) */
|