1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | #include "pal/palinternal.h" |
7 | #include "pal/dbgmsg.h" |
8 | SET_DEFAULT_DEBUG_CHANNEL(MISC); |
9 | |
10 | #if defined(_ARM64_) |
11 | #define _TARGET_ARM64_ |
12 | #endif |
13 | |
14 | #include "../../../inc/corjitflags.h" |
15 | |
16 | #if HAVE_AUXV_HWCAP_H |
17 | #include <sys/auxv.h> |
18 | #include <asm/hwcap.h> |
19 | #endif |
20 | |
21 | PALIMPORT |
22 | VOID |
23 | PALAPI |
24 | PAL_GetJitCpuCapabilityFlags(CORJIT_FLAGS *flags) |
25 | { |
26 | _ASSERTE(flags); |
27 | |
28 | #if defined(_ARM64_) |
29 | #if HAVE_AUXV_HWCAP_H |
30 | unsigned long hwCap = getauxval(AT_HWCAP); |
31 | |
32 | CORJIT_FLAGS &CPUCompileFlags = *flags; |
33 | // HWCAP_* flags are introduced by ARM into the Linux kernel as new extensions are published. |
34 | // For a given kernel, some of these flags may not be present yet. |
35 | // Use ifdef for each to allow for compilation with any vintage kernel. |
36 | // From a single binary distribution perspective, compiling with latest kernel asm/hwcap.h should |
37 | // include all published flags. Given flags are merged to kernel and published before silicon is |
38 | // available, using the latest kernel for release should be sufficient. |
39 | #ifdef HWCAP_AES |
40 | if (hwCap & HWCAP_AES) |
41 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_AES); |
42 | #endif |
43 | #ifdef HWCAP_ATOMICS |
44 | if (hwCap & HWCAP_ATOMICS) |
45 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_ATOMICS); |
46 | #endif |
47 | #ifdef HWCAP_CRC32 |
48 | if (hwCap & HWCAP_CRC32) |
49 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_CRC32); |
50 | #endif |
51 | #ifdef HWCAP_DCPOP |
52 | if (hwCap & HWCAP_DCPOP) |
53 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DCPOP); |
54 | #endif |
55 | #ifdef HWCAP_ASIMDDP |
56 | if (hwCap & HWCAP_ASIMDDP) |
57 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_DP); |
58 | #endif |
59 | #ifdef HWCAP_FCMA |
60 | if (hwCap & HWCAP_FCMA) |
61 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FCMA); |
62 | #endif |
63 | #ifdef HWCAP_FP |
64 | if (hwCap & HWCAP_FP) |
65 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); |
66 | #endif |
67 | #ifdef HWCAP_FPHP |
68 | if (hwCap & HWCAP_FPHP) |
69 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP16); |
70 | #endif |
71 | #ifdef HWCAP_JSCVT |
72 | if (hwCap & HWCAP_JSCVT) |
73 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_JSCVT); |
74 | #endif |
75 | #ifdef HWCAP_LRCPC |
76 | if (hwCap & HWCAP_LRCPC) |
77 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_LRCPC); |
78 | #endif |
79 | #ifdef HWCAP_PMULL |
80 | if (hwCap & HWCAP_PMULL) |
81 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_PMULL); |
82 | #endif |
83 | #ifdef HWCAP_SHA1 |
84 | if (hwCap & HWCAP_SHA1) |
85 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA1); |
86 | #endif |
87 | #ifdef HWCAP_SHA2 |
88 | if (hwCap & HWCAP_SHA2) |
89 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA256); |
90 | #endif |
91 | #ifdef HWCAP_SHA512 |
92 | if (hwCap & HWCAP_SHA512) |
93 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA512); |
94 | #endif |
95 | #ifdef HWCAP_SHA3 |
96 | if (hwCap & HWCAP_SHA3) |
97 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SHA3); |
98 | #endif |
99 | #ifdef HWCAP_ASIMD |
100 | if (hwCap & HWCAP_ASIMD) |
101 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SIMD); |
102 | #endif |
103 | #ifdef HWCAP_ASIMDRDM |
104 | if (hwCap & HWCAP_ASIMDRDM) |
105 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SIMD_V81); |
106 | #endif |
107 | #ifdef HWCAP_ASIMDHP |
108 | if (hwCap & HWCAP_ASIMDHP) |
109 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SIMD_FP16); |
110 | #endif |
111 | #ifdef HWCAP_SM3 |
112 | if (hwCap & HWCAP_SM3) |
113 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM3); |
114 | #endif |
115 | #ifdef HWCAP_SM4 |
116 | if (hwCap & HWCAP_SM4) |
117 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SM4); |
118 | #endif |
119 | #ifdef HWCAP_SVE |
120 | if (hwCap & HWCAP_SVE) |
121 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SVE); |
122 | #endif |
123 | #else // !HAVE_AUXV_HWCAP_H |
124 | // CoreCLR SIMD and FP support is included in ARM64 baseline |
125 | // On exceptional basis platforms may leave out support, but CoreCLR does not |
126 | // yet support such platforms |
127 | // Set baseline flags if OS has not exposed mechanism for us to determine CPU capabilities |
128 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_SIMD); |
129 | CPUCompileFlags.Set(CORJIT_FLAGS::CORJIT_FLAG_HAS_ARM64_FP); |
130 | #endif // HAVE_AUXV_HWCAP_H |
131 | #endif // defined(_ARM64_) |
132 | } |
133 | |