/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/Arch/AArch64.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- AArch64.cpp - AArch64 (not ARM) Helpers for Tools ------*- 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 | | #include "AArch64.h" |
10 | | #include "../CommonArgs.h" |
11 | | #include "clang/Driver/Driver.h" |
12 | | #include "clang/Driver/DriverDiagnostic.h" |
13 | | #include "clang/Driver/Options.h" |
14 | | #include "llvm/Option/ArgList.h" |
15 | | #include "llvm/TargetParser/AArch64TargetParser.h" |
16 | | #include "llvm/TargetParser/Host.h" |
17 | | |
18 | | using namespace clang::driver; |
19 | | using namespace clang::driver::tools; |
20 | | using namespace clang; |
21 | | using namespace llvm::opt; |
22 | | |
23 | | /// \returns true if the given triple can determine the default CPU type even |
24 | | /// if -arch is not specified. |
25 | 2.19k | static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) { |
26 | 2.19k | return Triple.isOSDarwin(); |
27 | 2.19k | } |
28 | | |
29 | | /// getAArch64TargetCPU - Get the (LLVM) name of the AArch64 cpu we are |
30 | | /// targeting. Set \p A to the Arg corresponding to the -mcpu argument if it is |
31 | | /// provided, or to nullptr otherwise. |
32 | | std::string aarch64::getAArch64TargetCPU(const ArgList &Args, |
33 | 2.30k | const llvm::Triple &Triple, Arg *&A) { |
34 | 2.30k | std::string CPU; |
35 | | // If we have -mcpu, use that. |
36 | 2.30k | if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) { |
37 | 255 | StringRef Mcpu = A->getValue(); |
38 | 255 | CPU = Mcpu.split("+").first.lower(); |
39 | 255 | } |
40 | | |
41 | 2.30k | CPU = llvm::AArch64::resolveCPUAlias(CPU); |
42 | | |
43 | | // Handle CPU name is 'native'. |
44 | 2.30k | if (CPU == "native") |
45 | 1 | return std::string(llvm::sys::getHostCPUName()); |
46 | | |
47 | 2.30k | if (CPU.size()) |
48 | 254 | return CPU; |
49 | | |
50 | 2.05k | if (Triple.isTargetMachineMac() && |
51 | 2.05k | Triple.getArch() == llvm::Triple::aarch64290 ) { |
52 | | // Apple Silicon macs default to M1 CPUs. |
53 | 287 | return "apple-m1"; |
54 | 287 | } |
55 | | |
56 | | // arm64e requires v8.3a and only runs on apple-a12 and later CPUs. |
57 | 1.76k | if (Triple.isArm64e()) |
58 | 18 | return "apple-a12"; |
59 | | |
60 | | // Make sure we pick the appropriate Apple CPU if -arch is used or when |
61 | | // targetting a Darwin OS. |
62 | 1.74k | if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin()1.62k ) |
63 | 279 | return Triple.getArch() == llvm::Triple::aarch64_32 ? "apple-s4"15 |
64 | 279 | : "apple-a7"264 ; |
65 | | |
66 | 1.47k | return "generic"; |
67 | 1.74k | } |
68 | | |
69 | | // Decode AArch64 features from string like +[no]featureA+[no]featureB+... |
70 | | static bool DecodeAArch64Features(const Driver &D, StringRef text, |
71 | | std::vector<StringRef> &Features, |
72 | 450 | const llvm::AArch64::ArchInfo &ArchInfo) { |
73 | 450 | SmallVector<StringRef, 8> Split; |
74 | 450 | text.split(Split, StringRef("+"), -1, false); |
75 | | |
76 | 601 | for (StringRef Feature : Split) { |
77 | 601 | StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature); |
78 | 601 | if (!FeatureName.empty()) |
79 | 595 | Features.push_back(FeatureName); |
80 | 6 | else if (Feature == "neon" || Feature == "noneon"3 ) |
81 | 6 | D.Diag(clang::diag::err_drv_no_neon_modifier); |
82 | 0 | else |
83 | 0 | return false; |
84 | | |
85 | | // +sme implies +bf16. |
86 | | // +sme-f64f64 and +sme-i16i64 both imply +sme. |
87 | 601 | if (Feature == "sme") { |
88 | 3 | Features.push_back("+bf16"); |
89 | 598 | } else if (Feature == "nosme") { |
90 | 4 | Features.push_back("-sme-f64f64"); |
91 | 4 | Features.push_back("-sme-i16i64"); |
92 | 594 | } else if (Feature == "sme-f64f64") { |
93 | 3 | Features.push_back("+sme"); |
94 | 3 | Features.push_back("+bf16"); |
95 | 591 | } else if (Feature == "sme-i16i64") { |
96 | 4 | Features.push_back("+sme"); |
97 | 4 | Features.push_back("+bf16"); |
98 | 587 | } else if (Feature == "nobf16") { |
99 | 4 | Features.push_back("-sme"); |
100 | 4 | Features.push_back("-sme-f64f64"); |
101 | 4 | Features.push_back("-sme-i16i64"); |
102 | 4 | } |
103 | | |
104 | 601 | if (Feature == "sve2") |
105 | 9 | Features.push_back("+sve"); |
106 | 592 | else if (Feature == "sve2-bitperm" || Feature == "sve2-sha3"588 || |
107 | 592 | Feature == "sve2-aes"585 || Feature == "sve2-sm4"580 ) { |
108 | 16 | Features.push_back("+sve"); |
109 | 16 | Features.push_back("+sve2"); |
110 | 576 | } else if (Feature == "nosve") { |
111 | 8 | Features.push_back("-sve2"); |
112 | 8 | Features.push_back("-sve2-bitperm"); |
113 | 8 | Features.push_back("-sve2-sha3"); |
114 | 8 | Features.push_back("-sve2-aes"); |
115 | 8 | Features.push_back("-sve2-sm4"); |
116 | 568 | } else if (Feature == "nosve2") { |
117 | 10 | Features.push_back("-sve2-bitperm"); |
118 | 10 | Features.push_back("-sve2-sha3"); |
119 | 10 | Features.push_back("-sve2-aes"); |
120 | 10 | Features.push_back("-sve2-sm4"); |
121 | 10 | } |
122 | | |
123 | | // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A) |
124 | | // It isn't the case in general that sve implies both f64mm and f32mm |
125 | 601 | if ((ArchInfo == llvm::AArch64::ARMV8_6A || |
126 | 601 | ArchInfo == llvm::AArch64::ARMV8_7A569 || |
127 | 601 | ArchInfo == llvm::AArch64::ARMV8_8A541 || |
128 | 601 | ArchInfo == llvm::AArch64::ARMV8_9A507 || |
129 | 601 | ArchInfo == llvm::AArch64::ARMV9_1A501 || |
130 | 601 | ArchInfo == llvm::AArch64::ARMV9_2A501 || |
131 | 601 | ArchInfo == llvm::AArch64::ARMV9_3A497 || |
132 | 601 | ArchInfo == llvm::AArch64::ARMV9_4A487 ) && |
133 | 601 | Feature == "sve"125 ) |
134 | 5 | Features.push_back("+f32mm"); |
135 | 601 | } |
136 | 450 | return true; |
137 | 450 | } |
138 | | |
139 | | // Check if the CPU name and feature modifiers in -mcpu are legal. If yes, |
140 | | // decode CPU and feature. |
141 | | static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, |
142 | 1.43k | std::vector<StringRef> &Features) { |
143 | 1.43k | std::pair<StringRef, StringRef> Split = Mcpu.split("+"); |
144 | 1.43k | CPU = Split.first; |
145 | 1.43k | const llvm::AArch64::ArchInfo *ArchInfo = &llvm::AArch64::ARMV8A; |
146 | | |
147 | 1.43k | if (CPU == "native") |
148 | 1 | CPU = llvm::sys::getHostCPUName(); |
149 | | |
150 | 1.43k | if (CPU == "generic") { |
151 | 46 | Features.push_back("+neon"); |
152 | 1.39k | } else { |
153 | 1.39k | const std::optional<llvm::AArch64::CpuInfo> CpuInfo = |
154 | 1.39k | llvm::AArch64::parseCpu(CPU); |
155 | 1.39k | if (!CpuInfo) |
156 | 3 | return false; |
157 | 1.38k | ArchInfo = &CpuInfo->Arch; |
158 | | |
159 | 1.38k | Features.push_back(ArchInfo->ArchFeature); |
160 | | |
161 | 1.38k | auto Extension = CpuInfo->getImpliedExtensions(); |
162 | 1.38k | if (!llvm::AArch64::getExtensionFeatures(Extension, Features)) |
163 | 0 | return false; |
164 | 1.38k | } |
165 | | |
166 | 1.43k | if (Split.second.size() && |
167 | 1.43k | !DecodeAArch64Features(D, Split.second, Features, *ArchInfo)50 ) |
168 | 0 | return false; |
169 | | |
170 | 1.43k | return true; |
171 | 1.43k | } |
172 | | |
173 | | static bool |
174 | | getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, |
175 | | const ArgList &Args, |
176 | 1.39k | std::vector<StringRef> &Features) { |
177 | 1.39k | std::string MarchLowerCase = March.lower(); |
178 | 1.39k | std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+"); |
179 | | |
180 | 1.39k | std::optional <llvm::AArch64::ArchInfo> ArchInfo = |
181 | 1.39k | llvm::AArch64::parseArch(Split.first); |
182 | 1.39k | if (Split.first == "native") |
183 | 0 | ArchInfo = llvm::AArch64::getArchForCpu(llvm::sys::getHostCPUName().str()); |
184 | 1.39k | if (!ArchInfo) |
185 | 8 | return false; |
186 | 1.39k | Features.push_back(ArchInfo->ArchFeature); |
187 | | |
188 | | // Enable SVE2 by default on Armv9-A. |
189 | | // It can still be disabled if +nosve2 is present. |
190 | | // We must do this early so that DecodeAArch64Features has the correct state |
191 | 1.39k | if ((*ArchInfo == llvm::AArch64::ARMV9A || |
192 | 1.39k | *ArchInfo == llvm::AArch64::ARMV9_1A1.36k || |
193 | 1.39k | *ArchInfo == llvm::AArch64::ARMV9_2A1.34k )) { |
194 | 63 | Features.push_back("+sve"); |
195 | 63 | Features.push_back("+sve2"); |
196 | 63 | } |
197 | | |
198 | 1.39k | if ((Split.second.size() && |
199 | 1.39k | !DecodeAArch64Features(D, Split.second, Features, *ArchInfo)400 )) |
200 | 0 | return false; |
201 | | |
202 | 1.39k | return true; |
203 | 1.39k | } |
204 | | |
205 | | static bool |
206 | | getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, |
207 | | const ArgList &Args, |
208 | 437 | std::vector<StringRef> &Features) { |
209 | 437 | StringRef CPU; |
210 | 437 | std::string McpuLowerCase = Mcpu.lower(); |
211 | 437 | if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features)) |
212 | 2 | return false; |
213 | | |
214 | 435 | return true; |
215 | 437 | } |
216 | | |
217 | | static bool |
218 | | getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, |
219 | | const ArgList &Args, |
220 | 575 | std::vector<StringRef> &Features) { |
221 | 575 | std::string MtuneLowerCase = Mtune.lower(); |
222 | | // Check CPU name is valid |
223 | 575 | std::vector<StringRef> MtuneFeatures; |
224 | 575 | StringRef Tune; |
225 | 575 | if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures)) |
226 | 1 | return false; |
227 | | |
228 | | // Handle CPU name is 'native'. |
229 | 574 | if (MtuneLowerCase == "native") |
230 | 0 | MtuneLowerCase = std::string(llvm::sys::getHostCPUName()); |
231 | 574 | if (MtuneLowerCase == "cyclone" || |
232 | 574 | StringRef(MtuneLowerCase).startswith("apple")561 ) { |
233 | 220 | Features.push_back("+zcm"); |
234 | 220 | Features.push_back("+zcz"); |
235 | 220 | } |
236 | 574 | return true; |
237 | 575 | } |
238 | | |
239 | | static bool |
240 | | getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, |
241 | | const ArgList &Args, |
242 | 426 | std::vector<StringRef> &Features) { |
243 | 426 | StringRef CPU; |
244 | 426 | std::vector<StringRef> DecodedFeature; |
245 | 426 | std::string McpuLowerCase = Mcpu.lower(); |
246 | 426 | if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature)) |
247 | 0 | return false; |
248 | | |
249 | 426 | return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features); |
250 | 426 | } |
251 | | |
252 | | void aarch64::getAArch64TargetFeatures(const Driver &D, |
253 | | const llvm::Triple &Triple, |
254 | | const ArgList &Args, |
255 | | std::vector<StringRef> &Features, |
256 | 1.83k | bool ForAS) { |
257 | 1.83k | Arg *A; |
258 | 1.83k | bool success = true; |
259 | | // Enable NEON by default. |
260 | 1.83k | Features.push_back("+neon"); |
261 | 1.83k | llvm::StringRef WaMArch; |
262 | 1.83k | if (ForAS) |
263 | 30 | for (const auto *A : |
264 | 30 | Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) |
265 | 12 | for (StringRef Value : A->getValues()) |
266 | 13 | if (Value.startswith("-march=")) |
267 | 13 | WaMArch = Value.substr(7); |
268 | | // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or |
269 | | // "-Xassembler -march" is detected. Otherwise it may return false |
270 | | // and causes Clang to error out. |
271 | 1.83k | if (!WaMArch.empty()) |
272 | 9 | success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Features); |
273 | 1.82k | else if ((A = Args.getLastArg(options::OPT_march_EQ))) |
274 | 719 | success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features); |
275 | 1.10k | else if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) |
276 | 242 | success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features); |
277 | 866 | else if (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple)807 ) |
278 | 195 | success = getAArch64ArchFeaturesFromMcpu( |
279 | 195 | D, getAArch64TargetCPU(Args, Triple, A), Args, Features); |
280 | 671 | else |
281 | | // Default to 'A' profile if the architecture is not specified. |
282 | 671 | success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Features); |
283 | | |
284 | 1.83k | if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ))1.82k ) |
285 | 149 | success = |
286 | 149 | getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features); |
287 | 1.68k | else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ))1.67k ) |
288 | 232 | success = |
289 | 232 | getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features); |
290 | 1.45k | else if (success && |
291 | 1.45k | (1.44k Args.hasArg(options::OPT_arch)1.44k || isCPUDeterminedByTriple(Triple)1.38k )) |
292 | 194 | success = getAArch64MicroArchFeaturesFromMcpu( |
293 | 194 | D, getAArch64TargetCPU(Args, Triple, A), Args, Features); |
294 | | |
295 | 1.83k | if (!success) { |
296 | 11 | auto Diag = D.Diag(diag::err_drv_unsupported_option_argument); |
297 | | // If "-Wa,-march=" is used, 'WaMArch' will contain the argument's value, |
298 | | // while 'A' is uninitialized. Only dereference 'A' in the other case. |
299 | 11 | if (!WaMArch.empty()) |
300 | 2 | Diag << "-march=" << WaMArch; |
301 | 9 | else |
302 | 9 | Diag << A->getSpelling() << A->getValue(); |
303 | 11 | } |
304 | | |
305 | 1.83k | if (Args.getLastArg(options::OPT_mgeneral_regs_only)) { |
306 | 2 | Features.push_back("-fp-armv8"); |
307 | 2 | Features.push_back("-crypto"); |
308 | 2 | Features.push_back("-neon"); |
309 | 2 | } |
310 | | |
311 | 1.83k | if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) { |
312 | 9 | StringRef Mtp = A->getValue(); |
313 | 9 | if (Mtp == "el3" || Mtp == "tpidr_el3"8 ) |
314 | 2 | Features.push_back("+tpidr-el3"); |
315 | 7 | else if (Mtp == "el2" || Mtp == "tpidr_el2"6 ) |
316 | 2 | Features.push_back("+tpidr-el2"); |
317 | 5 | else if (Mtp == "el1" || Mtp == "tpidr_el1"4 ) |
318 | 2 | Features.push_back("+tpidr-el1"); |
319 | 3 | else if (Mtp == "tpidrro_el0") |
320 | 1 | Features.push_back("+tpidrro-el0"); |
321 | 2 | else if (Mtp != "el0" && Mtp != "tpidr_el0"1 ) |
322 | 0 | D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args); |
323 | 9 | } |
324 | | |
325 | | // Enable/disable straight line speculation hardening. |
326 | 1.83k | if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) { |
327 | 17 | StringRef Scope = A->getValue(); |
328 | 17 | bool EnableRetBr = false; |
329 | 17 | bool EnableBlr = false; |
330 | 17 | bool DisableComdat = false; |
331 | 17 | if (Scope != "none") { |
332 | 15 | SmallVector<StringRef, 4> Opts; |
333 | 15 | Scope.split(Opts, ","); |
334 | 30 | for (auto Opt : Opts) { |
335 | 30 | Opt = Opt.trim(); |
336 | 30 | if (Opt == "all") { |
337 | 4 | EnableBlr = true; |
338 | 4 | EnableRetBr = true; |
339 | 4 | continue; |
340 | 4 | } |
341 | 26 | if (Opt == "retbr") { |
342 | 10 | EnableRetBr = true; |
343 | 10 | continue; |
344 | 10 | } |
345 | 16 | if (Opt == "blr") { |
346 | 6 | EnableBlr = true; |
347 | 6 | continue; |
348 | 6 | } |
349 | 10 | if (Opt == "comdat") { |
350 | 1 | DisableComdat = false; |
351 | 1 | continue; |
352 | 1 | } |
353 | 9 | if (Opt == "nocomdat") { |
354 | 3 | DisableComdat = true; |
355 | 3 | continue; |
356 | 3 | } |
357 | 6 | D.Diag(diag::err_drv_unsupported_option_argument) |
358 | 6 | << A->getSpelling() << Scope; |
359 | 6 | break; |
360 | 9 | } |
361 | 15 | } |
362 | | |
363 | 17 | if (EnableRetBr) |
364 | 12 | Features.push_back("+harden-sls-retbr"); |
365 | 17 | if (EnableBlr) |
366 | 10 | Features.push_back("+harden-sls-blr"); |
367 | 17 | if (DisableComdat) { |
368 | 3 | Features.push_back("+harden-sls-nocomdat"); |
369 | 3 | } |
370 | 17 | } |
371 | | |
372 | | // En/disable crc |
373 | 1.83k | if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) { |
374 | 2 | if (A->getOption().matches(options::OPT_mcrc)) |
375 | 2 | Features.push_back("+crc"); |
376 | 0 | else |
377 | 0 | Features.push_back("-crc"); |
378 | 2 | } |
379 | | |
380 | 1.83k | int V8Version = -1; |
381 | 1.83k | int V9Version = -1; |
382 | 1.83k | bool HasNoSM4 = false; |
383 | 1.83k | bool HasNoSHA3 = false; |
384 | 1.83k | bool HasNoSHA2 = false; |
385 | 1.83k | bool HasNoAES = false; |
386 | 1.83k | bool HasSM4 = false; |
387 | 1.83k | bool HasSHA3 = false; |
388 | 1.83k | bool HasSHA2 = false; |
389 | 1.83k | bool HasAES = false; |
390 | 1.83k | bool HasCrypto = false; |
391 | 1.83k | bool HasNoCrypto = false; |
392 | 1.83k | int FullFP16Pos = -1; |
393 | 1.83k | int NoFullFP16Pos = -1; |
394 | 1.83k | int FP16FMLPos = -1; |
395 | 1.83k | int NoFP16FMLPos = -1; |
396 | 1.83k | int ArchFeatPos = -1; |
397 | | |
398 | 10.4k | for (auto I = Features.begin(), E = Features.end(); I != E; I++8.60k ) { |
399 | 8.60k | if (*I == "+v8a") V8Version = 01.03k ; |
400 | 7.57k | else if (*I == "+v8.1a") V8Version = 155 ; |
401 | 7.51k | else if (*I == "+v8.2a") V8Version = 2169 ; |
402 | 7.34k | else if (*I == "+v8.3a") V8Version = 360 ; |
403 | 7.28k | else if (*I == "+v8.4a") V8Version = 458 ; |
404 | 7.23k | else if (*I == "+v8.5a") V8Version = 5152 ; |
405 | 7.07k | else if (*I == "+v8.6a") V8Version = 641 ; |
406 | 7.03k | else if (*I == "+v8.7a") V8Version = 739 ; |
407 | 6.99k | else if (*I == "+v8.8a") V8Version = 844 ; |
408 | 6.95k | else if (*I == "+v8.9a") V8Version = 922 ; |
409 | 6.93k | else if (*I == "+v9a") V9Version = 040 ; |
410 | 6.89k | else if (*I == "+v9.1a") V9Version = 114 ; |
411 | 6.87k | else if (*I == "+v9.2a") V9Version = 219 ; |
412 | 6.85k | else if (*I == "+v9.3a") V9Version = 330 ; |
413 | 6.82k | else if (*I == "+v9.4a") V9Version = 430 ; |
414 | 6.79k | else if (*I == "+sm4") HasSM4 = true8 ; |
415 | 6.79k | else if (*I == "+sha3") HasSHA3 = true107 ; |
416 | 6.68k | else if (*I == "+sha2") HasSHA2 = true410 ; |
417 | 6.27k | else if (*I == "+aes") HasAES = true410 ; |
418 | 5.86k | else if (*I == "-sm4") HasNoSM4 = true2 ; |
419 | 5.86k | else if (*I == "-sha3") HasNoSHA3 = true2 ; |
420 | 5.86k | else if (*I == "-sha2") HasNoSHA2 = true2 ; |
421 | 5.85k | else if (*I == "-aes") HasNoAES = true2 ; |
422 | 5.85k | else if (*I == "+fp16fml") FP16FMLPos = I - Features.begin()173 ; |
423 | 5.68k | else if (*I == "-fp16fml") NoFP16FMLPos = I - Features.begin()34 ; |
424 | 5.64k | else if (*I == "-fullfp16") NoFullFP16Pos = I - Features.begin()34 ; |
425 | 5.61k | else if (*I == "+fullfp16") FullFP16Pos = I - Features.begin()286 ; |
426 | | // Whichever option comes after (right-most option) will win |
427 | 5.32k | else if (*I == "+crypto") { |
428 | 29 | HasCrypto = true; |
429 | 29 | HasNoCrypto = false; |
430 | 5.30k | } else if (*I == "-crypto" || *I == "-neon"5.28k ) { |
431 | 35 | HasCrypto = false; |
432 | 35 | HasNoCrypto = true; |
433 | 35 | HasSM4 = HasSHA2 = HasSHA3 = HasAES = false; |
434 | 35 | } |
435 | | // Register the iterator position if this is an architecture feature |
436 | 8.60k | if (ArchFeatPos == -1 && (3.70k V8Version != -13.70k || V9Version != -12.03k )) |
437 | 1.80k | ArchFeatPos = I - Features.begin(); |
438 | 8.60k | } |
439 | | |
440 | | // Handle (arch-dependent) fp16fml/fullfp16 relationship. |
441 | | // FIXME: this fp16fml option handling will be reimplemented after the |
442 | | // TargetParser rewrite. |
443 | 1.83k | if (V8Version >= 4) { |
444 | | // "-fullfp16" "+fullfp16" && "+fp16fml" "+fullfp16" && no "+fullfp16" "-fp16fml" = "+fp16fml" |
445 | 356 | if (FullFP16Pos > NoFullFP16Pos && FullFP16Pos > FP16FMLPos138 && FullFP16Pos > NoFP16FMLPos37 ) |
446 | | // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml. |
447 | | // Only append the +fp16fml if there is no -fp16fml after the +fullfp16. |
448 | 26 | Features.push_back("+fp16fml"); |
449 | 330 | else |
450 | 330 | goto fp16_fml_fallthrough; |
451 | 1.48k | } else { |
452 | 1.81k | fp16_fml_fallthrough: |
453 | | // In both of these cases, putting the 'other' feature on the end of the vector will |
454 | | // result in the same effect as placing it immediately after the current feature. |
455 | | // "+fp16fml" "-fullfp16" = "-fp16fml" |
456 | 1.81k | if (NoFullFP16Pos > FP16FMLPos) |
457 | 18 | Features.push_back("-fp16fml"); |
458 | | // "-fullfp16" "+fp16fml" = "+fullfp16" |
459 | 1.79k | else if (NoFullFP16Pos < FP16FMLPos) |
460 | 157 | Features.push_back("+fullfp16"); |
461 | 1.81k | } |
462 | | |
463 | | // FIXME: this needs reimplementation too after the TargetParser rewrite |
464 | | // |
465 | | // Context sensitive meaning of Crypto: |
466 | | // 1) For Arch >= ARMv8.4a: crypto = sm4 + sha3 + sha2 + aes |
467 | | // 2) For Arch <= ARMv8.3a: crypto = sha2 + aes |
468 | 1.83k | if (V8Version >= 4 || V9Version >= 01.48k ) { |
469 | 489 | if (HasCrypto && !HasNoCrypto10 ) { |
470 | | // Check if we have NOT disabled an algorithm with something like: |
471 | | // +crypto, -algorithm |
472 | | // And if "-algorithm" does not occur, we enable that crypto algorithm. |
473 | 10 | if (!HasNoSM4) |
474 | 9 | Features.push_back("+sm4"); |
475 | 10 | if (!HasNoSHA3) |
476 | 9 | Features.push_back("+sha3"); |
477 | 10 | if (!HasNoSHA2) |
478 | 10 | Features.push_back("+sha2"); |
479 | 10 | if (!HasNoAES) |
480 | 10 | Features.push_back("+aes"); |
481 | 479 | } else if (HasNoCrypto) { |
482 | | // Check if we have NOT enabled a crypto algorithm with something like: |
483 | | // -crypto, +algorithm |
484 | | // And if "+algorithm" does not occur, we disable that crypto algorithm. |
485 | 4 | if (!HasSM4) |
486 | 4 | Features.push_back("-sm4"); |
487 | 4 | if (!HasSHA3) |
488 | 4 | Features.push_back("-sha3"); |
489 | 4 | if (!HasSHA2) |
490 | 4 | Features.push_back("-sha2"); |
491 | 4 | if (!HasAES) |
492 | 4 | Features.push_back("-aes"); |
493 | 4 | } |
494 | 1.34k | } else { |
495 | 1.34k | if (HasCrypto && !HasNoCrypto14 ) { |
496 | 14 | if (!HasNoSHA2) |
497 | 13 | Features.push_back("+sha2"); |
498 | 14 | if (!HasNoAES) |
499 | 13 | Features.push_back("+aes"); |
500 | 1.33k | } else if (HasNoCrypto) { |
501 | 23 | if (!HasSHA2) |
502 | 22 | Features.push_back("-sha2"); |
503 | 23 | if (!HasAES) |
504 | 22 | Features.push_back("-aes"); |
505 | 23 | if (V8Version == 2 || V8Version == 322 ) { |
506 | 3 | Features.push_back("-sm4"); |
507 | 3 | Features.push_back("-sha3"); |
508 | 3 | } |
509 | 23 | } |
510 | 1.34k | } |
511 | | |
512 | 1.83k | if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access, |
513 | 1.83k | options::OPT_munaligned_access)) { |
514 | 8 | if (A->getOption().matches(options::OPT_mno_unaligned_access)) |
515 | 5 | Features.push_back("+strict-align"); |
516 | 1.82k | } else if (Triple.isOSOpenBSD()) |
517 | 11 | Features.push_back("+strict-align"); |
518 | | |
519 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x1)) |
520 | 3 | Features.push_back("+reserve-x1"); |
521 | | |
522 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x2)) |
523 | 3 | Features.push_back("+reserve-x2"); |
524 | | |
525 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x3)) |
526 | 2 | Features.push_back("+reserve-x3"); |
527 | | |
528 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x4)) |
529 | 2 | Features.push_back("+reserve-x4"); |
530 | | |
531 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x5)) |
532 | 2 | Features.push_back("+reserve-x5"); |
533 | | |
534 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x6)) |
535 | 2 | Features.push_back("+reserve-x6"); |
536 | | |
537 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x7)) |
538 | 2 | Features.push_back("+reserve-x7"); |
539 | | |
540 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x9)) |
541 | 2 | Features.push_back("+reserve-x9"); |
542 | | |
543 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x10)) |
544 | 2 | Features.push_back("+reserve-x10"); |
545 | | |
546 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x11)) |
547 | 2 | Features.push_back("+reserve-x11"); |
548 | | |
549 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x12)) |
550 | 2 | Features.push_back("+reserve-x12"); |
551 | | |
552 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x13)) |
553 | 2 | Features.push_back("+reserve-x13"); |
554 | | |
555 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x14)) |
556 | 2 | Features.push_back("+reserve-x14"); |
557 | | |
558 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x15)) |
559 | 2 | Features.push_back("+reserve-x15"); |
560 | | |
561 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x18)) |
562 | 7 | Features.push_back("+reserve-x18"); |
563 | | |
564 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x20)) |
565 | 2 | Features.push_back("+reserve-x20"); |
566 | | |
567 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x21)) |
568 | 2 | Features.push_back("+reserve-x21"); |
569 | | |
570 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x22)) |
571 | 2 | Features.push_back("+reserve-x22"); |
572 | | |
573 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x23)) |
574 | 2 | Features.push_back("+reserve-x23"); |
575 | | |
576 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x24)) |
577 | 2 | Features.push_back("+reserve-x24"); |
578 | | |
579 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x25)) |
580 | 2 | Features.push_back("+reserve-x25"); |
581 | | |
582 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x26)) |
583 | 2 | Features.push_back("+reserve-x26"); |
584 | | |
585 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x27)) |
586 | 2 | Features.push_back("+reserve-x27"); |
587 | | |
588 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x28)) |
589 | 2 | Features.push_back("+reserve-x28"); |
590 | | |
591 | 1.83k | if (Args.hasArg(options::OPT_ffixed_x30)) |
592 | 1 | Features.push_back("+reserve-x30"); |
593 | | |
594 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x8)) |
595 | 2 | Features.push_back("+call-saved-x8"); |
596 | | |
597 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x9)) |
598 | 2 | Features.push_back("+call-saved-x9"); |
599 | | |
600 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x10)) |
601 | 2 | Features.push_back("+call-saved-x10"); |
602 | | |
603 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x11)) |
604 | 2 | Features.push_back("+call-saved-x11"); |
605 | | |
606 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x12)) |
607 | 2 | Features.push_back("+call-saved-x12"); |
608 | | |
609 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x13)) |
610 | 2 | Features.push_back("+call-saved-x13"); |
611 | | |
612 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x14)) |
613 | 2 | Features.push_back("+call-saved-x14"); |
614 | | |
615 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x15)) |
616 | 2 | Features.push_back("+call-saved-x15"); |
617 | | |
618 | 1.83k | if (Args.hasArg(options::OPT_fcall_saved_x18)) |
619 | 3 | Features.push_back("+call-saved-x18"); |
620 | | |
621 | 1.83k | if (Args.hasArg(options::OPT_mno_neg_immediates)) |
622 | 1 | Features.push_back("+no-neg-immediates"); |
623 | | |
624 | 1.83k | if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769, |
625 | 1.83k | options::OPT_mno_fix_cortex_a53_835769)) { |
626 | 6 | if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769)) |
627 | 3 | Features.push_back("+fix-cortex-a53-835769"); |
628 | 3 | else |
629 | 3 | Features.push_back("-fix-cortex-a53-835769"); |
630 | 1.83k | } else if (Triple.isAndroid() || Triple.isOHOSFamily()1.75k ) { |
631 | | // Enabled A53 errata (835769) workaround by default on android |
632 | 78 | Features.push_back("+fix-cortex-a53-835769"); |
633 | 1.75k | } else if (Triple.isOSFuchsia()) { |
634 | 20 | std::string CPU = getCPUName(D, Args, Triple); |
635 | 20 | if (CPU.empty() || CPU == "generic" || CPU == "cortex-a53"2 ) |
636 | 19 | Features.push_back("+fix-cortex-a53-835769"); |
637 | 20 | } |
638 | | |
639 | 1.83k | if (Args.getLastArg(options::OPT_mno_bti_at_return_twice)) |
640 | 0 | Features.push_back("+no-bti-at-return-twice"); |
641 | 1.83k | } |