clang  14.0.0git
ARM.cpp
Go to the documentation of this file.
1 //===--- ARM.cpp - ARM (not AArch64) 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 "ARM.h"
10 #include "clang/Driver/Driver.h"
12 #include "clang/Driver/Options.h"
13 #include "llvm/ADT/StringSwitch.h"
14 #include "llvm/Option/ArgList.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 // Get SubArch (vN).
24 int arm::getARMSubArchVersionNumber(const llvm::Triple &Triple) {
25  llvm::StringRef Arch = Triple.getArchName();
26  return llvm::ARM::parseArchVersion(Arch);
27 }
28 
29 // True if M-profile.
30 bool arm::isARMMProfile(const llvm::Triple &Triple) {
31  llvm::StringRef Arch = Triple.getArchName();
32  return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::M;
33 }
34 
35 // True if A-profile.
36 bool arm::isARMAProfile(const llvm::Triple &Triple) {
37  llvm::StringRef Arch = Triple.getArchName();
38  return llvm::ARM::parseArchProfile(Arch) == llvm::ARM::ProfileKind::A;
39 }
40 
41 // Get Arch/CPU from args.
42 void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
43  llvm::StringRef &CPU, bool FromAs) {
44  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
45  CPU = A->getValue();
46  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
47  Arch = A->getValue();
48  if (!FromAs)
49  return;
50 
51  for (const Arg *A :
52  Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
53  // Use getValues because -Wa can have multiple arguments
54  // e.g. -Wa,-mcpu=foo,-mcpu=bar
55  for (StringRef Value : A->getValues()) {
56  if (Value.startswith("-mcpu="))
57  CPU = Value.substr(6);
58  if (Value.startswith("-march="))
59  Arch = Value.substr(7);
60  }
61  }
62 }
63 
64 // Handle -mhwdiv=.
65 // FIXME: Use ARMTargetParser.
66 static void getARMHWDivFeatures(const Driver &D, const Arg *A,
67  const ArgList &Args, StringRef HWDiv,
68  std::vector<StringRef> &Features) {
69  uint64_t HWDivID = llvm::ARM::parseHWDiv(HWDiv);
70  if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
71  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
72 }
73 
74 // Handle -mfpu=.
75 static unsigned getARMFPUFeatures(const Driver &D, const Arg *A,
76  const ArgList &Args, StringRef FPU,
77  std::vector<StringRef> &Features) {
78  unsigned FPUID = llvm::ARM::parseFPU(FPU);
79  if (!llvm::ARM::getFPUFeatures(FPUID, Features))
80  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
81  return FPUID;
82 }
83 
84 // Decode ARM features from string like +[no]featureA+[no]featureB+...
85 static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU,
86  llvm::ARM::ArchKind ArchKind,
87  std::vector<StringRef> &Features,
88  unsigned &ArgFPUID) {
90  text.split(Split, StringRef("+"), -1, false);
91 
92  for (StringRef Feature : Split) {
93  if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features, ArgFPUID))
94  return false;
95  }
96  return true;
97 }
98 
99 static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU,
100  std::vector<StringRef> &Features) {
101  CPU = CPU.split("+").first;
102  if (CPU != "generic") {
103  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
104  uint64_t Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
105  llvm::ARM::getExtensionFeatures(Extension, Features);
106  }
107 }
108 
109 // Check if -march is valid by checking if it can be canonicalised and parsed.
110 // getARMArch is used here instead of just checking the -march value in order
111 // to handle -march=native correctly.
112 static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
113  llvm::StringRef ArchName, llvm::StringRef CPUName,
114  std::vector<StringRef> &Features,
115  const llvm::Triple &Triple, unsigned &ArgFPUID) {
116  std::pair<StringRef, StringRef> Split = ArchName.split("+");
117 
118  std::string MArch = arm::getARMArch(ArchName, Triple);
119  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
120  if (ArchKind == llvm::ARM::ArchKind::INVALID ||
121  (Split.second.size() && !DecodeARMFeatures(D, Split.second, CPUName,
122  ArchKind, Features, ArgFPUID)))
123  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
124 }
125 
126 // Check -mcpu=. Needs ArchName to handle -mcpu=generic.
127 static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
128  llvm::StringRef CPUName, llvm::StringRef ArchName,
129  std::vector<StringRef> &Features,
130  const llvm::Triple &Triple, unsigned &ArgFPUID) {
131  std::pair<StringRef, StringRef> Split = CPUName.split("+");
132 
133  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
134  llvm::ARM::ArchKind ArchKind =
135  arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
136  if (ArchKind == llvm::ARM::ArchKind::INVALID ||
137  (Split.second.size() &&
138  !DecodeARMFeatures(D, Split.second, CPU, ArchKind, Features, ArgFPUID)))
139  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
140 }
141 
142 bool arm::useAAPCSForMachO(const llvm::Triple &T) {
143  // The backend is hardwired to assume AAPCS for M-class processors, ensure
144  // the frontend matches that.
145  return T.getEnvironment() == llvm::Triple::EABI ||
146  T.getEnvironment() == llvm::Triple::EABIHF ||
147  T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
148 }
149 
150 // Select mode for reading thread pointer (-mtp=soft/cp15).
151 arm::ReadTPMode arm::getReadTPMode(const Driver &D, const ArgList &Args,
152  const llvm::Triple &Triple) {
153  if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
154  arm::ReadTPMode ThreadPointer =
155  llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
156  .Case("cp15", ReadTPMode::Cp15)
157  .Case("soft", ReadTPMode::Soft)
158  .Default(ReadTPMode::Invalid);
159  if (ThreadPointer == ReadTPMode::Cp15 &&
160  getARMSubArchVersionNumber(Triple) < 7 &&
161  llvm::ARM::parseArch(Triple.getArchName()) !=
162  llvm::ARM::ArchKind::ARMV6T2) {
163  D.Diag(diag::err_target_unsupported_tp_hard) << Triple.getArchName();
164  return ReadTPMode::Invalid;
165  }
166  if (ThreadPointer != ReadTPMode::Invalid)
167  return ThreadPointer;
168  if (StringRef(A->getValue()).empty())
169  D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
170  else
171  D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
172  return ReadTPMode::Invalid;
173  }
174  return ReadTPMode::Soft;
175 }
176 
177 void arm::setArchNameInTriple(const Driver &D, const ArgList &Args,
178  types::ID InputType, llvm::Triple &Triple) {
179  StringRef MCPU, MArch;
180  if (const Arg *A = Args.getLastArg(options::OPT_mcpu_EQ))
181  MCPU = A->getValue();
182  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
183  MArch = A->getValue();
184 
185  std::string CPU = Triple.isOSBinFormatMachO()
186  ? tools::arm::getARMCPUForMArch(MArch, Triple).str()
187  : tools::arm::getARMTargetCPU(MCPU, MArch, Triple);
188  StringRef Suffix = tools::arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
189 
190  bool IsBigEndian = Triple.getArch() == llvm::Triple::armeb ||
191  Triple.getArch() == llvm::Triple::thumbeb;
192  // Handle pseudo-target flags '-mlittle-endian'/'-EL' and
193  // '-mbig-endian'/'-EB'.
194  if (Arg *A = Args.getLastArg(options::OPT_mlittle_endian,
195  options::OPT_mbig_endian)) {
196  IsBigEndian = !A->getOption().matches(options::OPT_mlittle_endian);
197  }
198  std::string ArchName = IsBigEndian ? "armeb" : "arm";
199 
200  // FIXME: Thumb should just be another -target-feaure, not in the triple.
201  bool IsMProfile =
202  llvm::ARM::parseArchProfile(Suffix) == llvm::ARM::ProfileKind::M;
203  bool ThumbDefault = IsMProfile ||
204  // Thumb2 is the default for V7 on Darwin.
205  (llvm::ARM::parseArchVersion(Suffix) == 7 &&
206  Triple.isOSBinFormatMachO()) ||
207  // FIXME: this is invalid for WindowsCE
208  Triple.isOSWindows();
209 
210  // Check if ARM ISA was explicitly selected (using -mno-thumb or -marm) for
211  // M-Class CPUs/architecture variants, which is not supported.
212  bool ARMModeRequested =
213  !Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
214  if (IsMProfile && ARMModeRequested) {
215  if (MCPU.size())
216  D.Diag(diag::err_cpu_unsupported_isa) << CPU << "ARM";
217  else
218  D.Diag(diag::err_arch_unsupported_isa)
219  << tools::arm::getARMArch(MArch, Triple) << "ARM";
220  }
221 
222  // Check to see if an explicit choice to use thumb has been made via
223  // -mthumb. For assembler files we must check for -mthumb in the options
224  // passed to the assembler via -Wa or -Xassembler.
225  bool IsThumb = false;
226  if (InputType != types::TY_PP_Asm)
227  IsThumb =
228  Args.hasFlag(options::OPT_mthumb, options::OPT_mno_thumb, ThumbDefault);
229  else {
230  // Ideally we would check for these flags in
231  // CollectArgsForIntegratedAssembler but we can't change the ArchName at
232  // that point.
233  llvm::StringRef WaMArch, WaMCPU;
234  for (const auto *A :
235  Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
236  for (StringRef Value : A->getValues()) {
237  // There is no assembler equivalent of -mno-thumb, -marm, or -mno-arm.
238  if (Value == "-mthumb")
239  IsThumb = true;
240  else if (Value.startswith("-march="))
241  WaMArch = Value.substr(7);
242  else if (Value.startswith("-mcpu="))
243  WaMCPU = Value.substr(6);
244  }
245  }
246 
247  if (WaMCPU.size() || WaMArch.size()) {
248  // The way this works means that we prefer -Wa,-mcpu's architecture
249  // over -Wa,-march. Which matches the compiler behaviour.
250  Suffix = tools::arm::getLLVMArchSuffixForARM(WaMCPU, WaMArch, Triple);
251  }
252  }
253 
254  // Assembly files should start in ARM mode, unless arch is M-profile, or
255  // -mthumb has been passed explicitly to the assembler. Windows is always
256  // thumb.
257  if (IsThumb || IsMProfile || Triple.isOSWindows()) {
258  if (IsBigEndian)
259  ArchName = "thumbeb";
260  else
261  ArchName = "thumb";
262  }
263  Triple.setArchName(ArchName + Suffix.str());
264 }
265 
266 void arm::setFloatABIInTriple(const Driver &D, const ArgList &Args,
267  llvm::Triple &Triple) {
268  bool isHardFloat =
269  (arm::getARMFloatABI(D, Triple, Args) == arm::FloatABI::Hard);
270 
271  switch (Triple.getEnvironment()) {
272  case llvm::Triple::GNUEABI:
273  case llvm::Triple::GNUEABIHF:
274  Triple.setEnvironment(isHardFloat ? llvm::Triple::GNUEABIHF
275  : llvm::Triple::GNUEABI);
276  break;
277  case llvm::Triple::EABI:
278  case llvm::Triple::EABIHF:
279  Triple.setEnvironment(isHardFloat ? llvm::Triple::EABIHF
280  : llvm::Triple::EABI);
281  break;
282  case llvm::Triple::MuslEABI:
283  case llvm::Triple::MuslEABIHF:
284  Triple.setEnvironment(isHardFloat ? llvm::Triple::MuslEABIHF
285  : llvm::Triple::MuslEABI);
286  break;
287  default: {
288  arm::FloatABI DefaultABI = arm::getDefaultFloatABI(Triple);
289  if (DefaultABI != arm::FloatABI::Invalid &&
290  isHardFloat != (DefaultABI == arm::FloatABI::Hard)) {
291  Arg *ABIArg =
292  Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
293  options::OPT_mfloat_abi_EQ);
294  assert(ABIArg && "Non-default float abi expected to be from arg");
295  D.Diag(diag::err_drv_unsupported_opt_for_target)
296  << ABIArg->getAsString(Args) << Triple.getTriple();
297  }
298  break;
299  }
300  }
301 }
302 
303 arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
304  return arm::getARMFloatABI(TC.getDriver(), TC.getEffectiveTriple(), Args);
305 }
306 
307 arm::FloatABI arm::getDefaultFloatABI(const llvm::Triple &Triple) {
308  auto SubArch = getARMSubArchVersionNumber(Triple);
309  switch (Triple.getOS()) {
310  case llvm::Triple::Darwin:
311  case llvm::Triple::MacOSX:
312  case llvm::Triple::IOS:
313  case llvm::Triple::TvOS:
314  // Darwin defaults to "softfp" for v6 and v7.
315  if (Triple.isWatchABI())
316  return FloatABI::Hard;
317  else
318  return (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
319 
320  case llvm::Triple::WatchOS:
321  return FloatABI::Hard;
322 
323  // FIXME: this is invalid for WindowsCE
324  case llvm::Triple::Win32:
325  // It is incorrect to select hard float ABI on MachO platforms if the ABI is
326  // "apcs-gnu".
327  if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple))
328  return FloatABI::Soft;
329  return FloatABI::Hard;
330 
331  case llvm::Triple::NetBSD:
332  switch (Triple.getEnvironment()) {
333  case llvm::Triple::EABIHF:
334  case llvm::Triple::GNUEABIHF:
335  return FloatABI::Hard;
336  default:
337  return FloatABI::Soft;
338  }
339  break;
340 
341  case llvm::Triple::FreeBSD:
342  switch (Triple.getEnvironment()) {
343  case llvm::Triple::GNUEABIHF:
344  return FloatABI::Hard;
345  default:
346  // FreeBSD defaults to soft float
347  return FloatABI::Soft;
348  }
349  break;
350 
351  case llvm::Triple::OpenBSD:
352  return FloatABI::SoftFP;
353 
354  default:
355  switch (Triple.getEnvironment()) {
356  case llvm::Triple::GNUEABIHF:
357  case llvm::Triple::MuslEABIHF:
358  case llvm::Triple::EABIHF:
359  return FloatABI::Hard;
360  case llvm::Triple::GNUEABI:
361  case llvm::Triple::MuslEABI:
362  case llvm::Triple::EABI:
363  // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
364  return FloatABI::SoftFP;
365  case llvm::Triple::Android:
366  return (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
367  default:
368  return FloatABI::Invalid;
369  }
370  }
371  return FloatABI::Invalid;
372 }
373 
374 // Select the float ABI as determined by -msoft-float, -mhard-float, and
375 // -mfloat-abi=.
376 arm::FloatABI arm::getARMFloatABI(const Driver &D, const llvm::Triple &Triple,
377  const ArgList &Args) {
378  arm::FloatABI ABI = FloatABI::Invalid;
379  if (Arg *A =
380  Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
381  options::OPT_mfloat_abi_EQ)) {
382  if (A->getOption().matches(options::OPT_msoft_float)) {
383  ABI = FloatABI::Soft;
384  } else if (A->getOption().matches(options::OPT_mhard_float)) {
385  ABI = FloatABI::Hard;
386  } else {
387  ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
388  .Case("soft", FloatABI::Soft)
389  .Case("softfp", FloatABI::SoftFP)
390  .Case("hard", FloatABI::Hard)
391  .Default(FloatABI::Invalid);
392  if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
393  D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
394  ABI = FloatABI::Soft;
395  }
396  }
397  }
398 
399  // If unspecified, choose the default based on the platform.
400  if (ABI == FloatABI::Invalid)
401  ABI = arm::getDefaultFloatABI(Triple);
402 
403  if (ABI == FloatABI::Invalid) {
404  // Assume "soft", but warn the user we are guessing.
405  if (Triple.isOSBinFormatMachO() &&
406  Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
407  ABI = FloatABI::Hard;
408  else
409  ABI = FloatABI::Soft;
410 
411  if (Triple.getOS() != llvm::Triple::UnknownOS ||
412  !Triple.isOSBinFormatMachO())
413  D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
414  }
415 
416  assert(ABI != FloatABI::Invalid && "must select an ABI");
417  return ABI;
418 }
419 
420 static bool hasIntegerMVE(const std::vector<StringRef> &F) {
421  auto MVE = llvm::find(llvm::reverse(F), "+mve");
422  auto NoMVE = llvm::find(llvm::reverse(F), "-mve");
423  return MVE != F.rend() &&
424  (NoMVE == F.rend() || std::distance(MVE, NoMVE) > 0);
425 }
426 
427 void arm::getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple,
428  const ArgList &Args, ArgStringList &CmdArgs,
429  std::vector<StringRef> &Features, bool ForAS) {
430  bool KernelOrKext =
431  Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
432  arm::FloatABI ABI = arm::getARMFloatABI(D, Triple, Args);
433  arm::ReadTPMode ThreadPointer = arm::getReadTPMode(D, Args, Triple);
435  WaArch;
436 
437  // This vector will accumulate features from the architecture
438  // extension suffixes on -mcpu and -march (e.g. the 'bar' in
439  // -mcpu=foo+bar). We want to apply those after the features derived
440  // from the FPU, in case -mfpu generates a negative feature which
441  // the +bar is supposed to override.
442  std::vector<StringRef> ExtensionFeatures;
443 
444  if (!ForAS) {
445  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
446  // yet (it uses the -mfloat-abi and -msoft-float options), and it is
447  // stripped out by the ARM target. We should probably pass this a new
448  // -target-option, which is handled by the -cc1/-cc1as invocation.
449  //
450  // FIXME2: For consistency, it would be ideal if we set up the target
451  // machine state the same when using the frontend or the assembler. We don't
452  // currently do that for the assembler, we pass the options directly to the
453  // backend and never even instantiate the frontend TargetInfo. If we did,
454  // and used its handleTargetFeatures hook, then we could ensure the
455  // assembler and the frontend behave the same.
456 
457  // Use software floating point operations?
458  if (ABI == arm::FloatABI::Soft)
459  Features.push_back("+soft-float");
460 
461  // Use software floating point argument passing?
462  if (ABI != arm::FloatABI::Hard)
463  Features.push_back("+soft-float-abi");
464  } else {
465  // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
466  // to the assembler correctly.
467  for (const Arg *A :
468  Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
469  // We use getValues here because you can have many options per -Wa
470  // We will keep the last one we find for each of these
471  for (StringRef Value : A->getValues()) {
472  if (Value.startswith("-mfpu=")) {
473  WaFPU = std::make_pair(A, Value.substr(6));
474  } else if (Value.startswith("-mcpu=")) {
475  WaCPU = std::make_pair(A, Value.substr(6));
476  } else if (Value.startswith("-mhwdiv=")) {
477  WaHDiv = std::make_pair(A, Value.substr(8));
478  } else if (Value.startswith("-march=")) {
479  WaArch = std::make_pair(A, Value.substr(7));
480  }
481  }
482  }
483  }
484 
485  if (ThreadPointer == arm::ReadTPMode::Cp15)
486  Features.push_back("+read-tp-hard");
487 
488  const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
489  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
490  StringRef ArchName;
491  StringRef CPUName;
492  unsigned ArchArgFPUID = llvm::ARM::FK_INVALID;
493  unsigned CPUArgFPUID = llvm::ARM::FK_INVALID;
494 
495  // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
496  if (WaCPU) {
497  if (CPUArg)
498  D.Diag(clang::diag::warn_drv_unused_argument)
499  << CPUArg->getAsString(Args);
500  CPUName = WaCPU->second;
501  CPUArg = WaCPU->first;
502  } else if (CPUArg)
503  CPUName = CPUArg->getValue();
504 
505  // Check -march. ClangAs gives preference to -Wa,-march=.
506  if (WaArch) {
507  if (ArchArg)
508  D.Diag(clang::diag::warn_drv_unused_argument)
509  << ArchArg->getAsString(Args);
510  ArchName = WaArch->second;
511  // This will set any features after the base architecture.
512  checkARMArchName(D, WaArch->first, Args, ArchName, CPUName,
513  ExtensionFeatures, Triple, ArchArgFPUID);
514  // The base architecture was handled in ToolChain::ComputeLLVMTriple because
515  // triple is read only by this point.
516  } else if (ArchArg) {
517  ArchName = ArchArg->getValue();
518  checkARMArchName(D, ArchArg, Args, ArchName, CPUName, ExtensionFeatures,
519  Triple, ArchArgFPUID);
520  }
521 
522  // Add CPU features for generic CPUs
523  if (CPUName == "native") {
524  llvm::StringMap<bool> HostFeatures;
525  if (llvm::sys::getHostCPUFeatures(HostFeatures))
526  for (auto &F : HostFeatures)
527  Features.push_back(
528  Args.MakeArgString((F.second ? "+" : "-") + F.first()));
529  } else if (!CPUName.empty()) {
530  // This sets the default features for the specified CPU. We certainly don't
531  // want to override the features that have been explicitly specified on the
532  // command line. Therefore, process them directly instead of appending them
533  // at the end later.
534  DecodeARMFeaturesFromCPU(D, CPUName, Features);
535  }
536 
537  if (CPUArg)
538  checkARMCPUName(D, CPUArg, Args, CPUName, ArchName, ExtensionFeatures,
539  Triple, CPUArgFPUID);
540  // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
541  unsigned FPUID = llvm::ARM::FK_INVALID;
542  const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
543  if (WaFPU) {
544  if (FPUArg)
545  D.Diag(clang::diag::warn_drv_unused_argument)
546  << FPUArg->getAsString(Args);
547  (void)getARMFPUFeatures(D, WaFPU->first, Args, WaFPU->second, Features);
548  } else if (FPUArg) {
549  FPUID = getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
550  } else if (Triple.isAndroid() && getARMSubArchVersionNumber(Triple) >= 7) {
551  const char *AndroidFPU = "neon";
552  FPUID = llvm::ARM::parseFPU(AndroidFPU);
553  if (!llvm::ARM::getFPUFeatures(FPUID, Features))
554  D.Diag(clang::diag::err_drv_clang_unsupported)
555  << std::string("-mfpu=") + AndroidFPU;
556  } else {
557  if (!ForAS) {
558  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
559  llvm::ARM::ArchKind ArchKind =
560  arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
561  FPUID = llvm::ARM::getDefaultFPU(CPU, ArchKind);
562  (void)llvm::ARM::getFPUFeatures(FPUID, Features);
563  }
564  }
565 
566  // Now we've finished accumulating features from arch, cpu and fpu,
567  // we can append the ones for architecture extensions that we
568  // collected separately.
569  Features.insert(std::end(Features),
570  std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
571 
572  // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
573  const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
574  if (WaHDiv) {
575  if (HDivArg)
576  D.Diag(clang::diag::warn_drv_unused_argument)
577  << HDivArg->getAsString(Args);
578  getARMHWDivFeatures(D, WaHDiv->first, Args, WaHDiv->second, Features);
579  } else if (HDivArg)
580  getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
581 
582  // Handle (arch-dependent) fp16fml/fullfp16 relationship.
583  // Must happen before any features are disabled due to soft-float.
584  // FIXME: this fp16fml option handling will be reimplemented after the
585  // TargetParser rewrite.
586  const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16");
587  const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml");
588  if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
589  const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(), "+fullfp16");
590  if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
591  // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
592  // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
593  if (std::find(Features.rbegin(), ItRFullFP16, "-fp16fml") == ItRFullFP16)
594  Features.push_back("+fp16fml");
595  }
596  else
597  goto fp16_fml_fallthrough;
598  }
599  else {
600 fp16_fml_fallthrough:
601  // In both of these cases, putting the 'other' feature on the end of the vector will
602  // result in the same effect as placing it immediately after the current feature.
603  if (ItRNoFullFP16 < ItRFP16FML)
604  Features.push_back("-fp16fml");
605  else if (ItRNoFullFP16 > ItRFP16FML)
606  Features.push_back("+fullfp16");
607  }
608 
609  // Setting -msoft-float/-mfloat-abi=soft, -mfpu=none, or adding +nofp to
610  // -march/-mcpu effectively disables the FPU (GCC ignores the -mfpu options in
611  // this case). Note that the ABI can also be set implicitly by the target
612  // selected.
613  if (ABI == arm::FloatABI::Soft) {
614  llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
615 
616  // Disable all features relating to hardware FP, not already disabled by the
617  // above call.
618  Features.insert(Features.end(), {"-dotprod", "-fp16fml", "-bf16", "-mve",
619  "-mve.fp", "-fpregs"});
620  } else if (FPUID == llvm::ARM::FK_NONE ||
621  ArchArgFPUID == llvm::ARM::FK_NONE ||
622  CPUArgFPUID == llvm::ARM::FK_NONE) {
623  // -mfpu=none, -march=armvX+nofp or -mcpu=X+nofp is *very* similar to
624  // -mfloat-abi=soft, only that it should not disable MVE-I. They disable the
625  // FPU, but not the FPU registers, thus MVE-I, which depends only on the
626  // latter, is still supported.
627  Features.insert(Features.end(),
628  {"-dotprod", "-fp16fml", "-bf16", "-mve.fp"});
629  if (!hasIntegerMVE(Features))
630  Features.emplace_back("-fpregs");
631  }
632 
633  // En/disable crc code generation.
634  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
635  if (A->getOption().matches(options::OPT_mcrc))
636  Features.push_back("+crc");
637  else
638  Features.push_back("-crc");
639  }
640 
641  // For Arch >= ARMv8.0 && A or R profile: crypto = sha2 + aes
642  // Rather than replace within the feature vector, determine whether each
643  // algorithm is enabled and append this to the end of the vector.
644  // The algorithms can be controlled by their specific feature or the crypto
645  // feature, so their status can be determined by the last occurance of
646  // either in the vector. This allows one to supercede the other.
647  // e.g. +crypto+noaes in -march/-mcpu should enable sha2, but not aes
648  // FIXME: this needs reimplementation after the TargetParser rewrite
649  bool HasSHA2 = false;
650  bool HasAES = false;
651  const auto ItCrypto =
652  llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
653  return F.contains("crypto");
654  });
655  const auto ItSHA2 =
656  llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
657  return F.contains("crypto") || F.contains("sha2");
658  });
659  const auto ItAES =
660  llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
661  return F.contains("crypto") || F.contains("aes");
662  });
663  const bool FoundSHA2 = ItSHA2 != Features.rend();
664  const bool FoundAES = ItAES != Features.rend();
665  if (FoundSHA2)
666  HasSHA2 = ItSHA2->take_front() == "+";
667  if (FoundAES)
668  HasAES = ItAES->take_front() == "+";
669  if (ItCrypto != Features.rend()) {
670  if (HasSHA2 && HasAES)
671  Features.push_back("+crypto");
672  else
673  Features.push_back("-crypto");
674  if (HasSHA2)
675  Features.push_back("+sha2");
676  else
677  Features.push_back("-sha2");
678  if (HasAES)
679  Features.push_back("+aes");
680  else
681  Features.push_back("-aes");
682  }
683 
684  if (HasSHA2 || HasAES) {
685  StringRef ArchSuffix = arm::getLLVMArchSuffixForARM(
686  arm::getARMTargetCPU(CPUName, ArchName, Triple), ArchName, Triple);
687  llvm::ARM::ProfileKind ArchProfile =
688  llvm::ARM::parseArchProfile(ArchSuffix);
689  if (!((llvm::ARM::parseArchVersion(ArchSuffix) >= 8) &&
690  (ArchProfile == llvm::ARM::ProfileKind::A ||
691  ArchProfile == llvm::ARM::ProfileKind::R))) {
692  if (HasSHA2)
693  D.Diag(clang::diag::warn_target_unsupported_extension)
694  << "sha2"
695  << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
696  if (HasAES)
697  D.Diag(clang::diag::warn_target_unsupported_extension)
698  << "aes"
699  << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
700  // With -fno-integrated-as -mfpu=crypto-neon-fp-armv8 some assemblers such
701  // as the GNU assembler will permit the use of crypto instructions as the
702  // fpu will override the architecture. We keep the crypto feature in this
703  // case to preserve compatibility. In all other cases we remove the crypto
704  // feature.
705  if (!Args.hasArg(options::OPT_fno_integrated_as)) {
706  Features.push_back("-sha2");
707  Features.push_back("-aes");
708  }
709  }
710  }
711 
712  // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later.
713  if (Args.getLastArg(options::OPT_mcmse))
714  Features.push_back("+8msecext");
715 
716  if (Arg *A = Args.getLastArg(options::OPT_mfix_cmse_cve_2021_35465,
717  options::OPT_mno_fix_cmse_cve_2021_35465)) {
718  if (!Args.getLastArg(options::OPT_mcmse))
719  D.Diag(diag::err_opt_not_valid_without_opt)
720  << A->getOption().getName() << "-mcmse";
721 
722  if (A->getOption().matches(options::OPT_mfix_cmse_cve_2021_35465))
723  Features.push_back("+fix-cmse-cve-2021-35465");
724  else
725  Features.push_back("-fix-cmse-cve-2021-35465");
726  }
727 
728  // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
729  // neither options are specified, see if we are compiling for kernel/kext and
730  // decide whether to pass "+long-calls" based on the OS and its version.
731  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
732  options::OPT_mno_long_calls)) {
733  if (A->getOption().matches(options::OPT_mlong_calls))
734  Features.push_back("+long-calls");
735  } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
736  !Triple.isWatchOS()) {
737  Features.push_back("+long-calls");
738  }
739 
740  // Generate execute-only output (no data access to code sections).
741  // This only makes sense for the compiler, not for the assembler.
742  if (!ForAS) {
743  // Supported only on ARMv6T2 and ARMv7 and above.
744  // Cannot be combined with -mno-movt or -mlong-calls
745  if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
746  if (A->getOption().matches(options::OPT_mexecute_only)) {
747  if (getARMSubArchVersionNumber(Triple) < 7 &&
748  llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2)
749  D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
750  else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
751  D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
752  // Long calls create constant pool entries and have not yet been fixed up
753  // to play nicely with execute-only. Hence, they cannot be used in
754  // execute-only code for now
755  else if (Arg *B = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) {
756  if (B->getOption().matches(options::OPT_mlong_calls))
757  D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
758  }
759  Features.push_back("+execute-only");
760  }
761  }
762  }
763 
764  // Kernel code has more strict alignment requirements.
765  if (KernelOrKext)
766  Features.push_back("+strict-align");
767  else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
768  options::OPT_munaligned_access)) {
769  if (A->getOption().matches(options::OPT_munaligned_access)) {
770  // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
771  if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
772  D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
773  // v8M Baseline follows on from v6M, so doesn't support unaligned memory
774  // access either.
775  else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
776  D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
777  } else
778  Features.push_back("+strict-align");
779  } else {
780  // Assume pre-ARMv6 doesn't support unaligned accesses.
781  //
782  // ARMv6 may or may not support unaligned accesses depending on the
783  // SCTLR.U bit, which is architecture-specific. We assume ARMv6
784  // Darwin and NetBSD targets support unaligned accesses, and others don't.
785  //
786  // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
787  // which raises an alignment fault on unaligned accesses. Linux
788  // defaults this bit to 0 and handles it as a system-wide (not
789  // per-process) setting. It is therefore safe to assume that ARMv7+
790  // Linux targets support unaligned accesses. The same goes for NaCl
791  // and Windows.
792  //
793  // The above behavior is consistent with GCC.
794  int VersionNum = getARMSubArchVersionNumber(Triple);
795  if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
796  if (VersionNum < 6 ||
797  Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
798  Features.push_back("+strict-align");
799  } else if (Triple.isOSLinux() || Triple.isOSNaCl() ||
800  Triple.isOSWindows()) {
801  if (VersionNum < 7)
802  Features.push_back("+strict-align");
803  } else
804  Features.push_back("+strict-align");
805  }
806 
807  // llvm does not support reserving registers in general. There is support
808  // for reserving r9 on ARM though (defined as a platform-specific register
809  // in ARM EABI).
810  if (Args.hasArg(options::OPT_ffixed_r9))
811  Features.push_back("+reserve-r9");
812 
813  // The kext linker doesn't know how to deal with movw/movt.
814  if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
815  Features.push_back("+no-movt");
816 
817  if (Args.hasArg(options::OPT_mno_neg_immediates))
818  Features.push_back("+no-neg-immediates");
819 
820  // Enable/disable straight line speculation hardening.
821  if (Arg *A = Args.getLastArg(options::OPT_mharden_sls_EQ)) {
822  StringRef Scope = A->getValue();
823  bool EnableRetBr = false;
824  bool EnableBlr = false;
825  bool DisableComdat = false;
826  if (Scope != "none") {
828  Scope.split(Opts, ",");
829  for (auto Opt : Opts) {
830  Opt = Opt.trim();
831  if (Opt == "all") {
832  EnableBlr = true;
833  EnableRetBr = true;
834  continue;
835  }
836  if (Opt == "retbr") {
837  EnableRetBr = true;
838  continue;
839  }
840  if (Opt == "blr") {
841  EnableBlr = true;
842  continue;
843  }
844  if (Opt == "comdat") {
845  DisableComdat = false;
846  continue;
847  }
848  if (Opt == "nocomdat") {
849  DisableComdat = true;
850  continue;
851  }
852  D.Diag(diag::err_invalid_sls_hardening)
853  << Scope << A->getAsString(Args);
854  break;
855  }
856  }
857 
858  if (EnableRetBr || EnableBlr)
859  if (!(isARMAProfile(Triple) && getARMSubArchVersionNumber(Triple) >= 7))
860  D.Diag(diag::err_sls_hardening_arm_not_supported)
861  << Scope << A->getAsString(Args);
862 
863  if (EnableRetBr)
864  Features.push_back("+harden-sls-retbr");
865  if (EnableBlr)
866  Features.push_back("+harden-sls-blr");
867  if (DisableComdat) {
868  Features.push_back("+harden-sls-nocomdat");
869  }
870  }
871 
872 }
873 
874 std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
875  std::string MArch;
876  if (!Arch.empty())
877  MArch = std::string(Arch);
878  else
879  MArch = std::string(Triple.getArchName());
880  MArch = StringRef(MArch).split("+").first.lower();
881 
882  // Handle -march=native.
883  if (MArch == "native") {
884  std::string CPU = std::string(llvm::sys::getHostCPUName());
885  if (CPU != "generic") {
886  // Translate the native cpu into the architecture suffix for that CPU.
887  StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
888  // If there is no valid architecture suffix for this CPU we don't know how
889  // to handle it, so return no architecture.
890  if (Suffix.empty())
891  MArch = "";
892  else
893  MArch = std::string("arm") + Suffix.str();
894  }
895  }
896 
897  return MArch;
898 }
899 
900 /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
901 StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
902  std::string MArch = getARMArch(Arch, Triple);
903  // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
904  // here means an -march=native that we can't handle, so instead return no CPU.
905  if (MArch.empty())
906  return StringRef();
907 
908  // We need to return an empty string here on invalid MArch values as the
909  // various places that call this function can't cope with a null result.
910  return Triple.getARMCPUForArch(MArch);
911 }
912 
913 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
914 std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
915  const llvm::Triple &Triple) {
916  // FIXME: Warn on inconsistent use of -mcpu and -march.
917  // If we have -mcpu=, use that.
918  if (!CPU.empty()) {
919  std::string MCPU = StringRef(CPU).split("+").first.lower();
920  // Handle -mcpu=native.
921  if (MCPU == "native")
922  return std::string(llvm::sys::getHostCPUName());
923  else
924  return MCPU;
925  }
926 
927  return std::string(getARMCPUForMArch(Arch, Triple));
928 }
929 
930 /// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a
931 /// particular CPU (or Arch, if CPU is generic). This is needed to
932 /// pass to functions like llvm::ARM::getDefaultFPU which need an
933 /// ArchKind as well as a CPU name.
934 llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch,
935  const llvm::Triple &Triple) {
936  llvm::ARM::ArchKind ArchKind;
937  if (CPU == "generic" || CPU.empty()) {
938  std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
939  ArchKind = llvm::ARM::parseArch(ARMArch);
940  if (ArchKind == llvm::ARM::ArchKind::INVALID)
941  // In case of generic Arch, i.e. "arm",
942  // extract arch from default cpu of the Triple
943  ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
944  } else {
945  // FIXME: horrible hack to get around the fact that Cortex-A7 is only an
946  // armv7k triple if it's actually been specified via "-arch armv7k".
947  ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
948  ? llvm::ARM::ArchKind::ARMV7K
949  : llvm::ARM::parseCPUArch(CPU);
950  }
951  return ArchKind;
952 }
953 
954 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
955 /// CPU (or Arch, if CPU is generic).
956 // FIXME: This is redundant with -mcpu, why does LLVM use this.
957 StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
958  const llvm::Triple &Triple) {
959  llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple);
960  if (ArchKind == llvm::ARM::ArchKind::INVALID)
961  return "";
962  return llvm::ARM::getSubArch(ArchKind);
963 }
964 
965 void arm::appendBE8LinkFlag(const ArgList &Args, ArgStringList &CmdArgs,
966  const llvm::Triple &Triple) {
967  if (Args.hasArg(options::OPT_r))
968  return;
969 
970  // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
971  // to generate BE-8 executables.
972  if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple))
973  CmdArgs.push_back("--be8");
974 }
clang::driver::tools::arm::getARMTargetFeatures
void getARMTargetFeatures(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, std::vector< llvm::StringRef > &Features, bool ForAS)
clang::comments::tok::text
@ text
Definition: CommentLexer.h:35
clang::driver::ToolChain::getEffectiveTriple
const llvm::Triple & getEffectiveTriple() const
Get the toolchain's effective clang triple.
Definition: ToolChain.h:251
getARMFPUFeatures
static unsigned getARMFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args, StringRef FPU, std::vector< StringRef > &Features)
Definition: ARM.cpp:75
DecodeARMFeatures
static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU, llvm::ARM::ArchKind ArchKind, std::vector< StringRef > &Features, unsigned &ArgFPUID)
Definition: ARM.cpp:85
clang::driver::tools::arm::setFloatABIInTriple
void setFloatABIInTriple(const Driver &D, const llvm::opt::ArgList &Args, llvm::Triple &triple)
getARMHWDivFeatures
static void getARMHWDivFeatures(const Driver &D, const Arg *A, const ArgList &Args, StringRef HWDiv, std::vector< StringRef > &Features)
Definition: ARM.cpp:66
Driver.h
string
string(SUBSTRING ${CMAKE_CURRENT_BINARY_DIR} 0 ${PATH_LIB_START} PATH_HEAD) string(SUBSTRING $
Definition: CMakeLists.txt:22
llvm::SmallVector< StringRef, 8 >
clang::driver::tools::arm::getARMFloatABI
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args)
clang::driver::tools
Definition: AIX.h:17
clang::driver::tools::arm::FloatABI::Soft
@ Soft
clang::driver::ToolChain::getDriver
const Driver & getDriver() const
Definition: ToolChain.h:221
hasIntegerMVE
static bool hasIntegerMVE(const std::vector< StringRef > &F)
Definition: ARM.cpp:420
distance
float __ovld __cnfn distance(float p0, float p1)
Returns the distance between p0 and p1.
llvm::Optional
Definition: LLVM.h:40
clang::driver::tools::arm::getLLVMArchKindForARM
llvm::ARM::ArchKind getLLVMArchKindForARM(StringRef CPU, StringRef Arch, const llvm::Triple &Triple)
getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a particular CPU (or Arch,...
Definition: ARM.cpp:934
clang::driver::tools::arm::isARMMProfile
bool isARMMProfile(const llvm::Triple &Triple)
Definition: ARM.cpp:30
clang::driver::tools::arm::setArchNameInTriple
void setArchNameInTriple(const Driver &D, const llvm::opt::ArgList &Args, types::ID InputType, llvm::Triple &Triple)
clang::driver::Driver::Diag
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:112
clang::driver::tools::arm::FloatABI
FloatABI
Definition: ARM.h:43
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::arm::getReadTPMode
ReadTPMode getReadTPMode(const Driver &D, const llvm::opt::ArgList &Args, const llvm::Triple &Triple)
clang::driver::tools::arm::getARMCPUForMArch
StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple)
llvm::opt
Definition: DiagnosticOptions.h:19
DriverDiagnostic.h
clang::driver::tools::arm::FloatABI::Hard
@ Hard
checkARMArchName
static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args, llvm::StringRef ArchName, llvm::StringRef CPUName, std::vector< StringRef > &Features, const llvm::Triple &Triple, unsigned &ArgFPUID)
Definition: ARM.cpp:112
clang::driver::tools::arm::FloatABI::Invalid
@ Invalid
clang::driver::tools::arm::getARMSubArchVersionNumber
int getARMSubArchVersionNumber(const llvm::Triple &Triple)
Definition: ARM.cpp:24
clang::driver::ToolChain
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:91
Value
Value
Definition: UninitializedValues.cpp:102
clang::driver::tools::arm::getARMTargetCPU
std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple)
DwarfFissionKind::Split
@ Split
checkARMCPUName
static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args, llvm::StringRef CPUName, llvm::StringRef ArchName, std::vector< StringRef > &Features, const llvm::Triple &Triple, unsigned &ArgFPUID)
Definition: ARM.cpp:127
clang::driver::tools::arm::getDefaultFloatABI
FloatABI getDefaultFloatABI(const llvm::Triple &Triple)
Definition: ARM.cpp:307
clang::driver::types::ID
ID
Definition: Types.h:23
clang::driver::tools::arm::getARMArchCPUFromArgs
void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args, llvm::StringRef &Arch, llvm::StringRef &CPU, bool FromAs=false)
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:59
clang::driver::tools::arm::getARMArch
std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple)
clang::driver::tools::arm::getLLVMArchSuffixForARM
StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple)
clang::driver::tools::arm::ReadTPMode::Cp15
@ Cp15
ARM.h
clang::driver::tools::arm::ReadTPMode
ReadTPMode
Definition: ARM.h:37
clang::driver
Definition: Action.h:31
clang::driver::tools::arm::appendBE8LinkFlag
void appendBE8LinkFlag(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple)
clang::driver::tools::arm::isARMAProfile
bool isARMAProfile(const llvm::Triple &Triple)
Definition: ARM.cpp:36
clang::driver::tools::arm::useAAPCSForMachO
bool useAAPCSForMachO(const llvm::Triple &T)
Definition: ARM.cpp:142
DecodeARMFeaturesFromCPU
static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, std::vector< StringRef > &Features)
Definition: ARM.cpp:99