1 | //===-- cpu_model/aarch64.c - Support for __cpu_model builtin ----*- C -*-===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file is based on LLVM's lib/Support/Host.cpp. |
10 | // It implements __aarch64_have_lse_atomics, __aarch64_cpu_features for |
11 | // AArch64. |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #include "cpu_model.h" |
16 | |
17 | #if !defined(__aarch64__) |
18 | #error This file is intended only for aarch64-based targets |
19 | #endif |
20 | |
21 | #if __has_include(<sys/ifunc.h>) |
22 | #include <sys/ifunc.h> |
23 | #else |
24 | typedef struct __ifunc_arg_t { |
25 | unsigned long _size; |
26 | unsigned long _hwcap; |
27 | unsigned long _hwcap2; |
28 | } __ifunc_arg_t; |
29 | #endif // __has_include(<sys/ifunc.h>) |
30 | |
31 | // LSE support detection for out-of-line atomics |
32 | // using HWCAP and Auxiliary vector |
33 | _Bool __aarch64_have_lse_atomics |
34 | __attribute__((visibility("hidden" ), nocommon)) = false; |
35 | |
36 | #if defined(__FreeBSD__) |
37 | // clang-format off: should not reorder sys/auxv.h alphabetically |
38 | #include <sys/auxv.h> |
39 | // clang-format on |
40 | #include "aarch64/hwcap.inc" |
41 | #include "aarch64/lse_atomics/freebsd.inc" |
42 | #elif defined(__Fuchsia__) |
43 | #include "aarch64/hwcap.inc" |
44 | #include "aarch64/lse_atomics/fuchsia.inc" |
45 | #elif defined(__ANDROID__) |
46 | #include "aarch64/hwcap.inc" |
47 | #include "aarch64/lse_atomics/android.inc" |
48 | #elif __has_include(<sys/auxv.h>) |
49 | #include "aarch64/hwcap.inc" |
50 | #include "aarch64/lse_atomics/sysauxv.inc" |
51 | #else |
52 | // When unimplemented, we leave __aarch64_have_lse_atomics initialized to false. |
53 | #endif |
54 | |
55 | #if !defined(DISABLE_AARCH64_FMV) |
56 | // CPUFeatures must correspond to the same AArch64 features in |
57 | // AArch64TargetParser.h |
58 | enum CPUFeatures { |
59 | FEAT_RNG, |
60 | FEAT_FLAGM, |
61 | FEAT_FLAGM2, |
62 | FEAT_FP16FML, |
63 | FEAT_DOTPROD, |
64 | FEAT_SM4, |
65 | FEAT_RDM, |
66 | FEAT_LSE, |
67 | FEAT_FP, |
68 | FEAT_SIMD, |
69 | FEAT_CRC, |
70 | FEAT_SHA1, |
71 | FEAT_SHA2, |
72 | FEAT_SHA3, |
73 | FEAT_AES, |
74 | FEAT_PMULL, |
75 | FEAT_FP16, |
76 | FEAT_DIT, |
77 | FEAT_DPB, |
78 | FEAT_DPB2, |
79 | FEAT_JSCVT, |
80 | FEAT_FCMA, |
81 | FEAT_RCPC, |
82 | FEAT_RCPC2, |
83 | FEAT_FRINTTS, |
84 | FEAT_DGH, |
85 | FEAT_I8MM, |
86 | FEAT_BF16, |
87 | FEAT_EBF16, |
88 | FEAT_RPRES, |
89 | FEAT_SVE, |
90 | FEAT_SVE_BF16, |
91 | FEAT_SVE_EBF16, |
92 | FEAT_SVE_I8MM, |
93 | FEAT_SVE_F32MM, |
94 | FEAT_SVE_F64MM, |
95 | FEAT_SVE2, |
96 | FEAT_SVE_AES, |
97 | FEAT_SVE_PMULL128, |
98 | FEAT_SVE_BITPERM, |
99 | FEAT_SVE_SHA3, |
100 | FEAT_SVE_SM4, |
101 | FEAT_SME, |
102 | FEAT_MEMTAG, |
103 | FEAT_MEMTAG2, |
104 | FEAT_MEMTAG3, |
105 | FEAT_SB, |
106 | FEAT_PREDRES, |
107 | FEAT_SSBS, |
108 | FEAT_SSBS2, |
109 | FEAT_BTI, |
110 | FEAT_LS64, |
111 | FEAT_LS64_V, |
112 | FEAT_LS64_ACCDATA, |
113 | FEAT_WFXT, |
114 | FEAT_SME_F64, |
115 | FEAT_SME_I64, |
116 | FEAT_SME2, |
117 | FEAT_RCPC3, |
118 | FEAT_MOPS, |
119 | FEAT_MAX, |
120 | FEAT_EXT = 62, // Reserved to indicate presence of additional features field |
121 | // in __aarch64_cpu_features |
122 | FEAT_INIT // Used as flag of features initialization completion |
123 | }; |
124 | |
125 | // Architecture features used |
126 | // in Function Multi Versioning |
127 | struct { |
128 | unsigned long long features; |
129 | // As features grows new fields could be added |
130 | } __aarch64_cpu_features __attribute__((visibility("hidden" ), nocommon)); |
131 | |
132 | // The formatter wants to re-order these includes, but doing so is incorrect: |
133 | // clang-format off |
134 | #if defined(__APPLE__) |
135 | #include "aarch64/fmv/apple.inc" |
136 | #elif defined(__FreeBSD__) |
137 | #include "aarch64/fmv/mrs.inc" |
138 | #include "aarch64/fmv/freebsd.inc" |
139 | #elif defined(__Fuchsia__) |
140 | #include "aarch64/fmv/fuchsia.inc" |
141 | #elif defined(__ANDROID__) |
142 | #include "aarch64/fmv/mrs.inc" |
143 | #include "aarch64/fmv/android.inc" |
144 | #elif __has_include(<sys/auxv.h>) |
145 | #include "aarch64/fmv/mrs.inc" |
146 | #include "aarch64/fmv/sysauxv.inc" |
147 | #else |
148 | #include "aarch64/fmv/unimplemented.inc" |
149 | #endif |
150 | // clang-format on |
151 | |
152 | #endif // !defined(DISABLE_AARCH64_FMV) |
153 | |