clang  10.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 // Get Arch/CPU from args.
36 void arm::getARMArchCPUFromArgs(const ArgList &Args, llvm::StringRef &Arch,
37  llvm::StringRef &CPU, bool FromAs) {
38  if (const Arg *A = Args.getLastArg(clang::driver::options::OPT_mcpu_EQ))
39  CPU = A->getValue();
40  if (const Arg *A = Args.getLastArg(options::OPT_march_EQ))
41  Arch = A->getValue();
42  if (!FromAs)
43  return;
44 
45  for (const Arg *A :
46  Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
47  StringRef Value = A->getValue();
48  if (Value.startswith("-mcpu="))
49  CPU = Value.substr(6);
50  if (Value.startswith("-march="))
51  Arch = Value.substr(7);
52  }
53 }
54 
55 // Handle -mhwdiv=.
56 // FIXME: Use ARMTargetParser.
57 static void getARMHWDivFeatures(const Driver &D, const Arg *A,
58  const ArgList &Args, StringRef HWDiv,
59  std::vector<StringRef> &Features) {
60  unsigned HWDivID = llvm::ARM::parseHWDiv(HWDiv);
61  if (!llvm::ARM::getHWDivFeatures(HWDivID, Features))
62  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
63 }
64 
65 // Handle -mfpu=.
66 static unsigned getARMFPUFeatures(const Driver &D, const Arg *A,
67  const ArgList &Args, StringRef FPU,
68  std::vector<StringRef> &Features) {
69  unsigned FPUID = llvm::ARM::parseFPU(FPU);
70  if (!llvm::ARM::getFPUFeatures(FPUID, Features))
71  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
72  return FPUID;
73 }
74 
75 // Decode ARM features from string like +[no]featureA+[no]featureB+...
76 static bool DecodeARMFeatures(const Driver &D, StringRef text,
77  StringRef CPU, llvm::ARM::ArchKind ArchKind,
78  std::vector<StringRef> &Features) {
80  text.split(Split, StringRef("+"), -1, false);
81 
82  for (StringRef Feature : Split) {
83  if (!appendArchExtFeatures(CPU, ArchKind, Feature, Features))
84  return false;
85  }
86  return true;
87 }
88 
89 static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU,
90  std::vector<StringRef> &Features) {
91  CPU = CPU.split("+").first;
92  if (CPU != "generic") {
93  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseCPUArch(CPU);
94  unsigned Extension = llvm::ARM::getDefaultExtensions(CPU, ArchKind);
95  llvm::ARM::getExtensionFeatures(Extension, Features);
96  }
97 }
98 
99 // Check if -march is valid by checking if it can be canonicalised and parsed.
100 // getARMArch is used here instead of just checking the -march value in order
101 // to handle -march=native correctly.
102 static void checkARMArchName(const Driver &D, const Arg *A, const ArgList &Args,
103  llvm::StringRef ArchName, llvm::StringRef CPUName,
104  std::vector<StringRef> &Features,
105  const llvm::Triple &Triple) {
106  std::pair<StringRef, StringRef> Split = ArchName.split("+");
107 
108  std::string MArch = arm::getARMArch(ArchName, Triple);
109  llvm::ARM::ArchKind ArchKind = llvm::ARM::parseArch(MArch);
110  if (ArchKind == llvm::ARM::ArchKind::INVALID ||
111  (Split.second.size() && !DecodeARMFeatures(
112  D, Split.second, CPUName, ArchKind, Features)))
113  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
114 }
115 
116 // Check -mcpu=. Needs ArchName to handle -mcpu=generic.
117 static void checkARMCPUName(const Driver &D, const Arg *A, const ArgList &Args,
118  llvm::StringRef CPUName, llvm::StringRef ArchName,
119  std::vector<StringRef> &Features,
120  const llvm::Triple &Triple) {
121  std::pair<StringRef, StringRef> Split = CPUName.split("+");
122 
123  std::string CPU = arm::getARMTargetCPU(CPUName, ArchName, Triple);
124  llvm::ARM::ArchKind ArchKind =
125  arm::getLLVMArchKindForARM(CPU, ArchName, Triple);
126  if (ArchKind == llvm::ARM::ArchKind::INVALID ||
127  (Split.second.size() && !DecodeARMFeatures(
128  D, Split.second, CPU, ArchKind, Features)))
129  D.Diag(clang::diag::err_drv_clang_unsupported) << A->getAsString(Args);
130 }
131 
132 bool arm::useAAPCSForMachO(const llvm::Triple &T) {
133  // The backend is hardwired to assume AAPCS for M-class processors, ensure
134  // the frontend matches that.
135  return T.getEnvironment() == llvm::Triple::EABI ||
136  T.getOS() == llvm::Triple::UnknownOS || isARMMProfile(T);
137 }
138 
139 // Select mode for reading thread pointer (-mtp=soft/cp15).
140 arm::ReadTPMode arm::getReadTPMode(const ToolChain &TC, const ArgList &Args) {
141  if (Arg *A = Args.getLastArg(options::OPT_mtp_mode_EQ)) {
142  const Driver &D = TC.getDriver();
143  arm::ReadTPMode ThreadPointer =
144  llvm::StringSwitch<arm::ReadTPMode>(A->getValue())
145  .Case("cp15", ReadTPMode::Cp15)
146  .Case("soft", ReadTPMode::Soft)
147  .Default(ReadTPMode::Invalid);
148  if (ThreadPointer != ReadTPMode::Invalid)
149  return ThreadPointer;
150  if (StringRef(A->getValue()).empty())
151  D.Diag(diag::err_drv_missing_arg_mtp) << A->getAsString(Args);
152  else
153  D.Diag(diag::err_drv_invalid_mtp) << A->getAsString(Args);
154  return ReadTPMode::Invalid;
155  }
156  return ReadTPMode::Soft;
157 }
158 
159 // Select the float ABI as determined by -msoft-float, -mhard-float, and
160 // -mfloat-abi=.
161 arm::FloatABI arm::getARMFloatABI(const ToolChain &TC, const ArgList &Args) {
162  const Driver &D = TC.getDriver();
163  const llvm::Triple &Triple = TC.getEffectiveTriple();
164  auto SubArch = getARMSubArchVersionNumber(Triple);
165  arm::FloatABI ABI = FloatABI::Invalid;
166  if (Arg *A =
167  Args.getLastArg(options::OPT_msoft_float, options::OPT_mhard_float,
168  options::OPT_mfloat_abi_EQ)) {
169  if (A->getOption().matches(options::OPT_msoft_float)) {
170  ABI = FloatABI::Soft;
171  } else if (A->getOption().matches(options::OPT_mhard_float)) {
172  ABI = FloatABI::Hard;
173  } else {
174  ABI = llvm::StringSwitch<arm::FloatABI>(A->getValue())
175  .Case("soft", FloatABI::Soft)
176  .Case("softfp", FloatABI::SoftFP)
177  .Case("hard", FloatABI::Hard)
178  .Default(FloatABI::Invalid);
179  if (ABI == FloatABI::Invalid && !StringRef(A->getValue()).empty()) {
180  D.Diag(diag::err_drv_invalid_mfloat_abi) << A->getAsString(Args);
181  ABI = FloatABI::Soft;
182  }
183  }
184 
185  // It is incorrect to select hard float ABI on MachO platforms if the ABI is
186  // "apcs-gnu".
187  if (Triple.isOSBinFormatMachO() && !useAAPCSForMachO(Triple) &&
188  ABI == FloatABI::Hard) {
189  D.Diag(diag::err_drv_unsupported_opt_for_target) << A->getAsString(Args)
190  << Triple.getArchName();
191  }
192  }
193 
194  // If unspecified, choose the default based on the platform.
195  if (ABI == FloatABI::Invalid) {
196  switch (Triple.getOS()) {
197  case llvm::Triple::Darwin:
198  case llvm::Triple::MacOSX:
199  case llvm::Triple::IOS:
200  case llvm::Triple::TvOS: {
201  // Darwin defaults to "softfp" for v6 and v7.
202  ABI = (SubArch == 6 || SubArch == 7) ? FloatABI::SoftFP : FloatABI::Soft;
203  ABI = Triple.isWatchABI() ? FloatABI::Hard : ABI;
204  break;
205  }
206  case llvm::Triple::WatchOS:
207  ABI = FloatABI::Hard;
208  break;
209 
210  // FIXME: this is invalid for WindowsCE
211  case llvm::Triple::Win32:
212  ABI = FloatABI::Hard;
213  break;
214 
215  case llvm::Triple::NetBSD:
216  switch (Triple.getEnvironment()) {
217  case llvm::Triple::EABIHF:
218  case llvm::Triple::GNUEABIHF:
219  ABI = FloatABI::Hard;
220  break;
221  default:
222  ABI = FloatABI::Soft;
223  break;
224  }
225  break;
226 
227  case llvm::Triple::FreeBSD:
228  switch (Triple.getEnvironment()) {
229  case llvm::Triple::GNUEABIHF:
230  ABI = FloatABI::Hard;
231  break;
232  default:
233  // FreeBSD defaults to soft float
234  ABI = FloatABI::Soft;
235  break;
236  }
237  break;
238 
239  case llvm::Triple::OpenBSD:
240  ABI = FloatABI::SoftFP;
241  break;
242 
243  default:
244  switch (Triple.getEnvironment()) {
245  case llvm::Triple::GNUEABIHF:
246  case llvm::Triple::MuslEABIHF:
247  case llvm::Triple::EABIHF:
248  ABI = FloatABI::Hard;
249  break;
250  case llvm::Triple::GNUEABI:
251  case llvm::Triple::MuslEABI:
252  case llvm::Triple::EABI:
253  // EABI is always AAPCS, and if it was not marked 'hard', it's softfp
254  ABI = FloatABI::SoftFP;
255  break;
256  case llvm::Triple::Android:
257  ABI = (SubArch >= 7) ? FloatABI::SoftFP : FloatABI::Soft;
258  break;
259  default:
260  // Assume "soft", but warn the user we are guessing.
261  if (Triple.isOSBinFormatMachO() &&
262  Triple.getSubArch() == llvm::Triple::ARMSubArch_v7em)
263  ABI = FloatABI::Hard;
264  else
265  ABI = FloatABI::Soft;
266 
267  if (Triple.getOS() != llvm::Triple::UnknownOS ||
268  !Triple.isOSBinFormatMachO())
269  D.Diag(diag::warn_drv_assuming_mfloat_abi_is) << "soft";
270  break;
271  }
272  }
273  }
274 
275  assert(ABI != FloatABI::Invalid && "must select an ABI");
276  return ABI;
277 }
278 
279 void arm::getARMTargetFeatures(const ToolChain &TC,
280  const llvm::Triple &Triple,
281  const ArgList &Args,
282  ArgStringList &CmdArgs,
283  std::vector<StringRef> &Features,
284  bool ForAS) {
285  const Driver &D = TC.getDriver();
286 
287  bool KernelOrKext =
288  Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
289  arm::FloatABI ABI = arm::getARMFloatABI(TC, Args);
290  arm::ReadTPMode ThreadPointer = arm::getReadTPMode(TC, Args);
291  const Arg *WaCPU = nullptr, *WaFPU = nullptr;
292  const Arg *WaHDiv = nullptr, *WaArch = nullptr;
293 
294  // This vector will accumulate features from the architecture
295  // extension suffixes on -mcpu and -march (e.g. the 'bar' in
296  // -mcpu=foo+bar). We want to apply those after the features derived
297  // from the FPU, in case -mfpu generates a negative feature which
298  // the +bar is supposed to override.
299  std::vector<StringRef> ExtensionFeatures;
300 
301  if (!ForAS) {
302  // FIXME: Note, this is a hack, the LLVM backend doesn't actually use these
303  // yet (it uses the -mfloat-abi and -msoft-float options), and it is
304  // stripped out by the ARM target. We should probably pass this a new
305  // -target-option, which is handled by the -cc1/-cc1as invocation.
306  //
307  // FIXME2: For consistency, it would be ideal if we set up the target
308  // machine state the same when using the frontend or the assembler. We don't
309  // currently do that for the assembler, we pass the options directly to the
310  // backend and never even instantiate the frontend TargetInfo. If we did,
311  // and used its handleTargetFeatures hook, then we could ensure the
312  // assembler and the frontend behave the same.
313 
314  // Use software floating point operations?
315  if (ABI == arm::FloatABI::Soft)
316  Features.push_back("+soft-float");
317 
318  // Use software floating point argument passing?
319  if (ABI != arm::FloatABI::Hard)
320  Features.push_back("+soft-float-abi");
321  } else {
322  // Here, we make sure that -Wa,-mfpu/cpu/arch/hwdiv will be passed down
323  // to the assembler correctly.
324  for (const Arg *A :
325  Args.filtered(options::OPT_Wa_COMMA, options::OPT_Xassembler)) {
326  StringRef Value = A->getValue();
327  if (Value.startswith("-mfpu=")) {
328  WaFPU = A;
329  } else if (Value.startswith("-mcpu=")) {
330  WaCPU = A;
331  } else if (Value.startswith("-mhwdiv=")) {
332  WaHDiv = A;
333  } else if (Value.startswith("-march=")) {
334  WaArch = A;
335  }
336  }
337  }
338 
339  if (ThreadPointer == arm::ReadTPMode::Cp15)
340  Features.push_back("+read-tp-hard");
341 
342  const Arg *ArchArg = Args.getLastArg(options::OPT_march_EQ);
343  const Arg *CPUArg = Args.getLastArg(options::OPT_mcpu_EQ);
344  StringRef ArchName;
345  StringRef CPUName;
346 
347  // Check -mcpu. ClangAs gives preference to -Wa,-mcpu=.
348  if (WaCPU) {
349  if (CPUArg)
350  D.Diag(clang::diag::warn_drv_unused_argument)
351  << CPUArg->getAsString(Args);
352  CPUName = StringRef(WaCPU->getValue()).substr(6);
353  CPUArg = WaCPU;
354  } else if (CPUArg)
355  CPUName = CPUArg->getValue();
356 
357  // Check -march. ClangAs gives preference to -Wa,-march=.
358  if (WaArch) {
359  if (ArchArg)
360  D.Diag(clang::diag::warn_drv_unused_argument)
361  << ArchArg->getAsString(Args);
362  ArchName = StringRef(WaArch->getValue()).substr(7);
363  checkARMArchName(D, WaArch, Args, ArchName, CPUName,
364  ExtensionFeatures, Triple);
365  // FIXME: Set Arch.
366  D.Diag(clang::diag::warn_drv_unused_argument) << WaArch->getAsString(Args);
367  } else if (ArchArg) {
368  ArchName = ArchArg->getValue();
369  checkARMArchName(D, ArchArg, Args, ArchName, CPUName,
370  ExtensionFeatures, Triple);
371  }
372 
373  // Add CPU features for generic CPUs
374  if (CPUName == "native") {
375  llvm::StringMap<bool> HostFeatures;
376  if (llvm::sys::getHostCPUFeatures(HostFeatures))
377  for (auto &F : HostFeatures)
378  Features.push_back(
379  Args.MakeArgString((F.second ? "+" : "-") + F.first()));
380  } else if (!CPUName.empty()) {
381  // This sets the default features for the specified CPU. We certainly don't
382  // want to override the features that have been explicitly specified on the
383  // command line. Therefore, process them directly instead of appending them
384  // at the end later.
385  DecodeARMFeaturesFromCPU(D, CPUName, Features);
386  }
387 
388  if (CPUArg)
389  checkARMCPUName(D, CPUArg, Args, CPUName, ArchName,
390  ExtensionFeatures, Triple);
391  // Honor -mfpu=. ClangAs gives preference to -Wa,-mfpu=.
392  unsigned FPUID = llvm::ARM::FK_INVALID;
393  const Arg *FPUArg = Args.getLastArg(options::OPT_mfpu_EQ);
394  if (WaFPU) {
395  if (FPUArg)
396  D.Diag(clang::diag::warn_drv_unused_argument)
397  << FPUArg->getAsString(Args);
398  (void)getARMFPUFeatures(D, WaFPU, Args, StringRef(WaFPU->getValue()).substr(6),
399  Features);
400  } else if (FPUArg) {
401  FPUID = getARMFPUFeatures(D, FPUArg, Args, FPUArg->getValue(), Features);
402  } else if (Triple.isAndroid() && getARMSubArchVersionNumber(Triple) >= 7) {
403  const char *AndroidFPU = "neon";
404  FPUID = llvm::ARM::parseFPU(AndroidFPU);
405  if (!llvm::ARM::getFPUFeatures(FPUID, Features))
406  D.Diag(clang::diag::err_drv_clang_unsupported)
407  << std::string("-mfpu=") + AndroidFPU;
408  }
409 
410  // Now we've finished accumulating features from arch, cpu and fpu,
411  // we can append the ones for architecture extensions that we
412  // collected separately.
413  Features.insert(std::end(Features),
414  std::begin(ExtensionFeatures), std::end(ExtensionFeatures));
415 
416  // Honor -mhwdiv=. ClangAs gives preference to -Wa,-mhwdiv=.
417  const Arg *HDivArg = Args.getLastArg(options::OPT_mhwdiv_EQ);
418  if (WaHDiv) {
419  if (HDivArg)
420  D.Diag(clang::diag::warn_drv_unused_argument)
421  << HDivArg->getAsString(Args);
422  getARMHWDivFeatures(D, WaHDiv, Args,
423  StringRef(WaHDiv->getValue()).substr(8), Features);
424  } else if (HDivArg)
425  getARMHWDivFeatures(D, HDivArg, Args, HDivArg->getValue(), Features);
426 
427  // Handle (arch-dependent) fp16fml/fullfp16 relationship.
428  // Must happen before any features are disabled due to soft-float.
429  // FIXME: this fp16fml option handling will be reimplemented after the
430  // TargetParser rewrite.
431  const auto ItRNoFullFP16 = std::find(Features.rbegin(), Features.rend(), "-fullfp16");
432  const auto ItRFP16FML = std::find(Features.rbegin(), Features.rend(), "+fp16fml");
433  if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8_4a) {
434  const auto ItRFullFP16 = std::find(Features.rbegin(), Features.rend(), "+fullfp16");
435  if (ItRFullFP16 < ItRNoFullFP16 && ItRFullFP16 < ItRFP16FML) {
436  // Only entangled feature that can be to the right of this +fullfp16 is -fp16fml.
437  // Only append the +fp16fml if there is no -fp16fml after the +fullfp16.
438  if (std::find(Features.rbegin(), ItRFullFP16, "-fp16fml") == ItRFullFP16)
439  Features.push_back("+fp16fml");
440  }
441  else
442  goto fp16_fml_fallthrough;
443  }
444  else {
445 fp16_fml_fallthrough:
446  // In both of these cases, putting the 'other' feature on the end of the vector will
447  // result in the same effect as placing it immediately after the current feature.
448  if (ItRNoFullFP16 < ItRFP16FML)
449  Features.push_back("-fp16fml");
450  else if (ItRNoFullFP16 > ItRFP16FML)
451  Features.push_back("+fullfp16");
452  }
453 
454  // Setting -msoft-float/-mfloat-abi=soft effectively disables the FPU (GCC
455  // ignores the -mfpu options in this case).
456  // Note that the ABI can also be set implicitly by the target selected.
457  if (ABI == arm::FloatABI::Soft) {
458  llvm::ARM::getFPUFeatures(llvm::ARM::FK_NONE, Features);
459 
460  // Disable all features relating to hardware FP, not already disabled by the
461  // above call.
462  Features.insert(Features.end(), {"-neon", "-crypto", "-dotprod", "-fp16fml",
463  "-mve", "-mve.fp", "-fpregs"});
464  } else if (FPUID == llvm::ARM::FK_NONE) {
465  // -mfpu=none is *very* similar to -mfloat-abi=soft, only that it should not
466  // disable MVE-I.
467  Features.insert(Features.end(),
468  {"-neon", "-crypto", "-dotprod", "-fp16fml", "-mve.fp"});
469  // Even though we remove MVE-FP, we still need to check if it was originally
470  // present among the requested extensions, because it implies MVE-I, which
471  // should not be disabled by -mfpu-none.
472  if (!llvm::is_contained(Features, "+mve") &&
473  !llvm::is_contained(Features, "+mve.fp"))
474  Features.emplace_back("-fpregs");
475  }
476 
477  // En/disable crc code generation.
478  if (Arg *A = Args.getLastArg(options::OPT_mcrc, options::OPT_mnocrc)) {
479  if (A->getOption().matches(options::OPT_mcrc))
480  Features.push_back("+crc");
481  else
482  Features.push_back("-crc");
483  }
484 
485  // For Arch >= ARMv8.0 && A profile: crypto = sha2 + aes
486  // FIXME: this needs reimplementation after the TargetParser rewrite
487  auto CryptoIt = llvm::find_if(llvm::reverse(Features), [](const StringRef F) {
488  return F.contains("crypto");
489  });
490  if (CryptoIt != Features.rend()) {
491  if (CryptoIt->take_front() == "+") {
492  StringRef ArchSuffix = arm::getLLVMArchSuffixForARM(
493  arm::getARMTargetCPU(CPUName, ArchName, Triple), ArchName, Triple);
494  if (llvm::ARM::parseArchVersion(ArchSuffix) >= 8 &&
495  llvm::ARM::parseArchProfile(ArchSuffix) ==
496  llvm::ARM::ProfileKind::A) {
497  if (ArchName.find_lower("+nosha2") == StringRef::npos &&
498  CPUName.find_lower("+nosha2") == StringRef::npos)
499  Features.push_back("+sha2");
500  if (ArchName.find_lower("+noaes") == StringRef::npos &&
501  CPUName.find_lower("+noaes") == StringRef::npos)
502  Features.push_back("+aes");
503  } else {
504  D.Diag(clang::diag::warn_target_unsupported_extension)
505  << "crypto"
506  << llvm::ARM::getArchName(llvm::ARM::parseArch(ArchSuffix));
507  // With -fno-integrated-as -mfpu=crypto-neon-fp-armv8 some assemblers such as the GNU assembler
508  // will permit the use of crypto instructions as the fpu will override the architecture.
509  // We keep the crypto feature in this case to preserve compatibility.
510  // In all other cases we remove the crypto feature.
511  if (!Args.hasArg(options::OPT_fno_integrated_as))
512  Features.push_back("-crypto");
513  }
514  }
515  }
516 
517  // CMSE: Check for target 8M (for -mcmse to be applicable) is performed later.
518  if (Args.getLastArg(options::OPT_mcmse))
519  Features.push_back("+8msecext");
520 
521  // Look for the last occurrence of -mlong-calls or -mno-long-calls. If
522  // neither options are specified, see if we are compiling for kernel/kext and
523  // decide whether to pass "+long-calls" based on the OS and its version.
524  if (Arg *A = Args.getLastArg(options::OPT_mlong_calls,
525  options::OPT_mno_long_calls)) {
526  if (A->getOption().matches(options::OPT_mlong_calls))
527  Features.push_back("+long-calls");
528  } else if (KernelOrKext && (!Triple.isiOS() || Triple.isOSVersionLT(6)) &&
529  !Triple.isWatchOS()) {
530  Features.push_back("+long-calls");
531  }
532 
533  // Generate execute-only output (no data access to code sections).
534  // This only makes sense for the compiler, not for the assembler.
535  if (!ForAS) {
536  // Supported only on ARMv6T2 and ARMv7 and above.
537  // Cannot be combined with -mno-movt or -mlong-calls
538  if (Arg *A = Args.getLastArg(options::OPT_mexecute_only, options::OPT_mno_execute_only)) {
539  if (A->getOption().matches(options::OPT_mexecute_only)) {
540  if (getARMSubArchVersionNumber(Triple) < 7 &&
541  llvm::ARM::parseArch(Triple.getArchName()) != llvm::ARM::ArchKind::ARMV6T2)
542  D.Diag(diag::err_target_unsupported_execute_only) << Triple.getArchName();
543  else if (Arg *B = Args.getLastArg(options::OPT_mno_movt))
544  D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
545  // Long calls create constant pool entries and have not yet been fixed up
546  // to play nicely with execute-only. Hence, they cannot be used in
547  // execute-only code for now
548  else if (Arg *B = Args.getLastArg(options::OPT_mlong_calls, options::OPT_mno_long_calls)) {
549  if (B->getOption().matches(options::OPT_mlong_calls))
550  D.Diag(diag::err_opt_not_valid_with_opt) << A->getAsString(Args) << B->getAsString(Args);
551  }
552  Features.push_back("+execute-only");
553  }
554  }
555  }
556 
557  // Kernel code has more strict alignment requirements.
558  if (KernelOrKext)
559  Features.push_back("+strict-align");
560  else if (Arg *A = Args.getLastArg(options::OPT_mno_unaligned_access,
561  options::OPT_munaligned_access)) {
562  if (A->getOption().matches(options::OPT_munaligned_access)) {
563  // No v6M core supports unaligned memory access (v6M ARM ARM A3.2).
564  if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
565  D.Diag(diag::err_target_unsupported_unaligned) << "v6m";
566  // v8M Baseline follows on from v6M, so doesn't support unaligned memory
567  // access either.
568  else if (Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v8m_baseline)
569  D.Diag(diag::err_target_unsupported_unaligned) << "v8m.base";
570  } else
571  Features.push_back("+strict-align");
572  } else {
573  // Assume pre-ARMv6 doesn't support unaligned accesses.
574  //
575  // ARMv6 may or may not support unaligned accesses depending on the
576  // SCTLR.U bit, which is architecture-specific. We assume ARMv6
577  // Darwin and NetBSD targets support unaligned accesses, and others don't.
578  //
579  // ARMv7 always has SCTLR.U set to 1, but it has a new SCTLR.A bit
580  // which raises an alignment fault on unaligned accesses. Linux
581  // defaults this bit to 0 and handles it as a system-wide (not
582  // per-process) setting. It is therefore safe to assume that ARMv7+
583  // Linux targets support unaligned accesses. The same goes for NaCl.
584  //
585  // The above behavior is consistent with GCC.
586  int VersionNum = getARMSubArchVersionNumber(Triple);
587  if (Triple.isOSDarwin() || Triple.isOSNetBSD()) {
588  if (VersionNum < 6 ||
589  Triple.getSubArch() == llvm::Triple::SubArchType::ARMSubArch_v6m)
590  Features.push_back("+strict-align");
591  } else if (Triple.isOSLinux() || Triple.isOSNaCl()) {
592  if (VersionNum < 7)
593  Features.push_back("+strict-align");
594  } else
595  Features.push_back("+strict-align");
596  }
597 
598  // llvm does not support reserving registers in general. There is support
599  // for reserving r9 on ARM though (defined as a platform-specific register
600  // in ARM EABI).
601  if (Args.hasArg(options::OPT_ffixed_r9))
602  Features.push_back("+reserve-r9");
603 
604  // The kext linker doesn't know how to deal with movw/movt.
605  if (KernelOrKext || Args.hasArg(options::OPT_mno_movt))
606  Features.push_back("+no-movt");
607 
608  if (Args.hasArg(options::OPT_mno_neg_immediates))
609  Features.push_back("+no-neg-immediates");
610 }
611 
612 const std::string arm::getARMArch(StringRef Arch, const llvm::Triple &Triple) {
613  std::string MArch;
614  if (!Arch.empty())
615  MArch = Arch;
616  else
617  MArch = Triple.getArchName();
618  MArch = StringRef(MArch).split("+").first.lower();
619 
620  // Handle -march=native.
621  if (MArch == "native") {
622  std::string CPU = llvm::sys::getHostCPUName();
623  if (CPU != "generic") {
624  // Translate the native cpu into the architecture suffix for that CPU.
625  StringRef Suffix = arm::getLLVMArchSuffixForARM(CPU, MArch, Triple);
626  // If there is no valid architecture suffix for this CPU we don't know how
627  // to handle it, so return no architecture.
628  if (Suffix.empty())
629  MArch = "";
630  else
631  MArch = std::string("arm") + Suffix.str();
632  }
633  }
634 
635  return MArch;
636 }
637 
638 /// Get the (LLVM) name of the minimum ARM CPU for the arch we are targeting.
639 StringRef arm::getARMCPUForMArch(StringRef Arch, const llvm::Triple &Triple) {
640  std::string MArch = getARMArch(Arch, Triple);
641  // getARMCPUForArch defaults to the triple if MArch is empty, but empty MArch
642  // here means an -march=native that we can't handle, so instead return no CPU.
643  if (MArch.empty())
644  return StringRef();
645 
646  // We need to return an empty string here on invalid MArch values as the
647  // various places that call this function can't cope with a null result.
648  return Triple.getARMCPUForArch(MArch);
649 }
650 
651 /// getARMTargetCPU - Get the (LLVM) name of the ARM cpu we are targeting.
652 std::string arm::getARMTargetCPU(StringRef CPU, StringRef Arch,
653  const llvm::Triple &Triple) {
654  // FIXME: Warn on inconsistent use of -mcpu and -march.
655  // If we have -mcpu=, use that.
656  if (!CPU.empty()) {
657  std::string MCPU = StringRef(CPU).split("+").first.lower();
658  // Handle -mcpu=native.
659  if (MCPU == "native")
660  return llvm::sys::getHostCPUName();
661  else
662  return MCPU;
663  }
664 
665  return getARMCPUForMArch(Arch, Triple);
666 }
667 
668 /// getLLVMArchSuffixForARM - Get the LLVM ArchKind value to use for a
669 /// particular CPU (or Arch, if CPU is generic). This is needed to
670 /// pass to functions like llvm::ARM::getDefaultFPU which need an
671 /// ArchKind as well as a CPU name.
672 llvm::ARM::ArchKind arm::getLLVMArchKindForARM(StringRef CPU, StringRef Arch,
673  const llvm::Triple &Triple) {
674  llvm::ARM::ArchKind ArchKind;
675  if (CPU == "generic" || CPU.empty()) {
676  std::string ARMArch = tools::arm::getARMArch(Arch, Triple);
677  ArchKind = llvm::ARM::parseArch(ARMArch);
678  if (ArchKind == llvm::ARM::ArchKind::INVALID)
679  // In case of generic Arch, i.e. "arm",
680  // extract arch from default cpu of the Triple
681  ArchKind = llvm::ARM::parseCPUArch(Triple.getARMCPUForArch(ARMArch));
682  } else {
683  // FIXME: horrible hack to get around the fact that Cortex-A7 is only an
684  // armv7k triple if it's actually been specified via "-arch armv7k".
685  ArchKind = (Arch == "armv7k" || Arch == "thumbv7k")
686  ? llvm::ARM::ArchKind::ARMV7K
687  : llvm::ARM::parseCPUArch(CPU);
688  }
689  return ArchKind;
690 }
691 
692 /// getLLVMArchSuffixForARM - Get the LLVM arch name to use for a particular
693 /// CPU (or Arch, if CPU is generic).
694 // FIXME: This is redundant with -mcpu, why does LLVM use this.
695 StringRef arm::getLLVMArchSuffixForARM(StringRef CPU, StringRef Arch,
696  const llvm::Triple &Triple) {
697  llvm::ARM::ArchKind ArchKind = getLLVMArchKindForARM(CPU, Arch, Triple);
698  if (ArchKind == llvm::ARM::ArchKind::INVALID)
699  return "";
700  return llvm::ARM::getSubArch(ArchKind);
701 }
702 
703 void arm::appendBE8LinkFlag(const ArgList &Args, ArgStringList &CmdArgs,
704  const llvm::Triple &Triple) {
705  if (Args.hasArg(options::OPT_r))
706  return;
707 
708  // ARMv7 (and later) and ARMv6-M do not support BE-32, so instruct the linker
709  // to generate BE-8 executables.
710  if (arm::getARMSubArchVersionNumber(Triple) >= 7 || arm::isARMMProfile(Triple))
711  CmdArgs.push_back("--be8");
712 }
bool useAAPCSForMachO(const llvm::Triple &T)
Definition: ARM.cpp:132
DiagnosticBuilder Diag(unsigned DiagID) const
Definition: Driver.h:109
static void getExtensionFeatures(const Driver &D, const ArgList &Args, std::vector< StringRef > &Features, StringRef &MArch, StringRef &Exts)
Definition: RISCV.cpp:96
FloatABI getARMFloatABI(const ToolChain &TC, const llvm::opt::ArgList &Args)
const std::string getARMArch(llvm::StringRef Arch, const llvm::Triple &Triple)
static void DecodeARMFeaturesFromCPU(const Driver &D, StringRef CPU, std::vector< StringRef > &Features)
Definition: ARM.cpp:89
bool isARMMProfile(const llvm::Triple &Triple)
Definition: ARM.cpp:30
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:672
StringRef getARMCPUForMArch(llvm::StringRef Arch, const llvm::Triple &Triple)
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
const llvm::Triple & getEffectiveTriple() const
Get the toolchain&#39;s effective clang triple.
Definition: ToolChain.h:229
static bool DecodeARMFeatures(const Driver &D, StringRef text, StringRef CPU, llvm::ARM::ArchKind ArchKind, std::vector< StringRef > &Features)
Definition: ARM.cpp:76
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)
Definition: ARM.cpp:102
int getARMSubArchVersionNumber(const llvm::Triple &Triple)
Definition: ARM.cpp:24
const Driver & getDriver() const
Definition: ToolChain.h:199
std::string getARMTargetCPU(StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple)
Dataflow Directional Tag Classes.
void getARMArchCPUFromArgs(const llvm::opt::ArgList &Args, llvm::StringRef &Arch, llvm::StringRef &CPU, bool FromAs=false)
static void getARMHWDivFeatures(const Driver &D, const Arg *A, const ArgList &Args, StringRef HWDiv, std::vector< StringRef > &Features)
Definition: ARM.cpp:57
void appendBE8LinkFlag(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const llvm::Triple &Triple)
ReadTPMode getReadTPMode(const ToolChain &TC, const llvm::opt::ArgList &Args)
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)
Definition: ARM.cpp:117
void getARMTargetFeatures(const ToolChain &TC, const llvm::Triple &Triple, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, std::vector< llvm::StringRef > &Features, bool ForAS)
static unsigned getARMFPUFeatures(const Driver &D, const Arg *A, const ArgList &Args, StringRef FPU, std::vector< StringRef > &Features)
Definition: ARM.cpp:66
StringRef getLLVMArchSuffixForARM(llvm::StringRef CPU, llvm::StringRef Arch, const llvm::Triple &Triple)
ToolChain - Access to tools for a single platform.
Definition: ToolChain.h:88