Fix runtime CPU feature detection for ARM
We had no routines for checking compiler support instead only compiler currently enabled. Change-Id: I5543e4cff2b0bab494e11abf257061147baaf0d7 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
parent
cc8a71e211
commit
70738cf726
@ -67,6 +67,7 @@ if(GCC OR CLANG OR QCC)
|
|||||||
set(QT_CFLAGS_NEON "${__prefix}-mfpu=neon")
|
set(QT_CFLAGS_NEON "${__prefix}-mfpu=neon")
|
||||||
endif()
|
endif()
|
||||||
set(QT_CFLAGS_ARM_SVE "${__prefix}-march=armv8-a+sve")
|
set(QT_CFLAGS_ARM_SVE "${__prefix}-march=armv8-a+sve")
|
||||||
|
set(QT_CFLAGS_ARM_CRYPTO "${__prefix}-march=armv8-a+crypto")
|
||||||
set(QT_CFLAGS_MIPS_DSP "${__prefix}-mdsp")
|
set(QT_CFLAGS_MIPS_DSP "${__prefix}-mdsp")
|
||||||
set(QT_CFLAGS_MIPS_DSPR2 "${__prefix}-mdspr2")
|
set(QT_CFLAGS_MIPS_DSPR2 "${__prefix}-mdspr2")
|
||||||
unset(__prefix)
|
unset(__prefix)
|
||||||
|
@ -1283,6 +1283,31 @@ function(qt_config_compile_test_x86simd extension label)
|
|||||||
set(TEST_subarch_${extension} "${TEST_X86SIMD_${extension}}" CACHE INTERNAL "${label}")
|
set(TEST_subarch_${extension} "${TEST_X86SIMD_${extension}}" CACHE INTERNAL "${label}")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
|
function(qt_config_compile_test_armintrin extension label)
|
||||||
|
if (DEFINED TEST_ARMINTRIN_${extension})
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(flags "-DSIMD:string=${extension}")
|
||||||
|
|
||||||
|
qt_get_platform_try_compile_vars(platform_try_compile_vars)
|
||||||
|
list(APPEND flags ${platform_try_compile_vars})
|
||||||
|
|
||||||
|
message(STATUS "Performing Test ${label} intrinsics")
|
||||||
|
try_compile("TEST_ARMINTRIN_${extension}"
|
||||||
|
"${CMAKE_CURRENT_BINARY_DIR}/config.tests/armintrin_${extension}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/config.tests/armintrin"
|
||||||
|
armintrin
|
||||||
|
CMAKE_FLAGS ${flags})
|
||||||
|
if(${TEST_ARMINTRIN_${extension}})
|
||||||
|
set(status_label "Success")
|
||||||
|
else()
|
||||||
|
set(status_label "Failed")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Performing Test ${label} intrinsics - ${status_label}")
|
||||||
|
set(TEST_subarch_${extension} "${TEST_ARMINTRIN_${extension}}" CACHE INTERNAL "${label}")
|
||||||
|
endfunction()
|
||||||
|
|
||||||
function(qt_config_compile_test_machine_tuple label)
|
function(qt_config_compile_test_machine_tuple label)
|
||||||
if(DEFINED TEST_MACHINE_TUPLE OR NOT (LINUX OR HURD) OR ANDROID)
|
if(DEFINED TEST_MACHINE_TUPLE OR NOT (LINUX OR HURD) OR ANDROID)
|
||||||
return()
|
return()
|
||||||
|
@ -244,6 +244,7 @@ endmacro()
|
|||||||
|
|
||||||
defstub(qt_add_qmake_lib_dependency)
|
defstub(qt_add_qmake_lib_dependency)
|
||||||
defstub(qt_config_compile_test)
|
defstub(qt_config_compile_test)
|
||||||
|
defstub(qt_config_compile_test_armintrin)
|
||||||
defstub(qt_config_compile_test_machine_tuple)
|
defstub(qt_config_compile_test_machine_tuple)
|
||||||
defstub(qt_config_compile_test_x86simd)
|
defstub(qt_config_compile_test_x86simd)
|
||||||
defstub(qt_config_compiler_supports_flag_test)
|
defstub(qt_config_compiler_supports_flag_test)
|
||||||
|
@ -248,7 +248,7 @@ const char msg2[] = "==Qt=magic=Qt== Sub-architecture:"
|
|||||||
#if defined(__ARM_FEATURE_CRC32) || (defined(_M_ARM64) && __ARM_ARCH >= 800)
|
#if defined(__ARM_FEATURE_CRC32) || (defined(_M_ARM64) && __ARM_ARCH >= 800)
|
||||||
" crc32"
|
" crc32"
|
||||||
#endif
|
#endif
|
||||||
#if defined(__ARM_FEATURE_CRYPTO) || (defined(_M_ARM64) && __ARM_ARCH >= 800)
|
#if defined(__ARM_FEATURE_AES) || defined(__ARM_FEATURE_CRYPTO) || (defined(_M_ARM64) && __ARM_ARCH >= 800)
|
||||||
" crypto"
|
" crypto"
|
||||||
#endif
|
#endif
|
||||||
#ifdef __ARM_FEATURE_SVE
|
#ifdef __ARM_FEATURE_SVE
|
||||||
|
21
config.tests/armintrin/CMakeLists.txt
Normal file
21
config.tests/armintrin/CMakeLists.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
# Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
project(armintrin LANGUAGES CXX)
|
||||||
|
|
||||||
|
include(../../cmake/QtPlatformSupport.cmake)
|
||||||
|
include(../../cmake/QtCompilerOptimization.cmake)
|
||||||
|
|
||||||
|
string(TOUPPER "${SIMD}" upper_simd)
|
||||||
|
|
||||||
|
if(NOT DEFINED "QT_CFLAGS_ARM_${upper_simd}")
|
||||||
|
# Don't use CMake error() because a configure error also fails the try_compile() call.
|
||||||
|
# Instead use a compile flag that doesn't exist to force a compiler error.
|
||||||
|
set(QT_CFLAGS_${upper_simd} "--qt-cflags-not-found")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable("SimdTest${SIMD}")
|
||||||
|
target_sources("SimdTest${SIMD}" PRIVATE main.cpp)
|
||||||
|
target_compile_options("SimdTest${SIMD}" PRIVATE ${QT_CFLAGS_ARM_${upper_simd}})
|
||||||
|
target_compile_definitions("SimdTest${SIMD}" PRIVATE QT_COMPILER_SUPPORTS_${upper_simd})
|
37
config.tests/armintrin/main.cpp
Normal file
37
config.tests/armintrin/main.cpp
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (C) 2024
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
#if defined QT_COMPILER_SUPPORTS_CRYPTO
|
||||||
|
#include <arm_neon.h>
|
||||||
|
void aeshash(uint8x16_t &state0, uint8x16_t data)
|
||||||
|
{
|
||||||
|
auto state1 = state0;
|
||||||
|
state0 = vaeseq_u8(state0, data);
|
||||||
|
state0 = vaesmcq_u8(state0);
|
||||||
|
auto state2 = state0;
|
||||||
|
state0 = vaeseq_u8(state0, state1);
|
||||||
|
state0 = vaesmcq_u8(state0);
|
||||||
|
auto state3 = state0;
|
||||||
|
state0 = vaeseq_u8(state0, state2);
|
||||||
|
state0 = vaesmcq_u8(state0);
|
||||||
|
state0 = veorq_u8(state0, state3);
|
||||||
|
}
|
||||||
|
#elif defined QT_COMPILER_SUPPORTS_SVE
|
||||||
|
#include <arm_sve.h>
|
||||||
|
void qt_memfill64_sve(uint64_t *dest, uint64_t color, int64_t count)
|
||||||
|
{
|
||||||
|
int64_t i = 0;
|
||||||
|
const svuint64_t vdup = svdup_n_u64(color);
|
||||||
|
svbool_t pg = svwhilelt_b64_s64(i, count);
|
||||||
|
do {
|
||||||
|
svst1_u64(pg, (uint64_t*)(dest + i), vdup);
|
||||||
|
i += svcntd();
|
||||||
|
pg = svwhilelt_b64_s64(i, count);
|
||||||
|
} while (svptest_any(svptrue_b64(), pg));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
@ -370,6 +370,12 @@ qt_config_compile_test_x86simd(avx512vbmi2 "AVX512VBMI2")
|
|||||||
# x86: vaes
|
# x86: vaes
|
||||||
qt_config_compile_test_x86simd(vaes "VAES")
|
qt_config_compile_test_x86simd(vaes "VAES")
|
||||||
|
|
||||||
|
# arm: crypto
|
||||||
|
qt_config_compile_test_armintrin(crypto "CRYPTO")
|
||||||
|
|
||||||
|
# arm: sve
|
||||||
|
qt_config_compile_test_armintrin(sve "SVE")
|
||||||
|
|
||||||
# localtime_r
|
# localtime_r
|
||||||
qt_config_compile_test(localtime_r
|
qt_config_compile_test(localtime_r
|
||||||
LABEL "localtime_r()"
|
LABEL "localtime_r()"
|
||||||
@ -923,7 +929,7 @@ qt_feature_definition("arm_crc32" "QT_COMPILER_SUPPORTS_CRC32" VALUE "1")
|
|||||||
qt_feature_config("arm_crc32" QMAKE_PRIVATE_CONFIG)
|
qt_feature_config("arm_crc32" QMAKE_PRIVATE_CONFIG)
|
||||||
qt_feature("arm_crypto" PRIVATE
|
qt_feature("arm_crypto" PRIVATE
|
||||||
LABEL "AES"
|
LABEL "AES"
|
||||||
CONDITION ( ( TEST_architecture_arch STREQUAL arm ) OR ( TEST_architecture_arch STREQUAL arm64 ) ) AND TEST_arch_${TEST_architecture_arch}_subarch_crypto
|
CONDITION ( ( TEST_architecture_arch STREQUAL arm ) OR ( TEST_architecture_arch STREQUAL arm64 ) ) AND ( TEST_arch_${TEST_architecture_arch}_subarch_crypto OR TEST_subarch_crypto )
|
||||||
)
|
)
|
||||||
qt_feature_definition("arm_crypto" "QT_COMPILER_SUPPORTS_CRYPTO" VALUE "1")
|
qt_feature_definition("arm_crypto" "QT_COMPILER_SUPPORTS_CRYPTO" VALUE "1")
|
||||||
qt_feature_definition("arm_crypto" "QT_COMPILER_SUPPORTS_AES" VALUE "1")
|
qt_feature_definition("arm_crypto" "QT_COMPILER_SUPPORTS_AES" VALUE "1")
|
||||||
@ -931,7 +937,7 @@ qt_feature_config("arm_crypto" QMAKE_PRIVATE_CONFIG)
|
|||||||
|
|
||||||
qt_feature("arm_sve" PRIVATE
|
qt_feature("arm_sve" PRIVATE
|
||||||
LABEL "SVE"
|
LABEL "SVE"
|
||||||
CONDITION ( TEST_architecture_arch STREQUAL arm64 ) AND TEST_arch_${TEST_architecture_arch}_subarch_sve
|
CONDITION ( TEST_architecture_arch STREQUAL arm64 ) AND ( TEST_arch_${TEST_architecture_arch}_subarch_sve OR TEST_subarch_sve )
|
||||||
)
|
)
|
||||||
qt_feature_definition("arm_sve" "QT_COMPILER_SUPPORTS_SVE" VALUE "1")
|
qt_feature_definition("arm_sve" "QT_COMPILER_SUPPORTS_SVE" VALUE "1")
|
||||||
qt_feature_config("arm_sve" QMAKE_PRIVATE_CONFIG)
|
qt_feature_config("arm_sve" QMAKE_PRIVATE_CONFIG)
|
||||||
@ -1291,7 +1297,7 @@ qt_configure_add_summary_entry(
|
|||||||
)
|
)
|
||||||
qt_configure_add_summary_entry(
|
qt_configure_add_summary_entry(
|
||||||
TYPE "featureList"
|
TYPE "featureList"
|
||||||
ARGS "neon arm_crc32 arm_crypto"
|
ARGS "neon arm_crc32 arm_crypto arm_sve"
|
||||||
MESSAGE "ARM Extensions"
|
MESSAGE "ARM Extensions"
|
||||||
CONDITION ( TEST_architecture_arch STREQUAL arm ) OR ( TEST_architecture_arch STREQUAL arm64 )
|
CONDITION ( TEST_architecture_arch STREQUAL arm ) OR ( TEST_architecture_arch STREQUAL arm64 )
|
||||||
)
|
)
|
||||||
|
@ -99,7 +99,7 @@ QT_WARNING_DISABLE_INTEL(103)
|
|||||||
|
|
||||||
#define QT_COMPILER_SUPPORTS(x) (QT_COMPILER_SUPPORTS_ ## x - 0)
|
#define QT_COMPILER_SUPPORTS(x) (QT_COMPILER_SUPPORTS_ ## x - 0)
|
||||||
|
|
||||||
#if defined(Q_PROCESSOR_ARM)
|
#if defined(Q_PROCESSOR_ARM_64)
|
||||||
# define QT_COMPILER_SUPPORTS_HERE(x) ((__ARM_FEATURE_ ## x) || (__ ## x ## __) || QT_COMPILER_SUPPORTS(x))
|
# define QT_COMPILER_SUPPORTS_HERE(x) ((__ARM_FEATURE_ ## x) || (__ ## x ## __) || QT_COMPILER_SUPPORTS(x))
|
||||||
# if defined(Q_CC_GNU)
|
# if defined(Q_CC_GNU)
|
||||||
/* GCC requires attributes for a function */
|
/* GCC requires attributes for a function */
|
||||||
@ -107,6 +107,10 @@ QT_WARNING_DISABLE_INTEL(103)
|
|||||||
# else
|
# else
|
||||||
# define QT_FUNCTION_TARGET(x)
|
# define QT_FUNCTION_TARGET(x)
|
||||||
# endif
|
# endif
|
||||||
|
#elif defined(Q_PROCESSOR_ARM_32)
|
||||||
|
/* We do not support for runtime CPU feature switching on ARM32 */
|
||||||
|
# define QT_COMPILER_SUPPORTS_HERE(x) ((__ARM_FEATURE_ ## x) || (__ ## x ## __))
|
||||||
|
# define QT_FUNCTION_TARGET(x)
|
||||||
#elif defined(Q_PROCESSOR_MIPS)
|
#elif defined(Q_PROCESSOR_MIPS)
|
||||||
# define QT_COMPILER_SUPPORTS_HERE(x) (__ ## x ## __)
|
# define QT_COMPILER_SUPPORTS_HERE(x) (__ ## x ## __)
|
||||||
# define QT_FUNCTION_TARGET(x)
|
# define QT_FUNCTION_TARGET(x)
|
||||||
@ -345,7 +349,7 @@ inline uint32x4_t qvsetq_n_u32(uint32_t a, uint32_t b, uint32_t c, uint32_t d)
|
|||||||
|
|
||||||
#if defined(Q_PROCESSOR_ARM_64)
|
#if defined(Q_PROCESSOR_ARM_64)
|
||||||
#if defined(Q_CC_CLANG)
|
#if defined(Q_CC_CLANG)
|
||||||
#define QT_FUNCTION_TARGET_STRING_AES "crypto"
|
#define QT_FUNCTION_TARGET_STRING_AES "aes"
|
||||||
#define QT_FUNCTION_TARGET_STRING_CRC32 "crc"
|
#define QT_FUNCTION_TARGET_STRING_CRC32 "crc"
|
||||||
#define QT_FUNCTION_TARGET_STRING_SVE "sve"
|
#define QT_FUNCTION_TARGET_STRING_SVE "sve"
|
||||||
#elif defined(Q_CC_GNU)
|
#elif defined(Q_CC_GNU)
|
||||||
@ -395,7 +399,7 @@ static const uint64_t qCompilerCpuFeatures = 0
|
|||||||
#if defined __ARM_FEATURE_CRC32
|
#if defined __ARM_FEATURE_CRC32
|
||||||
| CpuFeatureCRC32
|
| CpuFeatureCRC32
|
||||||
#endif
|
#endif
|
||||||
#if defined __ARM_FEATURE_CRYPTO
|
#if defined (__ARM_FEATURE_CRYPTO) || defined(__ARM_FEATURE_AES)
|
||||||
| CpuFeatureAES
|
| CpuFeatureAES
|
||||||
#endif
|
#endif
|
||||||
#endif // Q_OS_LINUX && Q_PROCESSOR_ARM64
|
#endif // Q_OS_LINUX && Q_PROCESSOR_ARM64
|
||||||
|
@ -732,7 +732,7 @@ static size_t aeshash(const uchar *p, size_t len, size_t seed, size_t seed2) noe
|
|||||||
|
|
||||||
// Compared to x86 AES, ARM splits each round into two instructions
|
// Compared to x86 AES, ARM splits each round into two instructions
|
||||||
// and includes the pre-xor instead of the post-xor.
|
// and includes the pre-xor instead of the post-xor.
|
||||||
const auto hash16bytes = [](uint8x16_t &state0, uint8x16_t data) {
|
const auto hash16bytes = [](uint8x16_t &state0, uint8x16_t data) QT_FUNCTION_TARGET(AES) {
|
||||||
auto state1 = state0;
|
auto state1 = state0;
|
||||||
state0 = vaeseq_u8(state0, data);
|
state0 = vaeseq_u8(state0, data);
|
||||||
state0 = vaesmcq_u8(state0);
|
state0 = vaesmcq_u8(state0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user