ARM.cpp revision 344779
1//===--- ARM.cpp - Implement ARM target feature support -------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements ARM TargetInfo objects.
11//
12//===----------------------------------------------------------------------===//
13
14#include "ARM.h"
15#include "clang/Basic/Builtins.h"
16#include "clang/Basic/Diagnostic.h"
17#include "clang/Basic/TargetBuiltins.h"
18#include "llvm/ADT/StringExtras.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/StringSwitch.h"
21
22using namespace clang;
23using namespace clang::targets;
24
25void ARMTargetInfo::setABIAAPCS() {
26  IsAAPCS = true;
27
28  DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
29  const llvm::Triple &T = getTriple();
30
31  bool IsNetBSD = T.isOSNetBSD();
32  bool IsOpenBSD = T.isOSOpenBSD();
33  if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
34    WCharType = UnsignedInt;
35
36  UseBitFieldTypeAlignment = true;
37
38  ZeroLengthBitfieldBoundary = 0;
39
40  // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
41  // so set preferred for small types to 32.
42  if (T.isOSBinFormatMachO()) {
43    resetDataLayout(BigEndian
44                        ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
45                        : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
46  } else if (T.isOSWindows()) {
47    assert(!BigEndian && "Windows on ARM does not support big endian");
48    resetDataLayout("e"
49                    "-m:w"
50                    "-p:32:32"
51                    "-i64:64"
52                    "-v128:64:128"
53                    "-a:0:32"
54                    "-n32"
55                    "-S64");
56  } else if (T.isOSNaCl()) {
57    assert(!BigEndian && "NaCl on ARM does not support big endian");
58    resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
59  } else {
60    resetDataLayout(BigEndian
61                        ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
62                        : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
63  }
64
65  // FIXME: Enumerated types are variable width in straight AAPCS.
66}
67
68void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
69  const llvm::Triple &T = getTriple();
70
71  IsAAPCS = false;
72
73  if (IsAAPCS16)
74    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
75  else
76    DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
77
78  WCharType = SignedInt;
79
80  // Do not respect the alignment of bit-field types when laying out
81  // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
82  UseBitFieldTypeAlignment = false;
83
84  /// gcc forces the alignment to 4 bytes, regardless of the type of the
85  /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
86  /// gcc.
87  ZeroLengthBitfieldBoundary = 32;
88
89  if (T.isOSBinFormatMachO() && IsAAPCS16) {
90    assert(!BigEndian && "AAPCS16 does not support big-endian");
91    resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
92  } else if (T.isOSBinFormatMachO())
93    resetDataLayout(
94        BigEndian
95            ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96            : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
97  else
98    resetDataLayout(
99        BigEndian
100            ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101            : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
102
103  // FIXME: Override "preferred align" for double and long long.
104}
105
106void ARMTargetInfo::setArchInfo() {
107  StringRef ArchName = getTriple().getArchName();
108
109  ArchISA = llvm::ARM::parseArchISA(ArchName);
110  CPU = llvm::ARM::getDefaultCPU(ArchName);
111  llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
112  if (AK != llvm::ARM::ArchKind::INVALID)
113    ArchKind = AK;
114  setArchInfo(ArchKind);
115}
116
117void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
118  StringRef SubArch;
119
120  // cache TargetParser info
121  ArchKind = Kind;
122  SubArch = llvm::ARM::getSubArch(ArchKind);
123  ArchProfile = llvm::ARM::parseArchProfile(SubArch);
124  ArchVersion = llvm::ARM::parseArchVersion(SubArch);
125
126  // cache CPU related strings
127  CPUAttr = getCPUAttr();
128  CPUProfile = getCPUProfile();
129}
130
131void ARMTargetInfo::setAtomic() {
132  // when triple does not specify a sub arch,
133  // then we are not using inline atomics
134  bool ShouldUseInlineAtomic =
135      (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
136      (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
137  // Cortex M does not support 8 byte atomics, while general Thumb2 does.
138  if (ArchProfile == llvm::ARM::ProfileKind::M) {
139    MaxAtomicPromoteWidth = 32;
140    if (ShouldUseInlineAtomic)
141      MaxAtomicInlineWidth = 32;
142  } else {
143    MaxAtomicPromoteWidth = 64;
144    if (ShouldUseInlineAtomic)
145      MaxAtomicInlineWidth = 64;
146  }
147}
148
149bool ARMTargetInfo::isThumb() const {
150  return ArchISA == llvm::ARM::ISAKind::THUMB;
151}
152
153bool ARMTargetInfo::supportsThumb() const {
154  return CPUAttr.count('T') || ArchVersion >= 6;
155}
156
157bool ARMTargetInfo::supportsThumb2() const {
158  return CPUAttr.equals("6T2") ||
159         (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
160}
161
162StringRef ARMTargetInfo::getCPUAttr() const {
163  // For most sub-arches, the build attribute CPU name is enough.
164  // For Cortex variants, it's slightly different.
165  switch (ArchKind) {
166  default:
167    return llvm::ARM::getCPUAttr(ArchKind);
168  case llvm::ARM::ArchKind::ARMV6M:
169    return "6M";
170  case llvm::ARM::ArchKind::ARMV7S:
171    return "7S";
172  case llvm::ARM::ArchKind::ARMV7A:
173    return "7A";
174  case llvm::ARM::ArchKind::ARMV7R:
175    return "7R";
176  case llvm::ARM::ArchKind::ARMV7M:
177    return "7M";
178  case llvm::ARM::ArchKind::ARMV7EM:
179    return "7EM";
180  case llvm::ARM::ArchKind::ARMV7VE:
181    return "7VE";
182  case llvm::ARM::ArchKind::ARMV8A:
183    return "8A";
184  case llvm::ARM::ArchKind::ARMV8_1A:
185    return "8_1A";
186  case llvm::ARM::ArchKind::ARMV8_2A:
187    return "8_2A";
188  case llvm::ARM::ArchKind::ARMV8_3A:
189    return "8_3A";
190  case llvm::ARM::ArchKind::ARMV8_4A:
191    return "8_4A";
192  case llvm::ARM::ArchKind::ARMV8_5A:
193    return "8_5A";
194  case llvm::ARM::ArchKind::ARMV8MBaseline:
195    return "8M_BASE";
196  case llvm::ARM::ArchKind::ARMV8MMainline:
197    return "8M_MAIN";
198  case llvm::ARM::ArchKind::ARMV8R:
199    return "8R";
200  }
201}
202
203StringRef ARMTargetInfo::getCPUProfile() const {
204  switch (ArchProfile) {
205  case llvm::ARM::ProfileKind::A:
206    return "A";
207  case llvm::ARM::ProfileKind::R:
208    return "R";
209  case llvm::ARM::ProfileKind::M:
210    return "M";
211  default:
212    return "";
213  }
214}
215
216ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
217                             const TargetOptions &Opts)
218    : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
219      HW_FP(0) {
220  bool IsOpenBSD = Triple.isOSOpenBSD();
221  bool IsNetBSD = Triple.isOSNetBSD();
222
223  // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
224  // environment where size_t is `unsigned long` rather than `unsigned int`
225
226  PtrDiffType = IntPtrType =
227      (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
228       IsNetBSD)
229          ? SignedLong
230          : SignedInt;
231
232  SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
233              IsNetBSD)
234                 ? UnsignedLong
235                 : UnsignedInt;
236
237  // ptrdiff_t is inconsistent on Darwin
238  if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
239      !Triple.isWatchABI())
240    PtrDiffType = SignedInt;
241
242  // Cache arch related info.
243  setArchInfo();
244
245  // {} in inline assembly are neon specifiers, not assembly variant
246  // specifiers.
247  NoAsmVariants = true;
248
249  // FIXME: This duplicates code from the driver that sets the -target-abi
250  // option - this code is used if -target-abi isn't passed and should
251  // be unified in some way.
252  if (Triple.isOSBinFormatMachO()) {
253    // The backend is hardwired to assume AAPCS for M-class processors, ensure
254    // the frontend matches that.
255    if (Triple.getEnvironment() == llvm::Triple::EABI ||
256        Triple.getOS() == llvm::Triple::UnknownOS ||
257        ArchProfile == llvm::ARM::ProfileKind::M) {
258      setABI("aapcs");
259    } else if (Triple.isWatchABI()) {
260      setABI("aapcs16");
261    } else {
262      setABI("apcs-gnu");
263    }
264  } else if (Triple.isOSWindows()) {
265    // FIXME: this is invalid for WindowsCE
266    setABI("aapcs");
267  } else {
268    // Select the default based on the platform.
269    switch (Triple.getEnvironment()) {
270    case llvm::Triple::Android:
271    case llvm::Triple::GNUEABI:
272    case llvm::Triple::GNUEABIHF:
273    case llvm::Triple::MuslEABI:
274    case llvm::Triple::MuslEABIHF:
275      setABI("aapcs-linux");
276      break;
277    case llvm::Triple::EABIHF:
278    case llvm::Triple::EABI:
279      setABI("aapcs");
280      break;
281    case llvm::Triple::GNU:
282      setABI("apcs-gnu");
283      break;
284    default:
285      if (IsNetBSD)
286        setABI("apcs-gnu");
287      else if (IsOpenBSD)
288        setABI("aapcs-linux");
289      else
290        setABI("aapcs");
291      break;
292    }
293  }
294
295  // ARM targets default to using the ARM C++ ABI.
296  TheCXXABI.set(TargetCXXABI::GenericARM);
297
298  // ARM has atomics up to 8 bytes
299  setAtomic();
300
301  // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
302  if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
303    MaxVectorAlign = 64;
304
305  // Do force alignment of members that follow zero length bitfields.  If
306  // the alignment of the zero-length bitfield is greater than the member
307  // that follows it, `bar', `bar' will be aligned as the  type of the
308  // zero length bitfield.
309  UseZeroLengthBitfieldAlignment = true;
310
311  if (Triple.getOS() == llvm::Triple::Linux ||
312      Triple.getOS() == llvm::Triple::UnknownOS)
313    this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
314                           ? "\01__gnu_mcount_nc"
315                           : "\01mcount";
316}
317
318StringRef ARMTargetInfo::getABI() const { return ABI; }
319
320bool ARMTargetInfo::setABI(const std::string &Name) {
321  ABI = Name;
322
323  // The defaults (above) are for AAPCS, check if we need to change them.
324  //
325  // FIXME: We need support for -meabi... we could just mangle it into the
326  // name.
327  if (Name == "apcs-gnu" || Name == "aapcs16") {
328    setABIAPCS(Name == "aapcs16");
329    return true;
330  }
331  if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
332    setABIAAPCS();
333    return true;
334  }
335  return false;
336}
337
338// FIXME: This should be based on Arch attributes, not CPU names.
339bool ARMTargetInfo::initFeatureMap(
340    llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
341    const std::vector<std::string> &FeaturesVec) const {
342
343  std::string ArchFeature;
344  std::vector<StringRef> TargetFeatures;
345  llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
346
347  // Map the base architecture to an appropriate target feature, so we don't
348  // rely on the target triple.
349  llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
350  if (CPUArch == llvm::ARM::ArchKind::INVALID)
351    CPUArch = Arch;
352  if (CPUArch != llvm::ARM::ArchKind::INVALID) {
353    ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
354    TargetFeatures.push_back(ArchFeature);
355  }
356
357  // get default FPU features
358  unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
359  llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
360
361  // get default Extension features
362  unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
363  llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
364
365  for (auto Feature : TargetFeatures)
366    if (Feature[0] == '+')
367      Features[Feature.drop_front(1)] = true;
368
369  // Enable or disable thumb-mode explicitly per function to enable mixed
370  // ARM and Thumb code generation.
371  if (isThumb())
372    Features["thumb-mode"] = true;
373  else
374    Features["thumb-mode"] = false;
375
376  // Convert user-provided arm and thumb GNU target attributes to
377  // [-|+]thumb-mode target features respectively.
378  std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
379  for (auto &Feature : UpdatedFeaturesVec) {
380    if (Feature.compare("+arm") == 0)
381      Feature = "-thumb-mode";
382    else if (Feature.compare("+thumb") == 0)
383      Feature = "+thumb-mode";
384  }
385
386  return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
387}
388
389
390bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
391                                         DiagnosticsEngine &Diags) {
392  FPU = 0;
393  CRC = 0;
394  Crypto = 0;
395  DSP = 0;
396  Unaligned = 1;
397  SoftFloat = SoftFloatABI = false;
398  HWDiv = 0;
399  DotProd = 0;
400  HasFloat16 = true;
401
402  // This does not diagnose illegal cases like having both
403  // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
404  uint32_t HW_FP_remove = 0;
405  for (const auto &Feature : Features) {
406    if (Feature == "+soft-float") {
407      SoftFloat = true;
408    } else if (Feature == "+soft-float-abi") {
409      SoftFloatABI = true;
410    } else if (Feature == "+vfp2") {
411      FPU |= VFP2FPU;
412      HW_FP |= HW_FP_SP | HW_FP_DP;
413    } else if (Feature == "+vfp3") {
414      FPU |= VFP3FPU;
415      HW_FP |= HW_FP_SP | HW_FP_DP;
416    } else if (Feature == "+vfp4") {
417      FPU |= VFP4FPU;
418      HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
419    } else if (Feature == "+fp-armv8") {
420      FPU |= FPARMV8;
421      HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
422    } else if (Feature == "+neon") {
423      FPU |= NeonFPU;
424      HW_FP |= HW_FP_SP | HW_FP_DP;
425    } else if (Feature == "+hwdiv") {
426      HWDiv |= HWDivThumb;
427    } else if (Feature == "+hwdiv-arm") {
428      HWDiv |= HWDivARM;
429    } else if (Feature == "+crc") {
430      CRC = 1;
431    } else if (Feature == "+crypto") {
432      Crypto = 1;
433    } else if (Feature == "+dsp") {
434      DSP = 1;
435    } else if (Feature == "+fp-only-sp") {
436      HW_FP_remove |= HW_FP_DP;
437    } else if (Feature == "+strict-align") {
438      Unaligned = 0;
439    } else if (Feature == "+fp16") {
440      HW_FP |= HW_FP_HP;
441    } else if (Feature == "+fullfp16") {
442      HasLegalHalfType = true;
443    } else if (Feature == "+dotprod") {
444      DotProd = true;
445    }
446  }
447  HW_FP &= ~HW_FP_remove;
448
449  switch (ArchVersion) {
450  case 6:
451    if (ArchProfile == llvm::ARM::ProfileKind::M)
452      LDREX = 0;
453    else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
454      LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
455    else
456      LDREX = LDREX_W;
457    break;
458  case 7:
459    if (ArchProfile == llvm::ARM::ProfileKind::M)
460      LDREX = LDREX_W | LDREX_H | LDREX_B;
461    else
462      LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
463    break;
464  case 8:
465    LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
466  }
467
468  if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
469    Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
470    return false;
471  }
472
473  if (FPMath == FP_Neon)
474    Features.push_back("+neonfp");
475  else if (FPMath == FP_VFP)
476    Features.push_back("-neonfp");
477
478  // Remove front-end specific options which the backend handles differently.
479  auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
480  if (Feature != Features.end())
481    Features.erase(Feature);
482
483  return true;
484}
485
486bool ARMTargetInfo::hasFeature(StringRef Feature) const {
487  return llvm::StringSwitch<bool>(Feature)
488      .Case("arm", true)
489      .Case("aarch32", true)
490      .Case("softfloat", SoftFloat)
491      .Case("thumb", isThumb())
492      .Case("neon", (FPU & NeonFPU) && !SoftFloat)
493      .Case("vfp", FPU && !SoftFloat)
494      .Case("hwdiv", HWDiv & HWDivThumb)
495      .Case("hwdiv-arm", HWDiv & HWDivARM)
496      .Default(false);
497}
498
499bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
500  return Name == "generic" ||
501         llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
502}
503
504void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
505  llvm::ARM::fillValidCPUArchList(Values);
506}
507
508bool ARMTargetInfo::setCPU(const std::string &Name) {
509  if (Name != "generic")
510    setArchInfo(llvm::ARM::parseCPUArch(Name));
511
512  if (ArchKind == llvm::ARM::ArchKind::INVALID)
513    return false;
514  setAtomic();
515  CPU = Name;
516  return true;
517}
518
519bool ARMTargetInfo::setFPMath(StringRef Name) {
520  if (Name == "neon") {
521    FPMath = FP_Neon;
522    return true;
523  } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
524             Name == "vfp4") {
525    FPMath = FP_VFP;
526    return true;
527  }
528  return false;
529}
530
531void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
532                                            MacroBuilder &Builder) const {
533  Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
534}
535
536void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
537                                            MacroBuilder &Builder) const {
538  // Also include the ARMv8.1-A defines
539  getTargetDefinesARMV81A(Opts, Builder);
540}
541
542void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
543                                     MacroBuilder &Builder) const {
544  // Target identification.
545  Builder.defineMacro("__arm");
546  Builder.defineMacro("__arm__");
547  // For bare-metal none-eabi.
548  if (getTriple().getOS() == llvm::Triple::UnknownOS &&
549      (getTriple().getEnvironment() == llvm::Triple::EABI ||
550       getTriple().getEnvironment() == llvm::Triple::EABIHF))
551    Builder.defineMacro("__ELF__");
552
553  // Target properties.
554  Builder.defineMacro("__REGISTER_PREFIX__", "");
555
556  // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
557  // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
558  if (getTriple().isWatchABI())
559    Builder.defineMacro("__ARM_ARCH_7K__", "2");
560
561  if (!CPUAttr.empty())
562    Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
563
564  // ACLE 6.4.1 ARM/Thumb instruction set architecture
565  // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
566  Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
567
568  if (ArchVersion >= 8) {
569    // ACLE 6.5.7 Crypto Extension
570    if (Crypto)
571      Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
572    // ACLE 6.5.8 CRC32 Extension
573    if (CRC)
574      Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
575    // ACLE 6.5.10 Numeric Maximum and Minimum
576    Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
577    // ACLE 6.5.9 Directed Rounding
578    Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
579  }
580
581  // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
582  // is not defined for the M-profile.
583  // NOTE that the default profile is assumed to be 'A'
584  if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
585    Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
586
587  // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
588  // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
589  // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
590  // v7 and v8 architectures excluding v8-M Baseline.
591  if (supportsThumb2())
592    Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
593  else if (supportsThumb())
594    Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
595
596  // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
597  // instruction set such as ARM or Thumb.
598  Builder.defineMacro("__ARM_32BIT_STATE", "1");
599
600  // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
601
602  // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
603  if (!CPUProfile.empty())
604    Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
605
606  // ACLE 6.4.3 Unaligned access supported in hardware
607  if (Unaligned)
608    Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
609
610  // ACLE 6.4.4 LDREX/STREX
611  if (LDREX)
612    Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
613
614  // ACLE 6.4.5 CLZ
615  if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
616      ArchVersion > 6)
617    Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
618
619  // ACLE 6.5.1 Hardware Floating Point
620  if (HW_FP)
621    Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
622
623  // ACLE predefines.
624  Builder.defineMacro("__ARM_ACLE", "200");
625
626  // FP16 support (we currently only support IEEE format).
627  Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
628  Builder.defineMacro("__ARM_FP16_ARGS", "1");
629
630  // ACLE 6.5.3 Fused multiply-accumulate (FMA)
631  if (ArchVersion >= 7 && (FPU & VFP4FPU))
632    Builder.defineMacro("__ARM_FEATURE_FMA", "1");
633
634  // Subtarget options.
635
636  // FIXME: It's more complicated than this and we don't really support
637  // interworking.
638  // Windows on ARM does not "support" interworking
639  if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
640    Builder.defineMacro("__THUMB_INTERWORK__");
641
642  if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
643    // Embedded targets on Darwin follow AAPCS, but not EABI.
644    // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
645    if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
646      Builder.defineMacro("__ARM_EABI__");
647    Builder.defineMacro("__ARM_PCS", "1");
648  }
649
650  if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
651    Builder.defineMacro("__ARM_PCS_VFP", "1");
652
653  if (SoftFloat)
654    Builder.defineMacro("__SOFTFP__");
655
656  if (ArchKind == llvm::ARM::ArchKind::XSCALE)
657    Builder.defineMacro("__XSCALE__");
658
659  if (isThumb()) {
660    Builder.defineMacro("__THUMBEL__");
661    Builder.defineMacro("__thumb__");
662    if (supportsThumb2())
663      Builder.defineMacro("__thumb2__");
664  }
665
666  // ACLE 6.4.9 32-bit SIMD instructions
667  if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
668    Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
669
670  // ACLE 6.4.10 Hardware Integer Divide
671  if (((HWDiv & HWDivThumb) && isThumb()) ||
672      ((HWDiv & HWDivARM) && !isThumb())) {
673    Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
674    Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
675  }
676
677  // Note, this is always on in gcc, even though it doesn't make sense.
678  Builder.defineMacro("__APCS_32__");
679
680  if (FPUModeIsVFP((FPUMode)FPU)) {
681    Builder.defineMacro("__VFP_FP__");
682    if (FPU & VFP2FPU)
683      Builder.defineMacro("__ARM_VFPV2__");
684    if (FPU & VFP3FPU)
685      Builder.defineMacro("__ARM_VFPV3__");
686    if (FPU & VFP4FPU)
687      Builder.defineMacro("__ARM_VFPV4__");
688    if (FPU & FPARMV8)
689      Builder.defineMacro("__ARM_FPV5__");
690  }
691
692  // This only gets set when Neon instructions are actually available, unlike
693  // the VFP define, hence the soft float and arch check. This is subtly
694  // different from gcc, we follow the intent which was that it should be set
695  // when Neon instructions are actually available.
696  if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
697    Builder.defineMacro("__ARM_NEON", "1");
698    Builder.defineMacro("__ARM_NEON__");
699    // current AArch32 NEON implementations do not support double-precision
700    // floating-point even when it is present in VFP.
701    Builder.defineMacro("__ARM_NEON_FP",
702                        "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
703  }
704
705  Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
706                      Twine(Opts.WCharSize ? Opts.WCharSize : 4));
707
708  Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
709
710  if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
711    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
712    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
713    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
714    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
715  }
716
717  // ACLE 6.4.7 DSP instructions
718  if (DSP) {
719    Builder.defineMacro("__ARM_FEATURE_DSP", "1");
720  }
721
722  // ACLE 6.4.8 Saturation instructions
723  bool SAT = false;
724  if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
725    Builder.defineMacro("__ARM_FEATURE_SAT", "1");
726    SAT = true;
727  }
728
729  // ACLE 6.4.6 Q (saturation) flag
730  if (DSP || SAT)
731    Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
732
733  if (Opts.UnsafeFPMath)
734    Builder.defineMacro("__ARM_FP_FAST", "1");
735
736  // Armv8.2-A FP16 vector intrinsic
737  if ((FPU & NeonFPU) && HasLegalHalfType)
738    Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
739
740  // Armv8.2-A FP16 scalar intrinsics
741  if (HasLegalHalfType)
742    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
743
744  // Armv8.2-A dot product intrinsics
745  if (DotProd)
746    Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
747
748  switch (ArchKind) {
749  default:
750    break;
751  case llvm::ARM::ArchKind::ARMV8_1A:
752    getTargetDefinesARMV81A(Opts, Builder);
753    break;
754  case llvm::ARM::ArchKind::ARMV8_2A:
755    getTargetDefinesARMV82A(Opts, Builder);
756    break;
757  }
758}
759
760const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
761#define BUILTIN(ID, TYPE, ATTRS)                                               \
762  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
763#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
764  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
765#include "clang/Basic/BuiltinsNEON.def"
766
767#define BUILTIN(ID, TYPE, ATTRS)                                               \
768  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
769#define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
770  {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
771#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
772  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
773#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
774  {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
775#include "clang/Basic/BuiltinsARM.def"
776};
777
778ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
779  return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
780                                             Builtin::FirstTSBuiltin);
781}
782
783bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
784TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
785  return IsAAPCS
786             ? AAPCSABIBuiltinVaList
787             : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
788                                         : TargetInfo::VoidPtrBuiltinVaList);
789}
790
791const char *const ARMTargetInfo::GCCRegNames[] = {
792    // Integer registers
793    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
794    "r12", "sp", "lr", "pc",
795
796    // Float registers
797    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
798    "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
799    "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
800
801    // Double registers
802    "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
803    "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
804    "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
805
806    // Quad registers
807    "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
808    "q12", "q13", "q14", "q15"};
809
810ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
811  return llvm::makeArrayRef(GCCRegNames);
812}
813
814const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
815    {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
816    {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
817    {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
818    {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
819    // The S, D and Q registers overlap, but aren't really aliases; we
820    // don't want to substitute one of these for a different-sized one.
821};
822
823ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
824  return llvm::makeArrayRef(GCCRegAliases);
825}
826
827bool ARMTargetInfo::validateAsmConstraint(
828    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
829  switch (*Name) {
830  default:
831    break;
832  case 'l': // r0-r7
833  case 'h': // r8-r15
834  case 't': // VFP Floating point register single precision
835  case 'w': // VFP Floating point register double precision
836    Info.setAllowsRegister();
837    return true;
838  case 'I':
839  case 'J':
840  case 'K':
841  case 'L':
842  case 'M':
843    // FIXME
844    return true;
845  case 'Q': // A memory address that is a single base register.
846    Info.setAllowsMemory();
847    return true;
848  case 'U': // a memory reference...
849    switch (Name[1]) {
850    case 'q': // ...ARMV4 ldrsb
851    case 'v': // ...VFP load/store (reg+constant offset)
852    case 'y': // ...iWMMXt load/store
853    case 't': // address valid for load/store opaque types wider
854              // than 128-bits
855    case 'n': // valid address for Neon doubleword vector load/store
856    case 'm': // valid address for Neon element and structure load/store
857    case 's': // valid address for non-offset loads/stores of quad-word
858              // values in four ARM registers
859      Info.setAllowsMemory();
860      Name++;
861      return true;
862    }
863  }
864  return false;
865}
866
867std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
868  std::string R;
869  switch (*Constraint) {
870  case 'U': // Two-character constraint; add "^" hint for later parsing.
871    R = std::string("^") + std::string(Constraint, 2);
872    Constraint++;
873    break;
874  case 'p': // 'p' should be translated to 'r' by default.
875    R = std::string("r");
876    break;
877  default:
878    return std::string(1, *Constraint);
879  }
880  return R;
881}
882
883bool ARMTargetInfo::validateConstraintModifier(
884    StringRef Constraint, char Modifier, unsigned Size,
885    std::string &SuggestedModifier) const {
886  bool isOutput = (Constraint[0] == '=');
887  bool isInOut = (Constraint[0] == '+');
888
889  // Strip off constraint modifiers.
890  while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
891    Constraint = Constraint.substr(1);
892
893  switch (Constraint[0]) {
894  default:
895    break;
896  case 'r': {
897    switch (Modifier) {
898    default:
899      return (isInOut || isOutput || Size <= 64);
900    case 'q':
901      // A register of size 32 cannot fit a vector type.
902      return false;
903    }
904  }
905  }
906
907  return true;
908}
909const char *ARMTargetInfo::getClobbers() const {
910  // FIXME: Is this really right?
911  return "";
912}
913
914TargetInfo::CallingConvCheckResult
915ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
916  switch (CC) {
917  case CC_AAPCS:
918  case CC_AAPCS_VFP:
919  case CC_Swift:
920  case CC_OpenCLKernel:
921    return CCCR_OK;
922  default:
923    return CCCR_Warning;
924  }
925}
926
927int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
928  if (RegNo == 0)
929    return 0;
930  if (RegNo == 1)
931    return 1;
932  return -1;
933}
934
935bool ARMTargetInfo::hasSjLjLowering() const { return true; }
936
937ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
938                                 const TargetOptions &Opts)
939    : ARMTargetInfo(Triple, Opts) {}
940
941void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
942                                       MacroBuilder &Builder) const {
943  Builder.defineMacro("__ARMEL__");
944  ARMTargetInfo::getTargetDefines(Opts, Builder);
945}
946
947ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
948                                 const TargetOptions &Opts)
949    : ARMTargetInfo(Triple, Opts) {}
950
951void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
952                                       MacroBuilder &Builder) const {
953  Builder.defineMacro("__ARMEB__");
954  Builder.defineMacro("__ARM_BIG_ENDIAN");
955  ARMTargetInfo::getTargetDefines(Opts, Builder);
956}
957
958WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
959                                           const TargetOptions &Opts)
960    : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
961}
962
963void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
964                                                  MacroBuilder &Builder) const {
965  WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
966
967  // FIXME: this is invalid for WindowsCE
968  Builder.defineMacro("_M_ARM_NT", "1");
969  Builder.defineMacro("_M_ARMT", "_M_ARM");
970  Builder.defineMacro("_M_THUMB", "_M_ARM");
971
972  assert((Triple.getArch() == llvm::Triple::arm ||
973          Triple.getArch() == llvm::Triple::thumb) &&
974         "invalid architecture for Windows ARM target info");
975  unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
976  Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
977
978  // TODO map the complete set of values
979  // 31: VFPv3 40: VFPv4
980  Builder.defineMacro("_M_ARM_FP", "31");
981}
982
983TargetInfo::BuiltinVaListKind
984WindowsARMTargetInfo::getBuiltinVaListKind() const {
985  return TargetInfo::CharPtrBuiltinVaList;
986}
987
988TargetInfo::CallingConvCheckResult
989WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
990  switch (CC) {
991  case CC_X86StdCall:
992  case CC_X86ThisCall:
993  case CC_X86FastCall:
994  case CC_X86VectorCall:
995    return CCCR_Ignore;
996  case CC_C:
997  case CC_OpenCLKernel:
998  case CC_PreserveMost:
999  case CC_PreserveAll:
1000  case CC_Swift:
1001    return CCCR_OK;
1002  default:
1003    return CCCR_Warning;
1004  }
1005}
1006
1007// Windows ARM + Itanium C++ ABI Target
1008ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1009    const llvm::Triple &Triple, const TargetOptions &Opts)
1010    : WindowsARMTargetInfo(Triple, Opts) {
1011  TheCXXABI.set(TargetCXXABI::GenericARM);
1012}
1013
1014void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1015    const LangOptions &Opts, MacroBuilder &Builder) const {
1016  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1017
1018  if (Opts.MSVCCompat)
1019    WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1020}
1021
1022// Windows ARM, MS (C++) ABI
1023MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1024                                                   const TargetOptions &Opts)
1025    : WindowsARMTargetInfo(Triple, Opts) {
1026  TheCXXABI.set(TargetCXXABI::Microsoft);
1027}
1028
1029void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1030                                                MacroBuilder &Builder) const {
1031  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1032  WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1033}
1034
1035MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1036                                       const TargetOptions &Opts)
1037    : WindowsARMTargetInfo(Triple, Opts) {
1038  TheCXXABI.set(TargetCXXABI::GenericARM);
1039}
1040
1041void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1042                                          MacroBuilder &Builder) const {
1043  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1044  Builder.defineMacro("_ARM_");
1045}
1046
1047CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1048                                         const TargetOptions &Opts)
1049    : ARMleTargetInfo(Triple, Opts) {
1050  this->WCharType = TargetInfo::UnsignedShort;
1051  TLSSupported = false;
1052  DoubleAlign = LongLongAlign = 64;
1053  resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1054}
1055
1056void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1057                                           MacroBuilder &Builder) const {
1058  ARMleTargetInfo::getTargetDefines(Opts, Builder);
1059  Builder.defineMacro("_ARM_");
1060  Builder.defineMacro("__CYGWIN__");
1061  Builder.defineMacro("__CYGWIN32__");
1062  DefineStd(Builder, "unix", Opts);
1063  if (Opts.CPlusPlus)
1064    Builder.defineMacro("_GNU_SOURCE");
1065}
1066
1067DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1068                                         const TargetOptions &Opts)
1069    : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1070  HasAlignMac68kSupport = true;
1071  // iOS always has 64-bit atomic instructions.
1072  // FIXME: This should be based off of the target features in
1073  // ARMleTargetInfo.
1074  MaxAtomicInlineWidth = 64;
1075
1076  if (Triple.isWatchABI()) {
1077    // Darwin on iOS uses a variant of the ARM C++ ABI.
1078    TheCXXABI.set(TargetCXXABI::WatchOS);
1079
1080    // BOOL should be a real boolean on the new ABI
1081    UseSignedCharForObjCBool = false;
1082  } else
1083    TheCXXABI.set(TargetCXXABI::iOS);
1084}
1085
1086void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1087                                       const llvm::Triple &Triple,
1088                                       MacroBuilder &Builder) const {
1089  getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1090}
1091
1092RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1093                                                   const TargetOptions &Opts)
1094    : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1095                                   Triple.getOSName(),
1096                                   Triple.getEnvironmentName()),
1097                      Opts) {
1098  IsRenderScriptTarget = true;
1099  LongWidth = LongAlign = 64;
1100}
1101
1102void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1103                                                MacroBuilder &Builder) const {
1104  Builder.defineMacro("__RENDERSCRIPT__");
1105  ARMleTargetInfo::getTargetDefines(Opts, Builder);
1106}
1107