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