/src/serenity/AK/CPUFeatures.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2024, Dan Klishch <danilklishch@gmail.com> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #include <AK/CPUFeatures.h> |
8 | | |
9 | | namespace AK { |
10 | | |
11 | | #ifndef KERNEL |
12 | | # if ARCH(I386) || ARCH(X86_64) |
13 | | struct CPUIDResult { |
14 | | u32 eax { 0 }; |
15 | | u32 ebx { 0 }; |
16 | | u32 ecx { 0 }; |
17 | | u32 edx { 0 }; |
18 | | }; |
19 | | |
20 | | static CPUIDResult cpuid(u32 leaf, u32 subleaf) |
21 | 30 | { |
22 | 30 | CPUIDResult result; |
23 | 30 | asm("cpuid" |
24 | 30 | : "=a"(result.eax), "=b"(result.ebx), "=c"(result.ecx), "=d"(result.edx) |
25 | 30 | : "0"(leaf), "2"(subleaf)); |
26 | 30 | return result; |
27 | 30 | } |
28 | | # endif |
29 | | |
30 | | CPUFeatures Detail::detect_cpu_features_uncached() |
31 | 10 | { |
32 | 10 | CPUFeatures result = CPUFeatures::None; |
33 | | |
34 | 10 | # if ARCH(I386) || ARCH(X86_64) |
35 | 10 | u32 max_leaf = cpuid(0, 0).eax; |
36 | 10 | [[maybe_unused]] auto cpuid1 = max_leaf >= 1 ? cpuid(1, 0) : CPUIDResult {}; |
37 | 10 | [[maybe_unused]] auto cpuid7 = max_leaf >= 7 ? cpuid(7, 0) : CPUIDResult {}; |
38 | | |
39 | 10 | # if AK_CAN_CODEGEN_FOR_X86_SSE42 |
40 | 10 | if (cpuid1.ecx >> 20 & 1) |
41 | 10 | result |= CPUFeatures::X86_SSE42; |
42 | 10 | # endif |
43 | 10 | # if AK_CAN_CODEGEN_FOR_X86_SHA |
44 | 10 | if (cpuid7.ebx >> 29 & 1) |
45 | 10 | result |= CPUFeatures::X86_SHA; |
46 | 10 | # endif |
47 | 10 | # if AK_CAN_CODEGEN_FOR_X86_AES |
48 | 10 | if (cpuid1.ecx >> 25 & 1) |
49 | 10 | result |= CPUFeatures::X86_AES; |
50 | 10 | # endif |
51 | 10 | # endif |
52 | | |
53 | 10 | return result; |
54 | 10 | } |
55 | | #endif |
56 | | |
57 | | } |