-
-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
AK+LibCrypto: Replace ad-hoc target clones with a generic mechanism
- Checked AVX, AVX2, loop unrolling -- no or negligible (<0.5%) effect - ifdef soup -> well-defined AK_CAN_CODEGEN_FOR_<FEATURE> - ifunc resolvers -> statically initialized function pointers TODO: Write proper description
- Loading branch information
1 parent
2ac61cd
commit ee3a6d9
Showing
3 changed files
with
116 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright (c) 2024, Dan Klishch <[email protected]> | ||
* | ||
* SPDX-License-Identifier: BSD-2-Clause | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <AK/EnumBits.h> | ||
#include <AK/Format.h> | ||
#include <AK/Types.h> | ||
#include <cpuid.h> | ||
|
||
namespace AK { | ||
|
||
enum class CPUFeature : u64 { | ||
None = 0ULL, | ||
Invalid = 1ULL << 63, | ||
|
||
#if !defined(KERNEL) && ARCH(X86_64) | ||
# define AK_CAN_CODEGEN_FOR_X86_SSE42 1 | ||
X86_SSE42 = 1 << 0, | ||
# define AK_CAN_CODEGEN_FOR_X86_AVX 1 | ||
X86_AVX = 1 << 1, | ||
# define AK_CAN_CODEGEN_FOR_X86_SHA 1 | ||
X86_SHA = 1 << 2, | ||
#else | ||
# define AK_CAN_CODEGEN_FOR_X86_SSE42 0 | ||
X86_SSE42 = Invalid, | ||
# define AK_CAN_CODEGEN_FOR_X86_AVX 0 | ||
X86_AVX = Invalid, | ||
# define AK_CAN_CODEGEN_FOR_X86_SHA 0 | ||
X86_SHA = Invalid, | ||
#endif | ||
}; | ||
|
||
AK_ENUM_BITWISE_OPERATORS(CPUFeature); | ||
|
||
inline CPUFeature detect_cpu_features() | ||
{ | ||
static CPUFeature const s_cached_features = [] { | ||
CPUFeature result = CPUFeature::None; | ||
|
||
__builtin_cpu_init(); | ||
|
||
#if AK_CAN_CODEGEN_FOR_X86_SSE42 | ||
if (__builtin_cpu_supports("sse4.2")) | ||
result |= CPUFeature::X86_SSE42; | ||
#endif | ||
|
||
#if AK_CAN_CODEGEN_FOR_X86_AVX | ||
if (__builtin_cpu_supports("avx")) | ||
result |= CPUFeature::X86_AVX; | ||
#endif | ||
|
||
#if AK_CAN_CODEGEN_FOR_X86_SHA | ||
// FIXME: Use __builtin_cpu_supports("sha") when compilers support it | ||
constexpr u32 cpuid_sha_ebx = 1 << 29; | ||
u32 eax, ebx, ecx, edx; | ||
__cpuid_count(7, 0, eax, ebx, ecx, edx); | ||
if (ebx & cpuid_sha_ebx) | ||
result |= CPUFeature::X86_SHA; | ||
#endif | ||
|
||
return result; | ||
}(); | ||
return s_cached_features; | ||
} | ||
|
||
#define AK_UPDATE_SELECTION_IF_FEATURE_SUPPORTED(feature, template_function) \ | ||
if constexpr (((feature) & CPUFeature::Invalid) == CPUFeature::None) { \ | ||
if (has_flag(detect_cpu_features(), (feature))) \ | ||
result = template_function<(feature)>; \ | ||
} | ||
|
||
} | ||
|
||
#ifdef USING_AK_GLOBALLY | ||
using AK::CPUFeature; | ||
using AK::detect_cpu_features; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters