Skip to content

Commit

Permalink
Full arm cpu feature detection.
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanHenson committed Jan 24, 2024
1 parent 88143c1 commit f1075a2
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 7 deletions.
12 changes: 8 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,13 +155,17 @@ if (USE_CPU_EXTENSIONS)
)
endif()
elseif (AWS_ARCH_ARM64 OR AWS_ARCH_ARM32)
if (MSVC)
if (WINDOWS)
file(GLOB AWS_COMMON_ARCH_SRC
"source/arch/arm/msvc/*.c"
"source/arch/arm/windows/*.c"
)
elseif (AWS_HAVE_AUXV)
elseif(APPLE)
file(GLOB AWS_COMMON_ARCH_SRC
"source/arch/arm/darwin/*.c"
)
else()
file(GLOB AWS_COMMON_ARCH_SRC
"source/arch/arm/asm/*.c"
"source/arch/arm/auxv/*.c"
)
endif()
endif()
Expand Down
14 changes: 14 additions & 0 deletions bin/system_info/print_system_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <aws/common/byte_buf.h>
#include <aws/common/logging.h>
#include <aws/common/system_info.h>
#include <aws/common/cpuid.h>

int main(void) {
struct aws_allocator *allocator = aws_default_allocator();
Expand Down Expand Up @@ -39,6 +40,19 @@ int main(void) {
fprintf(stdout, " 'numa architecture': 'false'\n");
}

fprintf(stdout, " 'cpu_capabilities': {\n");
fprintf(stdout, " 'arm_crc': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_ARM_CRC) ? "true" : "false");
fprintf(stdout, " 'arm_pmull': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_ARM_PMULL) ? "true" : "false");
fprintf(stdout, " 'arm_crypto': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_ARM_CRYPTO) ? "true" : "false");
fprintf(stdout, " 'amd_sse4_1': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_SSE_4_1) ? "true" : "false");
fprintf(stdout, " 'amd_sse4_2': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_SSE_4_2) ? "true" : "false");
fprintf(stdout, " 'amd_clmul': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_CLMUL) ? "true" : "false");
fprintf(stdout, " 'amd_vpclmulqdq': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_VPCLMULQDQ) ? "true" : "false");
fprintf(stdout, " 'amd_avx2': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_AVX2) ? "true" : "false");
fprintf(stdout, " 'amd_avx512': %s,\n", aws_cpu_has_feature(AWS_CPU_FEATURE_AVX512) ? "true" : "false");
fprintf(stdout, " 'amd_bmi2': %s\n", aws_cpu_has_feature(AWS_CPU_FEATURE_BMI2) ? "true" : "false");
fprintf(stdout, " }\n");

fprintf(stdout, "}\n");
aws_system_environment_release(env);
aws_logger_clean_up(&logger);
Expand Down
2 changes: 2 additions & 0 deletions include/aws/common/cpuid.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ enum aws_cpu_feature_name {
AWS_CPU_FEATURE_ARM_CRC,
AWS_CPU_FEATURE_BMI2,
AWS_CPU_FEATURE_VPCLMULQDQ,
AWS_CPU_FEATURE_ARM_PMULL,
AWS_CPU_FEATURE_ARM_CRYPTO,
AWS_CPU_FEATURE_COUNT,
};

Expand Down
4 changes: 3 additions & 1 deletion source/arch/arm/asm/cpuid.c → source/arch/arm/auxv/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ struct cap_bits {

# if (defined(__aarch64__))
struct cap_bits s_check_cap[AWS_CPU_FEATURE_COUNT] = {
[AWS_CPU_FEATURE_ARM_CRC] = {0, 1 << 7 /* HWCAP_CRC */},
[AWS_CPU_FEATURE_ARM_CRC] = {0, 1 << 7 /* HWCAP_CRC32 */},
[AWS_CPU_FEATURE_ARM_PMULL] = {0, 1 << 4 /* HWCAP_PMULL */},
[AWS_CPU_FEATURE_ARM_CRYPTO] = {0, 1 << 3 /* HWCAP_AES */},
};
# else
struct cap_bits s_check_cap[AWS_CPU_FEATURE_COUNT] = {
Expand Down
40 changes: 40 additions & 0 deletions source/arch/arm/darwin/cpuid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* 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 <sys/sysctl.h>

bool aws_cpu_has_feature(enum aws_cpu_feature_name feature_name) {
int64_t ret = 0;
size_t size = sizeof(ret);

switch (feature_name) {
case AWS_CPU_FEATURE_ARM_PMULL:
if (sysctlbyname("hw.optional.arm.FEAT_PMULL", &ret, &size, NULL, 0) != -1) {
return ret == 1;
}
case AWS_CPU_FEATURE_ARM_CRC:
if (sysctlbyname("hw.optional.armv8_crc32", &ret, &size, NULL, 0) != -1) {
return ret == 1;
}
case AWS_CPU_FEATURE_ARM_CRYPTO:
if (sysctlbyname("hw.optional.arm.FEAT_AES", &ret, &size, NULL, 0) != -1) {
return ret == 1;
}
default:
return false;
}
}
13 changes: 11 additions & 2 deletions source/arch/arm/msvc/cpuid.c → source/arch/arm/windows/cpuid.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,18 @@
* permissions and limitations under the License.
*/

#include <Windows.h>
#include <aws/common/cpuid.h>
#include <stdlib.h>

bool aws_cpu_has_feature(enum aws_cpu_feature_name feature_name) {
return false;
switch (feature_name) {
case AWS_CPU_FEATURE_ARM_CRC:
return IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE) != 0;
// this is the best we've got on windows as they don't separate PMULL and AES from each other.
case AWS_CPU_FEATURE_ARM_PMULL:
case AWS_CPU_FEATURE_ARM_CRYPTO:
return IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE) != 0;
default:
return false;
}
}

0 comments on commit f1075a2

Please sign in to comment.