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"
8SET_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
21PALIMPORT
22VOID
23PALAPI
24PAL_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