Clang Project

clang_source_code/lib/Basic/Targets/ARM.cpp
1//===--- ARM.cpp - Implement ARM target feature support -------------------===//
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// This file implements ARM TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARM.h"
14#include "clang/Basic/Builtins.h"
15#include "clang/Basic/Diagnostic.h"
16#include "clang/Basic/TargetBuiltins.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/StringSwitch.h"
20
21using namespace clang;
22using namespace clang::targets;
23
24void ARMTargetInfo::setABIAAPCS() {
25  IsAAPCS = true;
26
27  DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28  const llvm::Triple &T = getTriple();
29
30  bool IsNetBSD = T.isOSNetBSD();
31  bool IsOpenBSD = T.isOSOpenBSD();
32  if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
33    WCharType = UnsignedInt;
34
35  UseBitFieldTypeAlignment = true;
36
37  ZeroLengthBitfieldBoundary = 0;
38
39  // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
40  // so set preferred for small types to 32.
41  if (T.isOSBinFormatMachO()) {
42    resetDataLayout(BigEndian
43                        ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
44                        : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
45  } else if (T.isOSWindows()) {
46     (0) . __assert_fail ("!BigEndian && \"Windows on ARM does not support big endian\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Targets/ARM.cpp", 46, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!BigEndian && "Windows on ARM does not support big endian");
47    resetDataLayout("e"
48                    "-m:w"
49                    "-p:32:32"
50                    "-Fi8"
51                    "-i64:64"
52                    "-v128:64:128"
53                    "-a:0:32"
54                    "-n32"
55                    "-S64");
56  } else if (T.isOSNaCl()) {
57     (0) . __assert_fail ("!BigEndian && \"NaCl on ARM does not support big endian\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Targets/ARM.cpp", 57, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!BigEndian && "NaCl on ARM does not support big endian");
58    resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
59  } else {
60    resetDataLayout(BigEndian
61                        ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
62                        : "e-m:e-p:32:32-Fi8-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     (0) . __assert_fail ("!BigEndian && \"AAPCS16 does not support big-endian\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Targets/ARM.cpp", 90, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(!BigEndian && "AAPCS16 does not support big-endian");
91    resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128");
92  } else if (T.isOSBinFormatMachO())
93    resetDataLayout(
94        BigEndian
95            ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
96            : "e-m:o-p:32:32-Fi8-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-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101            : "e-m:e-p:32:32-Fi8-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  // ACLE position independent code macros.
657  if (Opts.ROPI)
658    Builder.defineMacro("__ARM_ROPI""1");
659  if (Opts.RWPI)
660    Builder.defineMacro("__ARM_RWPI""1");
661
662  if (ArchKind == llvm::ARM::ArchKind::XSCALE)
663    Builder.defineMacro("__XSCALE__");
664
665  if (isThumb()) {
666    Builder.defineMacro("__THUMBEL__");
667    Builder.defineMacro("__thumb__");
668    if (supportsThumb2())
669      Builder.defineMacro("__thumb2__");
670  }
671
672  // ACLE 6.4.9 32-bit SIMD instructions
673  if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
674    Builder.defineMacro("__ARM_FEATURE_SIMD32""1");
675
676  // ACLE 6.4.10 Hardware Integer Divide
677  if (((HWDiv & HWDivThumb) && isThumb()) ||
678      ((HWDiv & HWDivARM) && !isThumb())) {
679    Builder.defineMacro("__ARM_FEATURE_IDIV""1");
680    Builder.defineMacro("__ARM_ARCH_EXT_IDIV__""1");
681  }
682
683  // Note, this is always on in gcc, even though it doesn't make sense.
684  Builder.defineMacro("__APCS_32__");
685
686  if (FPUModeIsVFP((FPUMode)FPU)) {
687    Builder.defineMacro("__VFP_FP__");
688    if (FPU & VFP2FPU)
689      Builder.defineMacro("__ARM_VFPV2__");
690    if (FPU & VFP3FPU)
691      Builder.defineMacro("__ARM_VFPV3__");
692    if (FPU & VFP4FPU)
693      Builder.defineMacro("__ARM_VFPV4__");
694    if (FPU & FPARMV8)
695      Builder.defineMacro("__ARM_FPV5__");
696  }
697
698  // This only gets set when Neon instructions are actually available, unlike
699  // the VFP define, hence the soft float and arch check. This is subtly
700  // different from gcc, we follow the intent which was that it should be set
701  // when Neon instructions are actually available.
702  if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
703    Builder.defineMacro("__ARM_NEON""1");
704    Builder.defineMacro("__ARM_NEON__");
705    // current AArch32 NEON implementations do not support double-precision
706    // floating-point even when it is present in VFP.
707    Builder.defineMacro("__ARM_NEON_FP",
708                        "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
709  }
710
711  Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
712                      Twine(Opts.WCharSize ? Opts.WCharSize : 4));
713
714  Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
715
716  if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
717    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
718    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
719    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
720    Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
721  }
722
723  // ACLE 6.4.7 DSP instructions
724  if (DSP) {
725    Builder.defineMacro("__ARM_FEATURE_DSP""1");
726  }
727
728  // ACLE 6.4.8 Saturation instructions
729  bool SAT = false;
730  if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
731    Builder.defineMacro("__ARM_FEATURE_SAT""1");
732    SAT = true;
733  }
734
735  // ACLE 6.4.6 Q (saturation) flag
736  if (DSP || SAT)
737    Builder.defineMacro("__ARM_FEATURE_QBIT""1");
738
739  if (Opts.UnsafeFPMath)
740    Builder.defineMacro("__ARM_FP_FAST""1");
741
742  // Armv8.2-A FP16 vector intrinsic
743  if ((FPU & NeonFPU) && HasLegalHalfType)
744    Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC""1");
745
746  // Armv8.2-A FP16 scalar intrinsics
747  if (HasLegalHalfType)
748    Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC""1");
749
750  // Armv8.2-A dot product intrinsics
751  if (DotProd)
752    Builder.defineMacro("__ARM_FEATURE_DOTPROD""1");
753
754  switch (ArchKind) {
755  default:
756    break;
757  case llvm::ARM::ArchKind::ARMV8_1A:
758    getTargetDefinesARMV81A(Opts, Builder);
759    break;
760  case llvm::ARM::ArchKind::ARMV8_2A:
761    getTargetDefinesARMV82A(Opts, Builder);
762    break;
763  }
764}
765
766const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
767#define BUILTIN(ID, TYPE, ATTRS)                                               \
768  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
769#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
770  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
771#include "clang/Basic/BuiltinsNEON.def"
772
773#define BUILTIN(ID, TYPE, ATTRS)                                               \
774  {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
775#define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
776  {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
777#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
778  {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
779#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
780  {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
781#include "clang/Basic/BuiltinsARM.def"
782};
783
784ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
785  return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
786                                             Builtin::FirstTSBuiltin);
787}
788
789bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
790TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
791  return IsAAPCS
792             ? AAPCSABIBuiltinVaList
793             : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
794                                         : TargetInfo::VoidPtrBuiltinVaList);
795}
796
797const char *const ARMTargetInfo::GCCRegNames[] = {
798    // Integer registers
799    "r0""r1""r2""r3""r4""r5""r6""r7""r8""r9""r10""r11",
800    "r12""sp""lr""pc",
801
802    // Float registers
803    "s0""s1""s2""s3""s4""s5""s6""s7""s8""s9""s10""s11",
804    "s12""s13""s14""s15""s16""s17""s18""s19""s20""s21""s22",
805    "s23""s24""s25""s26""s27""s28""s29""s30""s31",
806
807    // Double registers
808    "d0""d1""d2""d3""d4""d5""d6""d7""d8""d9""d10""d11",
809    "d12""d13""d14""d15""d16""d17""d18""d19""d20""d21""d22",
810    "d23""d24""d25""d26""d27""d28""d29""d30""d31",
811
812    // Quad registers
813    "q0""q1""q2""q3""q4""q5""q6""q7""q8""q9""q10""q11",
814    "q12""q13""q14""q15"};
815
816ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
817  return llvm::makeArrayRef(GCCRegNames);
818}
819
820const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
821    {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
822    {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
823    {{"v5"}, "r8"},  {{"v6""rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
824    {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
825    // The S, D and Q registers overlap, but aren't really aliases; we
826    // don't want to substitute one of these for a different-sized one.
827};
828
829ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
830  return llvm::makeArrayRef(GCCRegAliases);
831}
832
833bool ARMTargetInfo::validateAsmConstraint(
834    const char *&Name, TargetInfo::ConstraintInfo &Info) const {
835  switch (*Name) {
836  default:
837    break;
838  case 'l'// r0-r7
839  case 'h'// r8-r15
840  case 't'// VFP Floating point register single precision
841  case 'w'// VFP Floating point register double precision
842    Info.setAllowsRegister();
843    return true;
844  case 'I':
845  case 'J':
846  case 'K':
847  case 'L':
848  case 'M':
849    // FIXME
850    return true;
851  case 'Q'// A memory address that is a single base register.
852    Info.setAllowsMemory();
853    return true;
854  case 'U'// a memory reference...
855    switch (Name[1]) {
856    case 'q'// ...ARMV4 ldrsb
857    case 'v'// ...VFP load/store (reg+constant offset)
858    case 'y'// ...iWMMXt load/store
859    case 't'// address valid for load/store opaque types wider
860              // than 128-bits
861    case 'n'// valid address for Neon doubleword vector load/store
862    case 'm'// valid address for Neon element and structure load/store
863    case 's'// valid address for non-offset loads/stores of quad-word
864              // values in four ARM registers
865      Info.setAllowsMemory();
866      Name++;
867      return true;
868    }
869  }
870  return false;
871}
872
873std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
874  std::string R;
875  switch (*Constraint) {
876  case 'U'// Two-character constraint; add "^" hint for later parsing.
877    R = std::string("^") + std::string(Constraint, 2);
878    Constraint++;
879    break;
880  case 'p'// 'p' should be translated to 'r' by default.
881    R = std::string("r");
882    break;
883  default:
884    return std::string(1, *Constraint);
885  }
886  return R;
887}
888
889bool ARMTargetInfo::validateConstraintModifier(
890    StringRef Constraint, char Modifier, unsigned Size,
891    std::string &SuggestedModifier) const {
892  bool isOutput = (Constraint[0] == '=');
893  bool isInOut = (Constraint[0] == '+');
894
895  // Strip off constraint modifiers.
896  while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
897    Constraint = Constraint.substr(1);
898
899  switch (Constraint[0]) {
900  default:
901    break;
902  case 'r': {
903    switch (Modifier) {
904    default:
905      return (isInOut || isOutput || Size <= 64);
906    case 'q':
907      // A register of size 32 cannot fit a vector type.
908      return false;
909    }
910  }
911  }
912
913  return true;
914}
915const char *ARMTargetInfo::getClobbers() const {
916  // FIXME: Is this really right?
917  return "";
918}
919
920TargetInfo::CallingConvCheckResult
921ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
922  switch (CC) {
923  case CC_AAPCS:
924  case CC_AAPCS_VFP:
925  case CC_Swift:
926  case CC_OpenCLKernel:
927    return CCCR_OK;
928  default:
929    return CCCR_Warning;
930  }
931}
932
933int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
934  if (RegNo == 0)
935    return 0;
936  if (RegNo == 1)
937    return 1;
938  return -1;
939}
940
941bool ARMTargetInfo::hasSjLjLowering() const { return true; }
942
943ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
944                                 const TargetOptions &Opts)
945    : ARMTargetInfo(Triple, Opts) {}
946
947void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
948                                       MacroBuilder &Builder) const {
949  Builder.defineMacro("__ARMEL__");
950  ARMTargetInfo::getTargetDefines(Opts, Builder);
951}
952
953ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
954                                 const TargetOptions &Opts)
955    : ARMTargetInfo(Triple, Opts) {}
956
957void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
958                                       MacroBuilder &Builder) const {
959  Builder.defineMacro("__ARMEB__");
960  Builder.defineMacro("__ARM_BIG_ENDIAN");
961  ARMTargetInfo::getTargetDefines(Opts, Builder);
962}
963
964WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
965                                           const TargetOptions &Opts)
966    : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
967}
968
969void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
970                                                  MacroBuilder &Builder) const {
971  WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
972
973  // FIXME: this is invalid for WindowsCE
974  Builder.defineMacro("_M_ARM_NT""1");
975  Builder.defineMacro("_M_ARMT""_M_ARM");
976  Builder.defineMacro("_M_THUMB""_M_ARM");
977
978   (0) . __assert_fail ("(Triple.getArch() == llvm..Triple..arm || Triple.getArch() == llvm..Triple..thumb) && \"invalid architecture for Windows ARM target info\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Targets/ARM.cpp", 980, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert((Triple.getArch() == llvm::Triple::arm ||
979 (0) . __assert_fail ("(Triple.getArch() == llvm..Triple..arm || Triple.getArch() == llvm..Triple..thumb) && \"invalid architecture for Windows ARM target info\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Targets/ARM.cpp", 980, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">          Triple.getArch() == llvm::Triple::thumb) &&
980 (0) . __assert_fail ("(Triple.getArch() == llvm..Triple..arm || Triple.getArch() == llvm..Triple..thumb) && \"invalid architecture for Windows ARM target info\"", "/home/seafit/code_projects/clang_source/clang/lib/Basic/Targets/ARM.cpp", 980, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">         "invalid architecture for Windows ARM target info");
981  unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
982  Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
983
984  // TODO map the complete set of values
985  // 31: VFPv3 40: VFPv4
986  Builder.defineMacro("_M_ARM_FP""31");
987}
988
989TargetInfo::BuiltinVaListKind
990WindowsARMTargetInfo::getBuiltinVaListKind() const {
991  return TargetInfo::CharPtrBuiltinVaList;
992}
993
994TargetInfo::CallingConvCheckResult
995WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
996  switch (CC) {
997  case CC_X86StdCall:
998  case CC_X86ThisCall:
999  case CC_X86FastCall:
1000  case CC_X86VectorCall:
1001    return CCCR_Ignore;
1002  case CC_C:
1003  case CC_OpenCLKernel:
1004  case CC_PreserveMost:
1005  case CC_PreserveAll:
1006  case CC_Swift:
1007    return CCCR_OK;
1008  default:
1009    return CCCR_Warning;
1010  }
1011}
1012
1013// Windows ARM + Itanium C++ ABI Target
1014ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1015    const llvm::Triple &Triple, const TargetOptions &Opts)
1016    : WindowsARMTargetInfo(Triple, Opts) {
1017  TheCXXABI.set(TargetCXXABI::GenericARM);
1018}
1019
1020void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1021    const LangOptions &Opts, MacroBuilder &Builder) const {
1022  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1023
1024  if (Opts.MSVCCompat)
1025    WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1026}
1027
1028// Windows ARM, MS (C++) ABI
1029MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1030                                                   const TargetOptions &Opts)
1031    : WindowsARMTargetInfo(Triple, Opts) {
1032  TheCXXABI.set(TargetCXXABI::Microsoft);
1033}
1034
1035void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1036                                                MacroBuilder &Builder) const {
1037  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1038  WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1039}
1040
1041MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1042                                       const TargetOptions &Opts)
1043    : WindowsARMTargetInfo(Triple, Opts) {
1044  TheCXXABI.set(TargetCXXABI::GenericARM);
1045}
1046
1047void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1048                                          MacroBuilder &Builder) const {
1049  WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1050  Builder.defineMacro("_ARM_");
1051}
1052
1053CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1054                                         const TargetOptions &Opts)
1055    : ARMleTargetInfo(Triple, Opts) {
1056  this->WCharType = TargetInfo::UnsignedShort;
1057  TLSSupported = false;
1058  DoubleAlign = LongLongAlign = 64;
1059  resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1060}
1061
1062void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1063                                           MacroBuilder &Builder) const {
1064  ARMleTargetInfo::getTargetDefines(Opts, Builder);
1065  Builder.defineMacro("_ARM_");
1066  Builder.defineMacro("__CYGWIN__");
1067  Builder.defineMacro("__CYGWIN32__");
1068  DefineStd(Builder, "unix", Opts);
1069  if (Opts.CPlusPlus)
1070    Builder.defineMacro("_GNU_SOURCE");
1071}
1072
1073DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1074                                         const TargetOptions &Opts)
1075    : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1076  HasAlignMac68kSupport = true;
1077  // iOS always has 64-bit atomic instructions.
1078  // FIXME: This should be based off of the target features in
1079  // ARMleTargetInfo.
1080  MaxAtomicInlineWidth = 64;
1081
1082  if (Triple.isWatchABI()) {
1083    // Darwin on iOS uses a variant of the ARM C++ ABI.
1084    TheCXXABI.set(TargetCXXABI::WatchOS);
1085
1086    // BOOL should be a real boolean on the new ABI
1087    UseSignedCharForObjCBool = false;
1088  } else
1089    TheCXXABI.set(TargetCXXABI::iOS);
1090}
1091
1092void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1093                                       const llvm::Triple &Triple,
1094                                       MacroBuilder &Builder) const {
1095  getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1096}
1097
1098RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1099                                                   const TargetOptions &Opts)
1100    : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1101                                   Triple.getOSName(),
1102                                   Triple.getEnvironmentName()),
1103                      Opts) {
1104  IsRenderScriptTarget = true;
1105  LongWidth = LongAlign = 64;
1106}
1107
1108void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1109                                                MacroBuilder &Builder) const {
1110  Builder.defineMacro("__RENDERSCRIPT__");
1111  ARMleTargetInfo::getTargetDefines(Opts, Builder);
1112}
1113