mirror of
https://github.com/SerenityOS/serenity
synced 2026-05-15 03:16:44 +02:00
The helper doesn't use __builtin_cpu_supports (and instead makes raw cpuid calls) because of three reasons: - __builtin_cpu_supports only works on x86_64, so its usage need to be guarded with the preprocessor similarly to the current code. Moreover, we will have to use custom mechanisms to detect features on ARM, since there isn't such thing as cpuid there (and __builtin_cpu_* are not provided). - __builtin_cpu_supports doesn't support "sha" feature on all targeted toolchains currently. - And, of course, NIH.
54 lines
1.1 KiB
C++
54 lines
1.1 KiB
C++
/*
|
|
* Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include <AK/CPUFeatures.h>
|
|
|
|
namespace AK {
|
|
|
|
#ifndef KERNEL
|
|
# if ARCH(I386) || ARCH(X86_64)
|
|
struct CPUIDResult {
|
|
u32 eax { 0 };
|
|
u32 ebx { 0 };
|
|
u32 ecx { 0 };
|
|
u32 edx { 0 };
|
|
};
|
|
|
|
static CPUIDResult cpuid(u32 leaf, u32 subleaf)
|
|
{
|
|
CPUIDResult result;
|
|
asm("cpuid"
|
|
: "=a"(result.eax), "=b"(result.ebx), "=c"(result.ecx), "=d"(result.edx)
|
|
: "0"(leaf), "2"(subleaf));
|
|
return result;
|
|
}
|
|
# endif
|
|
|
|
CPUFeatures Detail::detect_cpu_features_uncached()
|
|
{
|
|
CPUFeatures result = CPUFeatures::None;
|
|
|
|
# if ARCH(I386) || ARCH(X86_64)
|
|
u32 max_leaf = cpuid(0, 0).eax;
|
|
[[maybe_unused]] auto cpuid1 = max_leaf >= 1 ? cpuid(1, 0) : CPUIDResult {};
|
|
[[maybe_unused]] auto cpuid7 = max_leaf >= 7 ? cpuid(7, 0) : CPUIDResult {};
|
|
|
|
# if AK_CAN_CODEGEN_FOR_X86_SSE42
|
|
if (cpuid1.ecx >> 20 & 1)
|
|
result |= CPUFeatures::X86_SSE42;
|
|
# endif
|
|
# if AK_CAN_CODEGEN_FOR_X86_SHA
|
|
if (cpuid7.ebx >> 29 & 1)
|
|
result |= CPUFeatures::X86_SHA;
|
|
# endif
|
|
# endif
|
|
|
|
return result;
|
|
}
|
|
#endif
|
|
|
|
}
|