clang  15.0.0git
AArch64.cpp
Go to the documentation of this file.
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 "clang/Driver/Driver.h"
12 #include "clang/Driver/Options.h"
13 #include "llvm/Option/ArgList.h"
14 #include "llvm/Support/AArch64TargetParser.h"
15 #include "llvm/Support/TargetParser.h"
16 #include "llvm/Support/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 static bool isCPUDeterminedByTriple(const llvm::Triple &Triple) {
26  return Triple.isOSDarwin();
27 }
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  const llvm::Triple &Triple, Arg *&A) {
34  std::string CPU;
35  // If we have -mcpu, use that.
36  if ((A = Args.getLastArg(options::OPT_mcpu_EQ))) {
37  StringRef Mcpu = A->getValue();
38  CPU = Mcpu.split("+").first.lower();
39  }
40 
41  // Handle CPU name is 'native'.
42  if (CPU == "native")
43  return std::string(llvm::sys::getHostCPUName());
44 
45  if (CPU.size())
46  return CPU;
47 
48  if (Triple.isTargetMachineMac() &&
49  Triple.getArch() == llvm::Triple::aarch64) {
50  // Apple Silicon macs default to M1 CPUs.
51  return "apple-m1";
52  }
53 
54  // arm64e requires v8.3a and only runs on apple-a12 and later CPUs.
55  if (Triple.isArm64e())
56  return "apple-a12";
57 
58  // Make sure we pick the appropriate Apple CPU if -arch is used or when
59  // targetting a Darwin OS.
60  if (Args.getLastArg(options::OPT_arch) || Triple.isOSDarwin())
61  return Triple.getArch() == llvm::Triple::aarch64_32 ? "apple-s4"
62  : "apple-a7";
63 
64  return "generic";
65 }
66 
67 // Decode AArch64 features from string like +[no]featureA+[no]featureB+...
68 static bool DecodeAArch64Features(const Driver &D, StringRef text,
69  std::vector<StringRef> &Features,
70  llvm::AArch64::ArchKind ArchKind) {
72  text.split(Split, StringRef("+"), -1, false);
73 
74  for (StringRef Feature : Split) {
75  StringRef FeatureName = llvm::AArch64::getArchExtFeature(Feature);
76  if (!FeatureName.empty())
77  Features.push_back(FeatureName);
78  else if (Feature == "neon" || Feature == "noneon")
79  D.Diag(clang::diag::err_drv_no_neon_modifier);
80  else
81  return false;
82 
83  if (Feature == "sve2")
84  Features.push_back("+sve");
85  else if (Feature == "sve2-bitperm" || Feature == "sve2-sha3" ||
86  Feature == "sve2-aes" || Feature == "sve2-sm4") {
87  Features.push_back("+sve");
88  Features.push_back("+sve2");
89  } else if (Feature == "nosve") {
90  Features.push_back("-sve2");
91  Features.push_back("-sve2-bitperm");
92  Features.push_back("-sve2-sha3");
93  Features.push_back("-sve2-aes");
94  Features.push_back("-sve2-sm4");
95  } else if (Feature == "nosve2") {
96  Features.push_back("-sve2-bitperm");
97  Features.push_back("-sve2-sha3");
98  Features.push_back("-sve2-aes");
99  Features.push_back("-sve2-sm4");
100  }
101 
102  // +sve implies +f32mm if the base architecture is >= v8.6A (except v9A)
103  // It isn't the case in general that sve implies both f64mm and f32mm
104  if ((ArchKind == llvm::AArch64::ArchKind::ARMV8_6A ||
105  ArchKind == llvm::AArch64::ArchKind::ARMV8_7A ||
106  ArchKind == llvm::AArch64::ArchKind::ARMV8_8A ||
107  ArchKind == llvm::AArch64::ArchKind::ARMV9_1A ||
108  ArchKind == llvm::AArch64::ArchKind::ARMV9_2A ||
109  ArchKind == llvm::AArch64::ArchKind::ARMV9_3A) &&
110  Feature == "sve")
111  Features.push_back("+f32mm");
112  }
113  return true;
114 }
115 
116 // Check if the CPU name and feature modifiers in -mcpu are legal. If yes,
117 // decode CPU and feature.
118 static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU,
119  std::vector<StringRef> &Features) {
120  std::pair<StringRef, StringRef> Split = Mcpu.split("+");
121  CPU = Split.first;
122  llvm::AArch64::ArchKind ArchKind = llvm::AArch64::ArchKind::ARMV8A;
123 
124  if (CPU == "native")
125  CPU = llvm::sys::getHostCPUName();
126 
127  if (CPU == "generic") {
128  Features.push_back("+neon");
129  } else {
130  ArchKind = llvm::AArch64::parseCPUArch(CPU);
131  if (!llvm::AArch64::getArchFeatures(ArchKind, Features))
132  return false;
133 
134  uint64_t Extension = llvm::AArch64::getDefaultExtensions(CPU, ArchKind);
135  if (!llvm::AArch64::getExtensionFeatures(Extension, Features))
136  return false;
137  }
138 
139  if (Split.second.size() &&
140  !DecodeAArch64Features(D, Split.second, Features, ArchKind))
141  return false;
142 
143  return true;
144 }
145 
146 static bool
147 getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March,
148  const ArgList &Args,
149  std::vector<StringRef> &Features) {
150  std::string MarchLowerCase = March.lower();
151  std::pair<StringRef, StringRef> Split = StringRef(MarchLowerCase).split("+");
152 
153  llvm::AArch64::ArchKind ArchKind = llvm::AArch64::parseArch(Split.first);
154  if (Split.first == "native")
155  ArchKind = llvm::AArch64::getCPUArchKind(llvm::sys::getHostCPUName().str());
156  if (ArchKind == llvm::AArch64::ArchKind::INVALID ||
157  !llvm::AArch64::getArchFeatures(ArchKind, Features))
158  return false;
159 
160  // Enable SVE2 by default on Armv9-A.
161  // It can still be disabled if +nosve2 is present.
162  // We must do this early so that DecodeAArch64Features has the correct state
163  if ((ArchKind == llvm::AArch64::ArchKind::ARMV9A ||
164  ArchKind == llvm::AArch64::ArchKind::ARMV9_1A ||
165  ArchKind == llvm::AArch64::ArchKind::ARMV9_2A)) {
166  Features.push_back("+sve");
167  Features.push_back("+sve2");
168  }
169 
170  if ((Split.second.size() &&
171  !DecodeAArch64Features(D, Split.second, Features, ArchKind)))
172  return false;
173 
174  return true;
175 }
176 
177 static bool
178 getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu,
179  const ArgList &Args,
180  std::vector<StringRef> &Features) {
181  StringRef CPU;
182  std::string McpuLowerCase = Mcpu.lower();
183  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, Features))
184  return false;
185 
186  return true;
187 }
188 
189 static bool
191  const ArgList &Args,
192  std::vector<StringRef> &Features) {
193  std::string MtuneLowerCase = Mtune.lower();
194  // Check CPU name is valid
195  std::vector<StringRef> MtuneFeatures;
196  StringRef Tune;
197  if (!DecodeAArch64Mcpu(D, MtuneLowerCase, Tune, MtuneFeatures))
198  return false;
199 
200  // Handle CPU name is 'native'.
201  if (MtuneLowerCase == "native")
202  MtuneLowerCase = std::string(llvm::sys::getHostCPUName());
203  if (MtuneLowerCase == "cyclone" ||
204  StringRef(MtuneLowerCase).startswith("apple")) {
205  Features.push_back("+zcm");
206  Features.push_back("+zcz");
207  }
208  return true;
209 }
210 
211 static bool
213  const ArgList &Args,
214  std::vector<StringRef> &Features) {
215  StringRef CPU;
216  std::vector<StringRef> DecodedFeature;
217  std::string McpuLowerCase = Mcpu.lower();
218  if (!DecodeAArch64Mcpu(D, McpuLowerCase, CPU, DecodedFeature))
219  return false;
220 
221  return getAArch64MicroArchFeaturesFromMtune(D, CPU, Args, Features);
222 }
223 
225  const llvm::Triple &Triple,
226  const ArgList &Args,
227  std::vector<StringRef> &Features,
228  bool ForAS) {
229  Arg *A;
230  bool success = true;
231  // Enable NEON by default.
232  Features.push_back("+neon");
233  llvm::StringRef WaMArch;
234  if (ForAS)
235  for (const auto *A :
236  Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler))
237  for (StringRef Value : A->getValues())
238  if (Value.startswith("-march="))
239  WaMArch = Value.substr(7);
240  // Call getAArch64ArchFeaturesFromMarch only if "-Wa,-march=" or
241  // "-Xassembler -march" is detected. Otherwise it may return false
242  // and causes Clang to error out.
243  if (!WaMArch.empty())
244  success = getAArch64ArchFeaturesFromMarch(D, WaMArch, Args, Features);
245  else if ((A = Args.getLastArg(options::OPT_march_EQ)))
246  success = getAArch64ArchFeaturesFromMarch(D, A->getValue(), Args, Features);
247  else if ((A = Args.getLastArg(options::OPT_mcpu_EQ)))
248  success = getAArch64ArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
249  else if (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple))
251  D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
252  else
253  // Default to 'A' profile if the architecture is not specified.
254  success = getAArch64ArchFeaturesFromMarch(D, "armv8-a", Args, Features);
255 
256  if (success && (A = Args.getLastArg(clang::driver::options::OPT_mtune_EQ)))
257  success =
258  getAArch64MicroArchFeaturesFromMtune(D, A->getValue(), Args, Features);
259  else if (success && (A = Args.getLastArg(options::OPT_mcpu_EQ)))
260  success =
261  getAArch64MicroArchFeaturesFromMcpu(D, A->getValue(), Args, Features);
262  else if (success &&
263  (Args.hasArg(options::OPT_arch) || isCPUDeterminedByTriple(Triple)))
265  D, getAArch64TargetCPU(Args, Triple, A), Args, Features);
266 
267  if (!success) {
268  auto Diag = D.Diag(diag::err_drv_clang_unsupported);
269  // If "-Wa,-march=" is used, 'WaMArch' will contain the argument's value,
270  // while 'A' is uninitialized. Only dereference 'A' in the other case.
271  if (!WaMArch.empty())
272  Diag << "-march=" + WaMArch.str();
273  else
274  Diag << A->getAsString(Args);
275  }
276 
277  if (Args.getLastArg(options::OPT_mgeneral_regs_only)) {
278  Features.push_back("-fp-armv8");
279  Features.push_back("-crypto");
280  Features.push_back("-neon");
281  }
282 
283  if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
284  StringRef Mtp = A->getValue();
285  if (Mtp == "el3")
286  Features.push_back("+tpidr-el3");
287  else if (Mtp == "el2")
288  Features.push_back("+tpidr-el2");
289  else if (Mtp == "el1")
290  Features.push_back("+tpidr-el1");
291  else if (Mtp != "el0")
292  D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
293  }
294 
295  // Enable/disable straight line speculation hardening.
296  if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
297  StringRef Scope = A->getValue();
298  bool EnableRetBr = false;
299  bool EnableBlr = false;
300  bool DisableComdat = false;
301  if (Scope != "none") {
303  Scope.split(Opts, ",");
304  for (auto Opt : Opts) {
305  Opt = Opt.trim();
306  if (Opt == "all") {
307  EnableBlr = true;
308  EnableRetBr = true;
309  continue;
310  }
311  if (Opt == "retbr") {
312  EnableRetBr = true;
313  continue;
314  }
315  if (Opt == "blr") {
316  EnableBlr = true;
317  continue;
318  }
319  if (Opt == "comdat") {
320  DisableComdat = false;
321  continue;
322  }
323  if (Opt == "nocomdat") {
324  DisableComdat = true;
325  continue;
326  }
327  D.Diag(diag::err_invalid_sls_hardening)
328  << Scope << A->getAsString(Args);
329  break;
330  }
331  }
332 
333  if (EnableRetBr)
334  Features.push_back("+harden-sls-retbr");
335  if (EnableBlr)
336  Features.push_back("+harden-sls-blr");
337  if (DisableComdat) {
338  Features.push_back("+harden-sls-nocomdat");
339  }
340  }
341 
342  // En/disable crc
343  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
344  if (A->getOption().matches(options::OPT_mcrc))
345  Features.push_back("+crc");
346  else
347  Features.push_back("-crc");
348  }
349 
350  int V8Version = -1;
351  int V9Version = -1;
352  bool HasNoSM4 = false;
353  bool HasNoSHA3 = false;
354  bool HasNoSHA2 = false;
355  bool HasNoAES = false;
356  bool HasSM4 = false;
357  bool HasSHA3 = false;
358  bool HasSHA2 = false;
359  bool HasAES = false;
360  bool HasCrypto = false;
361  bool HasNoCrypto = false;
362  int FullFP16Pos = -1;
363  int NoFullFP16Pos = -1;
364  int FP16FMLPos = -1;
365  int NoFP16FMLPos = -1;
366  int ArchFeatPos = -1;
367 
368  for (auto I = Features.begin(), E = Features.end(); I != E; I++) {
369  if (*I == "+v8a") V8Version = 0;
370  else if (*I == "+v8.1a") V8Version = 1;
371  else if (*I == "+v8.2a") V8Version = 2;
372  else if (*I == "+v8.3a") V8Version = 3;
373  else if (*I == "+v8.4a") V8Version = 4;
374  else if (*I == "+v8.5a") V8Version = 5;
375  else if (*I == "+v8.6a") V8Version = 6;
376  else if (*I == "+v8.7a") V8Version = 7;
377  else if (*I == "+v8.8a") V8Version = 8;
378  else if (*I == "+v8.9a") V8Version = 9;
379  else if (*I == "+v9a") V9Version = 0;
380  else if (*I == "+v9.1a") V9Version = 1;
381  else if (*I == "+v9.2a") V9Version = 2;
382  else if (*I == "+v9.3a") V9Version = 3;
383  else if (*I == "+v9.4a") V9Version = 4;
384  else if (*I == "+sm4") HasSM4 = true;
385  else if (*I == "+sha3") HasSHA3 = true;
386  else if (*I == "+sha2") HasSHA2 = true;
387  else if (*I == "+aes") HasAES = true;
388  else if (*I == "-sm4") HasNoSM4 = true;
389  else if (*I == "-sha3") HasNoSHA3 = true;
390  else if (*I == "-sha2") HasNoSHA2 = true;
391  else if (*I == "-aes") HasNoAES = true;
392  else if (*I == "+fp16fml") FP16FMLPos = I - Features.begin();
393  else if (*I == "-fp16fml") NoFP16FMLPos = I - Features.begin();
394  else if (*I == "-fullfp16") NoFullFP16Pos = I - Features.begin();
395  else if (*I == "+fullfp16") FullFP16Pos = I - Features.begin();
396  // Whichever option comes after (right-most option) will win
397  else if (*I == "+crypto") {
398  HasCrypto = true;
399  HasNoCrypto = false;
400  } else if (*I == "-crypto") {
401  HasCrypto = false;
402  HasNoCrypto = true;
403  }
404  // Register the iterator position if this is an architecture feature
405  if (ArchFeatPos == -1 && (V8Version != -1 || V9Version != -1))
406  ArchFeatPos = I - Features.begin();
407  }
408 
409  // Handle (arch-dependent) fp16fml/fullfp16 relationship.
410  // FIXME: this fp16fml option handling will be reimplemented after the
411  // TargetParser rewrite.
412  if (V8Version >= 4) {
413  // "-fullfp16" "+fullfp16" && "+fp16fml" "+fullfp16" && no "+fullfp16" "-fp16fml" = "+fp16fml"
414  if (FullFP16Pos > NoFullFP16Pos && FullFP16Pos > FP16FMLPos && FullFP16Pos > NoFP16FMLPos)
415  // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
416  // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
417  Features.push_back("+fp16fml");
418  else
419  goto fp16_fml_fallthrough;
420  } else {
421 fp16_fml_fallthrough:
422  // In both of these cases, putting the 'other' feature on the end of the vector will
423  // result in the same effect as placing it immediately after the current feature.
424  // "+fp16fml" "-fullfp16" = "-fp16fml"
425  if (NoFullFP16Pos > FP16FMLPos)
426  Features.push_back("-fp16fml");
427  // "-fullfp16" "+fp16fml" = "+fullfp16"
428  else if (NoFullFP16Pos < FP16FMLPos)
429  Features.push_back("+fullfp16");
430  }
431 
432  // FIXME: this needs reimplementation too after the TargetParser rewrite
433  //
434  // Context sensitive meaning of Crypto:
435  // 1) For Arch >= ARMv8.4a: crypto = sm4 + sha3 + sha2 + aes
436  // 2) For Arch <= ARMv8.3a: crypto = sha2 + aes
437  if (V8Version >= 4 || V9Version >= 0) {
438  if (HasCrypto && !HasNoCrypto) {
439  // Check if we have NOT disabled an algorithm with something like:
440  // +crypto, -algorithm
441  // And if "-algorithm" does not occur, we enable that crypto algorithm.
442  if (!HasNoSM4)
443  Features.push_back("+sm4");
444  if (!HasNoSHA3)
445  Features.push_back("+sha3");
446  if (!HasNoSHA2)
447  Features.push_back("+sha2");
448  if (!HasNoAES)
449  Features.push_back("+aes");
450  } else if (HasNoCrypto) {
451  // Check if we have NOT enabled a crypto algorithm with something like:
452  // -crypto, +algorithm
453  // And if "+algorithm" does not occur, we disable that crypto algorithm.
454  if (!HasSM4)
455  Features.push_back("-sm4");
456  if (!HasSHA3)
457  Features.push_back("-sha3");
458  if (!HasSHA2)
459  Features.push_back("-sha2");
460  if (!HasAES)
461  Features.push_back("-aes");
462  }
463  } else {
464  if (HasCrypto && !HasNoCrypto) {
465  if (!HasNoSHA2)
466  Features.push_back("+sha2");
467  if (!HasNoAES)
468  Features.push_back("+aes");
469  } else if (HasNoCrypto) {
470  if (!HasSHA2)
471  Features.push_back("-sha2");
472  if (!HasAES)
473  Features.push_back("-aes");
474  if (V8Version == 2 || V8Version == 3) {
475  Features.push_back("-sm4");
476  Features.push_back("-sha3");
477  }
478  }
479  }
480 
481  // FIXME: these insertions should ideally be automated using default
482  // extensions support from the backend target parser.
483  if (V8Version >= 6 || V9Version >= 1)
484  Features.insert(std::next(Features.begin() + ArchFeatPos),
485  {"+i8mm", "+bf16"});
486 
487  // For Armv8.8-a/Armv9.3-a or later, FEAT_HBC and FEAT_MOPS are enabled by
488  // default.
489  if (V8Version >= 8 || V9Version >= 3)
490  Features.insert(std::next(Features.begin() + ArchFeatPos),
491  {"+hbc", "+mops"});
492 
493  if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
494  options::OPT_munaligned_access)) {
495  if (A->getOption().matches(options::OPT_mno_unaligned_access))
496  Features.push_back("+strict-align");
497  } else if (Triple.isOSOpenBSD())
498  Features.push_back("+strict-align");
499 
500  if (Args.hasArg(options::OPT_ffixed_x1))
501  Features.push_back("+reserve-x1");
502 
503  if (Args.hasArg(options::OPT_ffixed_x2))
504  Features.push_back("+reserve-x2");
505 
506  if (Args.hasArg(options::OPT_ffixed_x3))
507  Features.push_back("+reserve-x3");
508 
509  if (Args.hasArg(options::OPT_ffixed_x4))
510  Features.push_back("+reserve-x4");
511 
512  if (Args.hasArg(options::OPT_ffixed_x5))
513  Features.push_back("+reserve-x5");
514 
515  if (Args.hasArg(options::OPT_ffixed_x6))
516  Features.push_back("+reserve-x6");
517 
518  if (Args.hasArg(options::OPT_ffixed_x7))
519  Features.push_back("+reserve-x7");
520 
521  if (Args.hasArg(options::OPT_ffixed_x9))
522  Features.push_back("+reserve-x9");
523 
524  if (Args.hasArg(options::OPT_ffixed_x10))
525  Features.push_back("+reserve-x10");
526 
527  if (Args.hasArg(options::OPT_ffixed_x11))
528  Features.push_back("+reserve-x11");
529 
530  if (Args.hasArg(options::OPT_ffixed_x12))
531  Features.push_back("+reserve-x12");
532 
533  if (Args.hasArg(options::OPT_ffixed_x13))
534  Features.push_back("+reserve-x13");
535 
536  if (Args.hasArg(options::OPT_ffixed_x14))
537  Features.push_back("+reserve-x14");
538 
539  if (Args.hasArg(options::OPT_ffixed_x15))
540  Features.push_back("+reserve-x15");
541 
542  if (Args.hasArg(options::OPT_ffixed_x18))
543  Features.push_back("+reserve-x18");
544 
545  if (Args.hasArg(options::OPT_ffixed_x20))
546  Features.push_back("+reserve-x20");
547 
548  if (Args.hasArg(options::OPT_ffixed_x21))
549  Features.push_back("+reserve-x21");
550 
551  if (Args.hasArg(options::OPT_ffixed_x22))
552  Features.push_back("+reserve-x22");
553 
554  if (Args.hasArg(options::OPT_ffixed_x23))
555  Features.push_back("+reserve-x23");
556 
557  if (Args.hasArg(options::OPT_ffixed_x24))
558  Features.push_back("+reserve-x24");
559 
560  if (Args.hasArg(options::OPT_ffixed_x25))
561  Features.push_back("+reserve-x25");
562 
563  if (Args.hasArg(options::OPT_ffixed_x26))
564  Features.push_back("+reserve-x26");
565 
566  if (Args.hasArg(options::OPT_ffixed_x27))
567  Features.push_back("+reserve-x27");
568 
569  if (Args.hasArg(options::OPT_ffixed_x28))
570  Features.push_back("+reserve-x28");
571 
572  if (Args.hasArg(options::OPT_ffixed_x30))
573  Features.push_back("+reserve-x30");
574 
575  if (Args.hasArg(options::OPT_fcall_saved_x8))
576  Features.push_back("+call-saved-x8");
577 
578  if (Args.hasArg(options::OPT_fcall_saved_x9))
579  Features.push_back("+call-saved-x9");
580 
581  if (Args.hasArg(options::OPT_fcall_saved_x10))
582  Features.push_back("+call-saved-x10");
583 
584  if (Args.hasArg(options::OPT_fcall_saved_x11))
585  Features.push_back("+call-saved-x11");
586 
587  if (Args.hasArg(options::OPT_fcall_saved_x12))
588  Features.push_back("+call-saved-x12");
589 
590  if (Args.hasArg(options::OPT_fcall_saved_x13))
591  Features.push_back("+call-saved-x13");
592 
593  if (Args.hasArg(options::OPT_fcall_saved_x14))
594  Features.push_back("+call-saved-x14");
595 
596  if (Args.hasArg(options::OPT_fcall_saved_x15))
597  Features.push_back("+call-saved-x15");
598 
599  if (Args.hasArg(options::OPT_fcall_saved_x18))
600  Features.push_back("+call-saved-x18");
601 
602  if (Args.hasArg(options::OPT_mno_neg_immediates))
603  Features.push_back("+no-neg-immediates");
604 
605  if (Arg *A = Args.getLastArg(options::OPT_mfix_cortex_a53_835769,
606  options::OPT_mno_fix_cortex_a53_835769)) {
607  if (A->getOption().matches(options::OPT_mfix_cortex_a53_835769))
608  Features.push_back("+fix-cortex-a53-835769");
609  else
610  Features.push_back("-fix-cortex-a53-835769");
611  } else if (Triple.isAndroid()) {
612  // Enabled A53 errata (835769) workaround by default on android
613  Features.push_back("+fix-cortex-a53-835769");
614  }
615 
616  if (Args.getLastArg(options::OPT_mno_bti_at_return_twice))
617  Features.push_back("+no-bti-at-return-twice");
618 }
clang::comments::tok::text
@ text
Definition: CommentLexer.h:35
getAArch64MicroArchFeaturesFromMtune
static bool getAArch64MicroArchFeaturesFromMtune(const Driver &D, StringRef Mtune, const ArgList &Args, std::vector< StringRef > &Features)
Definition: AArch64.cpp:190
Driver.h
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
clang::driver::tools::aarch64::getAArch64TargetFeatures
void getAArch64TargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, std::vector< llvm::StringRef > &Features, bool ForAS)
Diag
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
Definition: LiteralSupport.cpp:78
llvm::SmallVector< StringRef, 8 >
DecodeAArch64Features
static bool DecodeAArch64Features(const Driver &D, StringRef text, std::vector< StringRef > &Features, llvm::AArch64::ArchKind ArchKind)
Definition: AArch64.cpp:68
clang::driver::tools
Definition: AIX.h:17
getAArch64ArchFeaturesFromMcpu
static bool getAArch64ArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, const ArgList &Args, std::vector< StringRef > &Features)
Definition: AArch64.cpp:178
isCPUDeterminedByTriple
static bool isCPUDeterminedByTriple(const llvm::Triple &Triple)
Definition: AArch64.cpp:25
AArch64.h
getAArch64MicroArchFeaturesFromMcpu
static bool getAArch64MicroArchFeaturesFromMcpu(const Driver &D, StringRef Mcpu, const ArgList &Args, std::vector< StringRef > &Features)
Definition: AArch64.cpp:212
clang::driver::Driver::Diag
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:132
Options.h
clang::Scope
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:40
clang::driver::tools::aarch64::getAArch64TargetCPU
std::string getAArch64TargetCPU(const llvm::opt::ArgList &Args, const llvm::Triple &Triple, llvm::opt::Arg *&A)
llvm::opt
Definition: DiagnosticOptions.h:19
DriverDiagnostic.h
clang::cross_tu::index_error_code::success
@ success
getAArch64ArchFeaturesFromMarch
static bool getAArch64ArchFeaturesFromMarch(const Driver &D, StringRef March, const ArgList &Args, std::vector< StringRef > &Features)
Definition: AArch64.cpp:147
Value
Value
Definition: UninitializedValues.cpp:102
DwarfFissionKind::Split
@ Split
DecodeAArch64Mcpu
static bool DecodeAArch64Mcpu(const Driver &D, StringRef Mcpu, StringRef &CPU, std::vector< StringRef > &Features)
Definition: AArch64.cpp:118
clang
Definition: CalledOnceCheck.h:17
clang::driver::Driver
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:71
clang::driver
Definition: Action.h:31
getArchFeatures
static bool getArchFeatures(const Driver &D, StringRef Arch, std::vector< StringRef > &Features, const ArgList &Args)
Definition: RISCV.cpp:28