xref: /openbsd-src/gnu/llvm/clang/lib/Basic/Targets/ARM.cpp (revision 12c855180aad702bbcca06e0398d774beeafb155)
1e5dd7070Spatrick //===--- ARM.cpp - Implement ARM target feature support -------------------===//
2e5dd7070Spatrick //
3e5dd7070Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4e5dd7070Spatrick // See https://llvm.org/LICENSE.txt for license information.
5e5dd7070Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6e5dd7070Spatrick //
7e5dd7070Spatrick //===----------------------------------------------------------------------===//
8e5dd7070Spatrick //
9e5dd7070Spatrick // This file implements ARM TargetInfo objects.
10e5dd7070Spatrick //
11e5dd7070Spatrick //===----------------------------------------------------------------------===//
12e5dd7070Spatrick 
13e5dd7070Spatrick #include "ARM.h"
14e5dd7070Spatrick #include "clang/Basic/Builtins.h"
15e5dd7070Spatrick #include "clang/Basic/Diagnostic.h"
16e5dd7070Spatrick #include "clang/Basic/TargetBuiltins.h"
17e5dd7070Spatrick #include "llvm/ADT/StringExtras.h"
18e5dd7070Spatrick #include "llvm/ADT/StringRef.h"
19e5dd7070Spatrick #include "llvm/ADT/StringSwitch.h"
20e5dd7070Spatrick 
21e5dd7070Spatrick using namespace clang;
22e5dd7070Spatrick using namespace clang::targets;
23e5dd7070Spatrick 
setABIAAPCS()24e5dd7070Spatrick void ARMTargetInfo::setABIAAPCS() {
25e5dd7070Spatrick   IsAAPCS = true;
26e5dd7070Spatrick 
27e5dd7070Spatrick   DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28ec727ea7Spatrick   BFloat16Width = BFloat16Align = 16;
29ec727ea7Spatrick   BFloat16Format = &llvm::APFloat::BFloat();
30ec727ea7Spatrick 
31e5dd7070Spatrick   const llvm::Triple &T = getTriple();
32e5dd7070Spatrick 
33e5dd7070Spatrick   bool IsNetBSD = T.isOSNetBSD();
34e5dd7070Spatrick   bool IsOpenBSD = T.isOSOpenBSD();
35e5dd7070Spatrick   if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
36e5dd7070Spatrick     WCharType = UnsignedInt;
37e5dd7070Spatrick 
38e5dd7070Spatrick   UseBitFieldTypeAlignment = true;
39e5dd7070Spatrick 
40e5dd7070Spatrick   ZeroLengthBitfieldBoundary = 0;
41e5dd7070Spatrick 
42e5dd7070Spatrick   // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
43e5dd7070Spatrick   // so set preferred for small types to 32.
44e5dd7070Spatrick   if (T.isOSBinFormatMachO()) {
45e5dd7070Spatrick     resetDataLayout(BigEndian
46e5dd7070Spatrick                         ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
47a9ac8606Spatrick                         : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
48a9ac8606Spatrick                     "_");
49e5dd7070Spatrick   } else if (T.isOSWindows()) {
50e5dd7070Spatrick     assert(!BigEndian && "Windows on ARM does not support big endian");
51e5dd7070Spatrick     resetDataLayout("e"
52e5dd7070Spatrick                     "-m:w"
53e5dd7070Spatrick                     "-p:32:32"
54e5dd7070Spatrick                     "-Fi8"
55e5dd7070Spatrick                     "-i64:64"
56e5dd7070Spatrick                     "-v128:64:128"
57e5dd7070Spatrick                     "-a:0:32"
58e5dd7070Spatrick                     "-n32"
59e5dd7070Spatrick                     "-S64");
60e5dd7070Spatrick   } else if (T.isOSNaCl()) {
61e5dd7070Spatrick     assert(!BigEndian && "NaCl on ARM does not support big endian");
62e5dd7070Spatrick     resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
63e5dd7070Spatrick   } else {
64e5dd7070Spatrick     resetDataLayout(BigEndian
65e5dd7070Spatrick                         ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
66e5dd7070Spatrick                         : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
67e5dd7070Spatrick   }
68e5dd7070Spatrick 
69e5dd7070Spatrick   // FIXME: Enumerated types are variable width in straight AAPCS.
70e5dd7070Spatrick }
71e5dd7070Spatrick 
setABIAPCS(bool IsAAPCS16)72e5dd7070Spatrick void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
73e5dd7070Spatrick   const llvm::Triple &T = getTriple();
74e5dd7070Spatrick 
75e5dd7070Spatrick   IsAAPCS = false;
76e5dd7070Spatrick 
77e5dd7070Spatrick   if (IsAAPCS16)
78e5dd7070Spatrick     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
79e5dd7070Spatrick   else
80e5dd7070Spatrick     DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
81ec727ea7Spatrick   BFloat16Width = BFloat16Align = 16;
82ec727ea7Spatrick   BFloat16Format = &llvm::APFloat::BFloat();
83e5dd7070Spatrick 
84e5dd7070Spatrick   WCharType = SignedInt;
85e5dd7070Spatrick 
86e5dd7070Spatrick   // Do not respect the alignment of bit-field types when laying out
87e5dd7070Spatrick   // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
88e5dd7070Spatrick   UseBitFieldTypeAlignment = false;
89e5dd7070Spatrick 
90e5dd7070Spatrick   /// gcc forces the alignment to 4 bytes, regardless of the type of the
91e5dd7070Spatrick   /// zero length bitfield.  This corresponds to EMPTY_FIELD_BOUNDARY in
92e5dd7070Spatrick   /// gcc.
93e5dd7070Spatrick   ZeroLengthBitfieldBoundary = 32;
94e5dd7070Spatrick 
95e5dd7070Spatrick   if (T.isOSBinFormatMachO() && IsAAPCS16) {
96e5dd7070Spatrick     assert(!BigEndian && "AAPCS16 does not support big-endian");
97a9ac8606Spatrick     resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_");
98e5dd7070Spatrick   } else if (T.isOSBinFormatMachO())
99e5dd7070Spatrick     resetDataLayout(
100e5dd7070Spatrick         BigEndian
101e5dd7070Spatrick             ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
102a9ac8606Spatrick             : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32",
103a9ac8606Spatrick         "_");
104e5dd7070Spatrick   else
105e5dd7070Spatrick     resetDataLayout(
106e5dd7070Spatrick         BigEndian
107e5dd7070Spatrick             ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
108e5dd7070Spatrick             : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
109e5dd7070Spatrick 
110e5dd7070Spatrick   // FIXME: Override "preferred align" for double and long long.
111e5dd7070Spatrick }
112e5dd7070Spatrick 
setArchInfo()113e5dd7070Spatrick void ARMTargetInfo::setArchInfo() {
114e5dd7070Spatrick   StringRef ArchName = getTriple().getArchName();
115e5dd7070Spatrick 
116e5dd7070Spatrick   ArchISA = llvm::ARM::parseArchISA(ArchName);
117ec727ea7Spatrick   CPU = std::string(llvm::ARM::getDefaultCPU(ArchName));
118e5dd7070Spatrick   llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
119e5dd7070Spatrick   if (AK != llvm::ARM::ArchKind::INVALID)
120e5dd7070Spatrick     ArchKind = AK;
121e5dd7070Spatrick   setArchInfo(ArchKind);
122e5dd7070Spatrick }
123e5dd7070Spatrick 
setArchInfo(llvm::ARM::ArchKind Kind)124e5dd7070Spatrick void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
125e5dd7070Spatrick   StringRef SubArch;
126e5dd7070Spatrick 
127e5dd7070Spatrick   // cache TargetParser info
128e5dd7070Spatrick   ArchKind = Kind;
129e5dd7070Spatrick   SubArch = llvm::ARM::getSubArch(ArchKind);
130e5dd7070Spatrick   ArchProfile = llvm::ARM::parseArchProfile(SubArch);
131e5dd7070Spatrick   ArchVersion = llvm::ARM::parseArchVersion(SubArch);
132e5dd7070Spatrick 
133e5dd7070Spatrick   // cache CPU related strings
134e5dd7070Spatrick   CPUAttr = getCPUAttr();
135e5dd7070Spatrick   CPUProfile = getCPUProfile();
136e5dd7070Spatrick }
137e5dd7070Spatrick 
setAtomic()138e5dd7070Spatrick void ARMTargetInfo::setAtomic() {
139e5dd7070Spatrick   // when triple does not specify a sub arch,
140e5dd7070Spatrick   // then we are not using inline atomics
141e5dd7070Spatrick   bool ShouldUseInlineAtomic =
142e5dd7070Spatrick       (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
143e5dd7070Spatrick       (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
144e5dd7070Spatrick   // Cortex M does not support 8 byte atomics, while general Thumb2 does.
145e5dd7070Spatrick   if (ArchProfile == llvm::ARM::ProfileKind::M) {
146e5dd7070Spatrick     MaxAtomicPromoteWidth = 32;
147e5dd7070Spatrick     if (ShouldUseInlineAtomic)
148e5dd7070Spatrick       MaxAtomicInlineWidth = 32;
149e5dd7070Spatrick   } else {
150e5dd7070Spatrick     MaxAtomicPromoteWidth = 64;
151e5dd7070Spatrick     if (ShouldUseInlineAtomic)
152e5dd7070Spatrick       MaxAtomicInlineWidth = 64;
153e5dd7070Spatrick   }
154e5dd7070Spatrick }
155e5dd7070Spatrick 
hasMVE() const156e5dd7070Spatrick bool ARMTargetInfo::hasMVE() const {
157e5dd7070Spatrick   return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
158e5dd7070Spatrick }
159e5dd7070Spatrick 
hasMVEFloat() const160e5dd7070Spatrick bool ARMTargetInfo::hasMVEFloat() const {
161e5dd7070Spatrick   return hasMVE() && (MVE & MVE_FP);
162e5dd7070Spatrick }
163e5dd7070Spatrick 
hasCDE() const164ec727ea7Spatrick bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
165ec727ea7Spatrick 
isThumb() const166e5dd7070Spatrick bool ARMTargetInfo::isThumb() const {
167e5dd7070Spatrick   return ArchISA == llvm::ARM::ISAKind::THUMB;
168e5dd7070Spatrick }
169e5dd7070Spatrick 
supportsThumb() const170e5dd7070Spatrick bool ARMTargetInfo::supportsThumb() const {
171e5dd7070Spatrick   return CPUAttr.count('T') || ArchVersion >= 6;
172e5dd7070Spatrick }
173e5dd7070Spatrick 
supportsThumb2() const174e5dd7070Spatrick bool ARMTargetInfo::supportsThumb2() const {
175e5dd7070Spatrick   return CPUAttr.equals("6T2") ||
176e5dd7070Spatrick          (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
177e5dd7070Spatrick }
178e5dd7070Spatrick 
getCPUAttr() const179e5dd7070Spatrick StringRef ARMTargetInfo::getCPUAttr() const {
180e5dd7070Spatrick   // For most sub-arches, the build attribute CPU name is enough.
181e5dd7070Spatrick   // For Cortex variants, it's slightly different.
182e5dd7070Spatrick   switch (ArchKind) {
183e5dd7070Spatrick   default:
184e5dd7070Spatrick     return llvm::ARM::getCPUAttr(ArchKind);
185e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV6M:
186e5dd7070Spatrick     return "6M";
187e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV7S:
188e5dd7070Spatrick     return "7S";
189e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV7A:
190e5dd7070Spatrick     return "7A";
191e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV7R:
192e5dd7070Spatrick     return "7R";
193e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV7M:
194e5dd7070Spatrick     return "7M";
195e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV7EM:
196e5dd7070Spatrick     return "7EM";
197e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV7VE:
198e5dd7070Spatrick     return "7VE";
199e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8A:
200e5dd7070Spatrick     return "8A";
201e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_1A:
202e5dd7070Spatrick     return "8_1A";
203e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_2A:
204e5dd7070Spatrick     return "8_2A";
205e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_3A:
206e5dd7070Spatrick     return "8_3A";
207e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_4A:
208e5dd7070Spatrick     return "8_4A";
209e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_5A:
210e5dd7070Spatrick     return "8_5A";
211ec727ea7Spatrick   case llvm::ARM::ArchKind::ARMV8_6A:
212ec727ea7Spatrick     return "8_6A";
213a9ac8606Spatrick   case llvm::ARM::ArchKind::ARMV8_7A:
214a9ac8606Spatrick     return "8_7A";
215*12c85518Srobert   case llvm::ARM::ArchKind::ARMV8_8A:
216*12c85518Srobert     return "8_8A";
217*12c85518Srobert   case llvm::ARM::ArchKind::ARMV8_9A:
218*12c85518Srobert     return "8_9A";
219*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9A:
220*12c85518Srobert     return "9A";
221*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_1A:
222*12c85518Srobert     return "9_1A";
223*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_2A:
224*12c85518Srobert     return "9_2A";
225*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_3A:
226*12c85518Srobert     return "9_3A";
227*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_4A:
228*12c85518Srobert     return "9_4A";
229e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8MBaseline:
230e5dd7070Spatrick     return "8M_BASE";
231e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8MMainline:
232e5dd7070Spatrick     return "8M_MAIN";
233e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8R:
234e5dd7070Spatrick     return "8R";
235e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_1MMainline:
236e5dd7070Spatrick     return "8_1M_MAIN";
237e5dd7070Spatrick   }
238e5dd7070Spatrick }
239e5dd7070Spatrick 
getCPUProfile() const240e5dd7070Spatrick StringRef ARMTargetInfo::getCPUProfile() const {
241e5dd7070Spatrick   switch (ArchProfile) {
242e5dd7070Spatrick   case llvm::ARM::ProfileKind::A:
243e5dd7070Spatrick     return "A";
244e5dd7070Spatrick   case llvm::ARM::ProfileKind::R:
245e5dd7070Spatrick     return "R";
246e5dd7070Spatrick   case llvm::ARM::ProfileKind::M:
247e5dd7070Spatrick     return "M";
248e5dd7070Spatrick   default:
249e5dd7070Spatrick     return "";
250e5dd7070Spatrick   }
251e5dd7070Spatrick }
252e5dd7070Spatrick 
ARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)253e5dd7070Spatrick ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
254e5dd7070Spatrick                              const TargetOptions &Opts)
255e5dd7070Spatrick     : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
256e5dd7070Spatrick       HW_FP(0) {
257*12c85518Srobert   bool IsFreeBSD = Triple.isOSFreeBSD();
258e5dd7070Spatrick   bool IsOpenBSD = Triple.isOSOpenBSD();
259e5dd7070Spatrick   bool IsNetBSD = Triple.isOSNetBSD();
260e5dd7070Spatrick 
261e5dd7070Spatrick   // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
262e5dd7070Spatrick   // environment where size_t is `unsigned long` rather than `unsigned int`
263e5dd7070Spatrick 
264e5dd7070Spatrick   PtrDiffType = IntPtrType =
265e5dd7070Spatrick       (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
266e5dd7070Spatrick        IsNetBSD)
267e5dd7070Spatrick           ? SignedLong
268e5dd7070Spatrick           : SignedInt;
269e5dd7070Spatrick 
270e5dd7070Spatrick   SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
271e5dd7070Spatrick               IsNetBSD)
272e5dd7070Spatrick                  ? UnsignedLong
273e5dd7070Spatrick                  : UnsignedInt;
274e5dd7070Spatrick 
275e5dd7070Spatrick   // ptrdiff_t is inconsistent on Darwin
276e5dd7070Spatrick   if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
277e5dd7070Spatrick       !Triple.isWatchABI())
278e5dd7070Spatrick     PtrDiffType = SignedInt;
279e5dd7070Spatrick 
280e5dd7070Spatrick   // Cache arch related info.
281e5dd7070Spatrick   setArchInfo();
282e5dd7070Spatrick 
283e5dd7070Spatrick   // {} in inline assembly are neon specifiers, not assembly variant
284e5dd7070Spatrick   // specifiers.
285e5dd7070Spatrick   NoAsmVariants = true;
286e5dd7070Spatrick 
287e5dd7070Spatrick   // FIXME: This duplicates code from the driver that sets the -target-abi
288e5dd7070Spatrick   // option - this code is used if -target-abi isn't passed and should
289e5dd7070Spatrick   // be unified in some way.
290e5dd7070Spatrick   if (Triple.isOSBinFormatMachO()) {
291e5dd7070Spatrick     // The backend is hardwired to assume AAPCS for M-class processors, ensure
292e5dd7070Spatrick     // the frontend matches that.
293e5dd7070Spatrick     if (Triple.getEnvironment() == llvm::Triple::EABI ||
294e5dd7070Spatrick         Triple.getOS() == llvm::Triple::UnknownOS ||
295e5dd7070Spatrick         ArchProfile == llvm::ARM::ProfileKind::M) {
296e5dd7070Spatrick       setABI("aapcs");
297e5dd7070Spatrick     } else if (Triple.isWatchABI()) {
298e5dd7070Spatrick       setABI("aapcs16");
299e5dd7070Spatrick     } else {
300e5dd7070Spatrick       setABI("apcs-gnu");
301e5dd7070Spatrick     }
302e5dd7070Spatrick   } else if (Triple.isOSWindows()) {
303e5dd7070Spatrick     // FIXME: this is invalid for WindowsCE
304e5dd7070Spatrick     setABI("aapcs");
305e5dd7070Spatrick   } else {
306e5dd7070Spatrick     // Select the default based on the platform.
307e5dd7070Spatrick     switch (Triple.getEnvironment()) {
308e5dd7070Spatrick     case llvm::Triple::Android:
309e5dd7070Spatrick     case llvm::Triple::GNUEABI:
310e5dd7070Spatrick     case llvm::Triple::GNUEABIHF:
311e5dd7070Spatrick     case llvm::Triple::MuslEABI:
312e5dd7070Spatrick     case llvm::Triple::MuslEABIHF:
313e5dd7070Spatrick       setABI("aapcs-linux");
314e5dd7070Spatrick       break;
315e5dd7070Spatrick     case llvm::Triple::EABIHF:
316e5dd7070Spatrick     case llvm::Triple::EABI:
317e5dd7070Spatrick       setABI("aapcs");
318e5dd7070Spatrick       break;
319e5dd7070Spatrick     case llvm::Triple::GNU:
320e5dd7070Spatrick       setABI("apcs-gnu");
321e5dd7070Spatrick       break;
322e5dd7070Spatrick     default:
323e5dd7070Spatrick       if (IsNetBSD)
324e5dd7070Spatrick         setABI("apcs-gnu");
325*12c85518Srobert       else if (IsFreeBSD || IsOpenBSD)
326e5dd7070Spatrick         setABI("aapcs-linux");
327e5dd7070Spatrick       else
328e5dd7070Spatrick         setABI("aapcs");
329e5dd7070Spatrick       break;
330e5dd7070Spatrick     }
331e5dd7070Spatrick   }
332e5dd7070Spatrick 
333e5dd7070Spatrick   // ARM targets default to using the ARM C++ ABI.
334e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::GenericARM);
335e5dd7070Spatrick 
336e5dd7070Spatrick   // ARM has atomics up to 8 bytes
337e5dd7070Spatrick   setAtomic();
338e5dd7070Spatrick 
339e5dd7070Spatrick   // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
340e5dd7070Spatrick   // as well the default alignment
341ec727ea7Spatrick   if (IsAAPCS && !Triple.isAndroid())
342e5dd7070Spatrick     DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
343e5dd7070Spatrick 
344e5dd7070Spatrick   // Do force alignment of members that follow zero length bitfields.  If
345e5dd7070Spatrick   // the alignment of the zero-length bitfield is greater than the member
346e5dd7070Spatrick   // that follows it, `bar', `bar' will be aligned as the  type of the
347e5dd7070Spatrick   // zero length bitfield.
348e5dd7070Spatrick   UseZeroLengthBitfieldAlignment = true;
349e5dd7070Spatrick 
350e5dd7070Spatrick   if (Triple.getOS() == llvm::Triple::Linux ||
351e5dd7070Spatrick       Triple.getOS() == llvm::Triple::UnknownOS)
352e5dd7070Spatrick     this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
353e5dd7070Spatrick                            ? "llvm.arm.gnu.eabi.mcount"
354e5dd7070Spatrick                            : "\01mcount";
355e5dd7070Spatrick 
356e5dd7070Spatrick   SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
357e5dd7070Spatrick }
358e5dd7070Spatrick 
getABI() const359e5dd7070Spatrick StringRef ARMTargetInfo::getABI() const { return ABI; }
360e5dd7070Spatrick 
setABI(const std::string & Name)361e5dd7070Spatrick bool ARMTargetInfo::setABI(const std::string &Name) {
362e5dd7070Spatrick   ABI = Name;
363e5dd7070Spatrick 
364e5dd7070Spatrick   // The defaults (above) are for AAPCS, check if we need to change them.
365e5dd7070Spatrick   //
366e5dd7070Spatrick   // FIXME: We need support for -meabi... we could just mangle it into the
367e5dd7070Spatrick   // name.
368e5dd7070Spatrick   if (Name == "apcs-gnu" || Name == "aapcs16") {
369e5dd7070Spatrick     setABIAPCS(Name == "aapcs16");
370e5dd7070Spatrick     return true;
371e5dd7070Spatrick   }
372e5dd7070Spatrick   if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
373e5dd7070Spatrick     setABIAAPCS();
374e5dd7070Spatrick     return true;
375e5dd7070Spatrick   }
376e5dd7070Spatrick   return false;
377e5dd7070Spatrick }
378e5dd7070Spatrick 
isBranchProtectionSupportedArch(StringRef Arch) const379*12c85518Srobert bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const {
380*12c85518Srobert   llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch);
381*12c85518Srobert   if (CPUArch == llvm::ARM::ArchKind::INVALID)
382*12c85518Srobert     CPUArch = llvm::ARM::parseArch(getTriple().getArchName());
383*12c85518Srobert 
384*12c85518Srobert   if (CPUArch == llvm::ARM::ArchKind::INVALID)
385*12c85518Srobert     return false;
386*12c85518Srobert 
387*12c85518Srobert   StringRef ArchFeature = llvm::ARM::getArchName(CPUArch);
388*12c85518Srobert   auto a =
389*12c85518Srobert       llvm::Triple(ArchFeature, getTriple().getVendorName(),
390*12c85518Srobert                    getTriple().getOSName(), getTriple().getEnvironmentName());
391*12c85518Srobert 
392*12c85518Srobert   StringRef SubArch = llvm::ARM::getSubArch(CPUArch);
393*12c85518Srobert   llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch);
394*12c85518Srobert   return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M);
395*12c85518Srobert }
396*12c85518Srobert 
validateBranchProtection(StringRef Spec,StringRef Arch,BranchProtectionInfo & BPI,StringRef & Err) const397*12c85518Srobert bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch,
398*12c85518Srobert                                              BranchProtectionInfo &BPI,
399*12c85518Srobert                                              StringRef &Err) const {
400*12c85518Srobert   llvm::ARM::ParsedBranchProtection PBP;
401*12c85518Srobert   if (!llvm::ARM::parseBranchProtection(Spec, PBP, Err))
402*12c85518Srobert     return false;
403*12c85518Srobert 
404*12c85518Srobert   if (!isBranchProtectionSupportedArch(Arch))
405*12c85518Srobert     return false;
406*12c85518Srobert 
407*12c85518Srobert   BPI.SignReturnAddr =
408*12c85518Srobert       llvm::StringSwitch<LangOptions::SignReturnAddressScopeKind>(PBP.Scope)
409*12c85518Srobert           .Case("non-leaf", LangOptions::SignReturnAddressScopeKind::NonLeaf)
410*12c85518Srobert           .Case("all", LangOptions::SignReturnAddressScopeKind::All)
411*12c85518Srobert           .Default(LangOptions::SignReturnAddressScopeKind::None);
412*12c85518Srobert 
413*12c85518Srobert   // Don't care for the sign key, beyond issuing a warning.
414*12c85518Srobert   if (PBP.Key == "b_key")
415*12c85518Srobert     Err = "b-key";
416*12c85518Srobert   BPI.SignKey = LangOptions::SignReturnAddressKeyKind::AKey;
417*12c85518Srobert 
418*12c85518Srobert   BPI.BranchTargetEnforcement = PBP.BranchTargetEnforcement;
419*12c85518Srobert   return true;
420*12c85518Srobert }
421*12c85518Srobert 
422e5dd7070Spatrick // FIXME: This should be based on Arch attributes, not CPU names.
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const423e5dd7070Spatrick bool ARMTargetInfo::initFeatureMap(
424e5dd7070Spatrick     llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
425e5dd7070Spatrick     const std::vector<std::string> &FeaturesVec) const {
426e5dd7070Spatrick 
427e5dd7070Spatrick   std::string ArchFeature;
428e5dd7070Spatrick   std::vector<StringRef> TargetFeatures;
429e5dd7070Spatrick   llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
430e5dd7070Spatrick 
431e5dd7070Spatrick   // Map the base architecture to an appropriate target feature, so we don't
432e5dd7070Spatrick   // rely on the target triple.
433e5dd7070Spatrick   llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
434e5dd7070Spatrick   if (CPUArch == llvm::ARM::ArchKind::INVALID)
435e5dd7070Spatrick     CPUArch = Arch;
436e5dd7070Spatrick   if (CPUArch != llvm::ARM::ArchKind::INVALID) {
437e5dd7070Spatrick     ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
438e5dd7070Spatrick     TargetFeatures.push_back(ArchFeature);
439*12c85518Srobert 
440*12c85518Srobert     // These features are added to allow arm_neon.h target(..) attributes to
441*12c85518Srobert     // match with both arm and aarch64. We need to add all previous architecture
442*12c85518Srobert     // versions, so that "8.6" also allows "8.1" functions. In case of v9.x the
443*12c85518Srobert     // v8.x counterparts are added too. We only need these for anything > 8.0-A.
444*12c85518Srobert     for (llvm::ARM::ArchKind I = llvm::ARM::convertV9toV8(CPUArch);
445*12c85518Srobert          I != llvm::ARM::ArchKind::INVALID; --I)
446*12c85518Srobert       Features[llvm::ARM::getSubArch(I)] = true;
447*12c85518Srobert     if (CPUArch > llvm::ARM::ArchKind::ARMV8A &&
448*12c85518Srobert         CPUArch <= llvm::ARM::ArchKind::ARMV9_3A)
449*12c85518Srobert       for (llvm::ARM::ArchKind I = CPUArch; I != llvm::ARM::ArchKind::INVALID;
450*12c85518Srobert            --I)
451*12c85518Srobert         Features[llvm::ARM::getSubArch(I)] = true;
452e5dd7070Spatrick   }
453e5dd7070Spatrick 
454e5dd7070Spatrick   // get default FPU features
455e5dd7070Spatrick   unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
456e5dd7070Spatrick   llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
457e5dd7070Spatrick 
458e5dd7070Spatrick   // get default Extension features
459ec727ea7Spatrick   uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
460e5dd7070Spatrick   llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
461e5dd7070Spatrick 
462e5dd7070Spatrick   for (auto Feature : TargetFeatures)
463e5dd7070Spatrick     if (Feature[0] == '+')
464e5dd7070Spatrick       Features[Feature.drop_front(1)] = true;
465e5dd7070Spatrick 
466e5dd7070Spatrick   // Enable or disable thumb-mode explicitly per function to enable mixed
467e5dd7070Spatrick   // ARM and Thumb code generation.
468e5dd7070Spatrick   if (isThumb())
469e5dd7070Spatrick     Features["thumb-mode"] = true;
470e5dd7070Spatrick   else
471e5dd7070Spatrick     Features["thumb-mode"] = false;
472e5dd7070Spatrick 
473e5dd7070Spatrick   // Convert user-provided arm and thumb GNU target attributes to
474e5dd7070Spatrick   // [-|+]thumb-mode target features respectively.
475e5dd7070Spatrick   std::vector<std::string> UpdatedFeaturesVec;
476e5dd7070Spatrick   for (const auto &Feature : FeaturesVec) {
477e5dd7070Spatrick     // Skip soft-float-abi; it's something we only use to initialize a bit of
478e5dd7070Spatrick     // class state, and is otherwise unrecognized.
479e5dd7070Spatrick     if (Feature == "+soft-float-abi")
480e5dd7070Spatrick       continue;
481e5dd7070Spatrick 
482e5dd7070Spatrick     StringRef FixedFeature;
483e5dd7070Spatrick     if (Feature == "+arm")
484e5dd7070Spatrick       FixedFeature = "-thumb-mode";
485e5dd7070Spatrick     else if (Feature == "+thumb")
486e5dd7070Spatrick       FixedFeature = "+thumb-mode";
487e5dd7070Spatrick     else
488e5dd7070Spatrick       FixedFeature = Feature;
489e5dd7070Spatrick     UpdatedFeaturesVec.push_back(FixedFeature.str());
490e5dd7070Spatrick   }
491e5dd7070Spatrick 
492e5dd7070Spatrick   return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
493e5dd7070Spatrick }
494e5dd7070Spatrick 
495e5dd7070Spatrick 
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)496e5dd7070Spatrick bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
497e5dd7070Spatrick                                          DiagnosticsEngine &Diags) {
498e5dd7070Spatrick   FPU = 0;
499e5dd7070Spatrick   MVE = 0;
500e5dd7070Spatrick   CRC = 0;
501e5dd7070Spatrick   Crypto = 0;
502a9ac8606Spatrick   SHA2 = 0;
503a9ac8606Spatrick   AES = 0;
504e5dd7070Spatrick   DSP = 0;
505e5dd7070Spatrick   Unaligned = 1;
506e5dd7070Spatrick   SoftFloat = false;
507e5dd7070Spatrick   // Note that SoftFloatABI is initialized in our constructor.
508e5dd7070Spatrick   HWDiv = 0;
509e5dd7070Spatrick   DotProd = 0;
510ec727ea7Spatrick   HasMatMul = 0;
511*12c85518Srobert   HasPAC = 0;
512*12c85518Srobert   HasBTI = 0;
513e5dd7070Spatrick   HasFloat16 = true;
514ec727ea7Spatrick   ARMCDECoprocMask = 0;
515ec727ea7Spatrick   HasBFloat16 = false;
516*12c85518Srobert   FPRegsDisabled = false;
517e5dd7070Spatrick 
518e5dd7070Spatrick   // This does not diagnose illegal cases like having both
519e5dd7070Spatrick   // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
520e5dd7070Spatrick   for (const auto &Feature : Features) {
521e5dd7070Spatrick     if (Feature == "+soft-float") {
522e5dd7070Spatrick       SoftFloat = true;
523e5dd7070Spatrick     } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
524e5dd7070Spatrick       FPU |= VFP2FPU;
525e5dd7070Spatrick       HW_FP |= HW_FP_SP;
526e5dd7070Spatrick       if (Feature == "+vfp2")
527e5dd7070Spatrick           HW_FP |= HW_FP_DP;
528e5dd7070Spatrick     } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
529e5dd7070Spatrick                Feature == "+vfp3" || Feature == "+vfp3d16") {
530e5dd7070Spatrick       FPU |= VFP3FPU;
531e5dd7070Spatrick       HW_FP |= HW_FP_SP;
532e5dd7070Spatrick       if (Feature == "+vfp3" || Feature == "+vfp3d16")
533e5dd7070Spatrick           HW_FP |= HW_FP_DP;
534e5dd7070Spatrick     } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
535e5dd7070Spatrick                Feature == "+vfp4" || Feature == "+vfp4d16") {
536e5dd7070Spatrick       FPU |= VFP4FPU;
537e5dd7070Spatrick       HW_FP |= HW_FP_SP | HW_FP_HP;
538e5dd7070Spatrick       if (Feature == "+vfp4" || Feature == "+vfp4d16")
539e5dd7070Spatrick           HW_FP |= HW_FP_DP;
540e5dd7070Spatrick     } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
541e5dd7070Spatrick                Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
542e5dd7070Spatrick       FPU |= FPARMV8;
543e5dd7070Spatrick       HW_FP |= HW_FP_SP | HW_FP_HP;
544e5dd7070Spatrick       if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
545e5dd7070Spatrick           HW_FP |= HW_FP_DP;
546e5dd7070Spatrick     } else if (Feature == "+neon") {
547e5dd7070Spatrick       FPU |= NeonFPU;
548e5dd7070Spatrick       HW_FP |= HW_FP_SP;
549e5dd7070Spatrick     } else if (Feature == "+hwdiv") {
550e5dd7070Spatrick       HWDiv |= HWDivThumb;
551e5dd7070Spatrick     } else if (Feature == "+hwdiv-arm") {
552e5dd7070Spatrick       HWDiv |= HWDivARM;
553e5dd7070Spatrick     } else if (Feature == "+crc") {
554e5dd7070Spatrick       CRC = 1;
555e5dd7070Spatrick     } else if (Feature == "+crypto") {
556e5dd7070Spatrick       Crypto = 1;
557a9ac8606Spatrick     } else if (Feature == "+sha2") {
558a9ac8606Spatrick       SHA2 = 1;
559a9ac8606Spatrick     } else if (Feature == "+aes") {
560a9ac8606Spatrick       AES = 1;
561e5dd7070Spatrick     } else if (Feature == "+dsp") {
562e5dd7070Spatrick       DSP = 1;
563e5dd7070Spatrick     } else if (Feature == "+fp64") {
564e5dd7070Spatrick       HW_FP |= HW_FP_DP;
565e5dd7070Spatrick     } else if (Feature == "+8msecext") {
566e5dd7070Spatrick       if (CPUProfile != "M" || ArchVersion != 8) {
567e5dd7070Spatrick         Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
568e5dd7070Spatrick         return false;
569e5dd7070Spatrick       }
570e5dd7070Spatrick     } else if (Feature == "+strict-align") {
571e5dd7070Spatrick       Unaligned = 0;
572e5dd7070Spatrick     } else if (Feature == "+fp16") {
573e5dd7070Spatrick       HW_FP |= HW_FP_HP;
574e5dd7070Spatrick     } else if (Feature == "+fullfp16") {
575e5dd7070Spatrick       HasLegalHalfType = true;
576e5dd7070Spatrick     } else if (Feature == "+dotprod") {
577e5dd7070Spatrick       DotProd = true;
578e5dd7070Spatrick     } else if (Feature == "+mve") {
579e5dd7070Spatrick       MVE |= MVE_INT;
580e5dd7070Spatrick     } else if (Feature == "+mve.fp") {
581e5dd7070Spatrick       HasLegalHalfType = true;
582e5dd7070Spatrick       FPU |= FPARMV8;
583e5dd7070Spatrick       MVE |= MVE_INT | MVE_FP;
584e5dd7070Spatrick       HW_FP |= HW_FP_SP | HW_FP_HP;
585ec727ea7Spatrick     } else if (Feature == "+i8mm") {
586ec727ea7Spatrick       HasMatMul = 1;
587ec727ea7Spatrick     } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
588ec727ea7Spatrick                Feature <= "+cdecp7") {
589ec727ea7Spatrick       unsigned Coproc = Feature.back() - '0';
590ec727ea7Spatrick       ARMCDECoprocMask |= (1U << Coproc);
591ec727ea7Spatrick     } else if (Feature == "+bf16") {
592ec727ea7Spatrick       HasBFloat16 = true;
593*12c85518Srobert     } else if (Feature == "-fpregs") {
594*12c85518Srobert       FPRegsDisabled = true;
595*12c85518Srobert     } else if (Feature == "+pacbti") {
596*12c85518Srobert       HasPAC = 1;
597*12c85518Srobert       HasBTI = 1;
598e5dd7070Spatrick     }
599e5dd7070Spatrick   }
600e5dd7070Spatrick 
601*12c85518Srobert   HalfArgsAndReturns = true;
602*12c85518Srobert 
603e5dd7070Spatrick   switch (ArchVersion) {
604e5dd7070Spatrick   case 6:
605e5dd7070Spatrick     if (ArchProfile == llvm::ARM::ProfileKind::M)
606e5dd7070Spatrick       LDREX = 0;
607e5dd7070Spatrick     else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
608e5dd7070Spatrick       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
609e5dd7070Spatrick     else
610e5dd7070Spatrick       LDREX = LDREX_W;
611e5dd7070Spatrick     break;
612e5dd7070Spatrick   case 7:
613e5dd7070Spatrick     if (ArchProfile == llvm::ARM::ProfileKind::M)
614e5dd7070Spatrick       LDREX = LDREX_W | LDREX_H | LDREX_B;
615e5dd7070Spatrick     else
616e5dd7070Spatrick       LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
617e5dd7070Spatrick     break;
618e5dd7070Spatrick   case 8:
619*12c85518Srobert   case 9:
620e5dd7070Spatrick     LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
621e5dd7070Spatrick   }
622e5dd7070Spatrick 
623e5dd7070Spatrick   if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
624e5dd7070Spatrick     Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
625e5dd7070Spatrick     return false;
626e5dd7070Spatrick   }
627e5dd7070Spatrick 
628e5dd7070Spatrick   if (FPMath == FP_Neon)
629e5dd7070Spatrick     Features.push_back("+neonfp");
630e5dd7070Spatrick   else if (FPMath == FP_VFP)
631e5dd7070Spatrick     Features.push_back("-neonfp");
632e5dd7070Spatrick 
633e5dd7070Spatrick   return true;
634e5dd7070Spatrick }
635e5dd7070Spatrick 
hasFeature(StringRef Feature) const636e5dd7070Spatrick bool ARMTargetInfo::hasFeature(StringRef Feature) const {
637e5dd7070Spatrick   return llvm::StringSwitch<bool>(Feature)
638e5dd7070Spatrick       .Case("arm", true)
639e5dd7070Spatrick       .Case("aarch32", true)
640e5dd7070Spatrick       .Case("softfloat", SoftFloat)
641e5dd7070Spatrick       .Case("thumb", isThumb())
642e5dd7070Spatrick       .Case("neon", (FPU & NeonFPU) && !SoftFloat)
643e5dd7070Spatrick       .Case("vfp", FPU && !SoftFloat)
644e5dd7070Spatrick       .Case("hwdiv", HWDiv & HWDivThumb)
645e5dd7070Spatrick       .Case("hwdiv-arm", HWDiv & HWDivARM)
646e5dd7070Spatrick       .Case("mve", hasMVE())
647e5dd7070Spatrick       .Default(false);
648e5dd7070Spatrick }
649e5dd7070Spatrick 
hasBFloat16Type() const650ec727ea7Spatrick bool ARMTargetInfo::hasBFloat16Type() const {
651*12c85518Srobert   // The __bf16 type is generally available so long as we have any fp registers.
652*12c85518Srobert   return HasBFloat16 || (FPU && !SoftFloat);
653ec727ea7Spatrick }
654ec727ea7Spatrick 
isValidCPUName(StringRef Name) const655e5dd7070Spatrick bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
656e5dd7070Spatrick   return Name == "generic" ||
657e5dd7070Spatrick          llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
658e5dd7070Spatrick }
659e5dd7070Spatrick 
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const660e5dd7070Spatrick void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
661e5dd7070Spatrick   llvm::ARM::fillValidCPUArchList(Values);
662e5dd7070Spatrick }
663e5dd7070Spatrick 
setCPU(const std::string & Name)664e5dd7070Spatrick bool ARMTargetInfo::setCPU(const std::string &Name) {
665e5dd7070Spatrick   if (Name != "generic")
666e5dd7070Spatrick     setArchInfo(llvm::ARM::parseCPUArch(Name));
667e5dd7070Spatrick 
668e5dd7070Spatrick   if (ArchKind == llvm::ARM::ArchKind::INVALID)
669e5dd7070Spatrick     return false;
670e5dd7070Spatrick   setAtomic();
671e5dd7070Spatrick   CPU = Name;
672e5dd7070Spatrick   return true;
673e5dd7070Spatrick }
674e5dd7070Spatrick 
setFPMath(StringRef Name)675e5dd7070Spatrick bool ARMTargetInfo::setFPMath(StringRef Name) {
676e5dd7070Spatrick   if (Name == "neon") {
677e5dd7070Spatrick     FPMath = FP_Neon;
678e5dd7070Spatrick     return true;
679e5dd7070Spatrick   } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
680e5dd7070Spatrick              Name == "vfp4") {
681e5dd7070Spatrick     FPMath = FP_VFP;
682e5dd7070Spatrick     return true;
683e5dd7070Spatrick   }
684e5dd7070Spatrick   return false;
685e5dd7070Spatrick }
686e5dd7070Spatrick 
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const687e5dd7070Spatrick void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
688e5dd7070Spatrick                                             MacroBuilder &Builder) const {
689e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
690e5dd7070Spatrick }
691e5dd7070Spatrick 
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const692e5dd7070Spatrick void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
693e5dd7070Spatrick                                             MacroBuilder &Builder) const {
694e5dd7070Spatrick   // Also include the ARMv8.1-A defines
695e5dd7070Spatrick   getTargetDefinesARMV81A(Opts, Builder);
696e5dd7070Spatrick }
697e5dd7070Spatrick 
getTargetDefinesARMV83A(const LangOptions & Opts,MacroBuilder & Builder) const698e5dd7070Spatrick void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
699e5dd7070Spatrick                                             MacroBuilder &Builder) const {
700e5dd7070Spatrick   // Also include the ARMv8.2-A defines
701e5dd7070Spatrick   Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
702e5dd7070Spatrick   getTargetDefinesARMV82A(Opts, Builder);
703e5dd7070Spatrick }
704e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const705e5dd7070Spatrick void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
706e5dd7070Spatrick                                      MacroBuilder &Builder) const {
707e5dd7070Spatrick   // Target identification.
708e5dd7070Spatrick   Builder.defineMacro("__arm");
709e5dd7070Spatrick   Builder.defineMacro("__arm__");
710e5dd7070Spatrick   // For bare-metal none-eabi.
711e5dd7070Spatrick   if (getTriple().getOS() == llvm::Triple::UnknownOS &&
712e5dd7070Spatrick       (getTriple().getEnvironment() == llvm::Triple::EABI ||
713*12c85518Srobert        getTriple().getEnvironment() == llvm::Triple::EABIHF)) {
714e5dd7070Spatrick     Builder.defineMacro("__ELF__");
715*12c85518Srobert     if (Opts.CPlusPlus)
716*12c85518Srobert       Builder.defineMacro("_GNU_SOURCE");
717*12c85518Srobert   }
718e5dd7070Spatrick 
719e5dd7070Spatrick   // Target properties.
720e5dd7070Spatrick   Builder.defineMacro("__REGISTER_PREFIX__", "");
721e5dd7070Spatrick 
722e5dd7070Spatrick   // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
723e5dd7070Spatrick   // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
724e5dd7070Spatrick   if (getTriple().isWatchABI())
725e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_7K__", "2");
726e5dd7070Spatrick 
727e5dd7070Spatrick   if (!CPUAttr.empty())
728e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
729e5dd7070Spatrick 
730e5dd7070Spatrick   // ACLE 6.4.1 ARM/Thumb instruction set architecture
731e5dd7070Spatrick   // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
732e5dd7070Spatrick   Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
733e5dd7070Spatrick 
734e5dd7070Spatrick   if (ArchVersion >= 8) {
735e5dd7070Spatrick     // ACLE 6.5.7 Crypto Extension
736a9ac8606Spatrick     // The __ARM_FEATURE_CRYPTO is deprecated in favor of finer grained
737a9ac8606Spatrick     // feature macros for AES and SHA2
738a9ac8606Spatrick     if (SHA2 && AES)
739e5dd7070Spatrick       Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
740a9ac8606Spatrick     if (SHA2)
741a9ac8606Spatrick       Builder.defineMacro("__ARM_FEATURE_SHA2", "1");
742a9ac8606Spatrick     if (AES)
743a9ac8606Spatrick       Builder.defineMacro("__ARM_FEATURE_AES", "1");
744e5dd7070Spatrick     // ACLE 6.5.8 CRC32 Extension
745e5dd7070Spatrick     if (CRC)
746e5dd7070Spatrick       Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
747e5dd7070Spatrick     // ACLE 6.5.10 Numeric Maximum and Minimum
748e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
749e5dd7070Spatrick     // ACLE 6.5.9 Directed Rounding
750e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
751e5dd7070Spatrick   }
752e5dd7070Spatrick 
753e5dd7070Spatrick   // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA.  It
754e5dd7070Spatrick   // is not defined for the M-profile.
755e5dd7070Spatrick   // NOTE that the default profile is assumed to be 'A'
756e5dd7070Spatrick   if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
757e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
758e5dd7070Spatrick 
759e5dd7070Spatrick   // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
760e5dd7070Spatrick   // Thumb ISA (including v6-M and v8-M Baseline).  It is set to 2 if the
761e5dd7070Spatrick   // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
762e5dd7070Spatrick   // v7 and v8 architectures excluding v8-M Baseline.
763e5dd7070Spatrick   if (supportsThumb2())
764e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
765e5dd7070Spatrick   else if (supportsThumb())
766e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
767e5dd7070Spatrick 
768e5dd7070Spatrick   // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
769e5dd7070Spatrick   // instruction set such as ARM or Thumb.
770e5dd7070Spatrick   Builder.defineMacro("__ARM_32BIT_STATE", "1");
771e5dd7070Spatrick 
772e5dd7070Spatrick   // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
773e5dd7070Spatrick 
774e5dd7070Spatrick   // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
775e5dd7070Spatrick   if (!CPUProfile.empty())
776e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
777e5dd7070Spatrick 
778e5dd7070Spatrick   // ACLE 6.4.3 Unaligned access supported in hardware
779e5dd7070Spatrick   if (Unaligned)
780e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
781e5dd7070Spatrick 
782e5dd7070Spatrick   // ACLE 6.4.4 LDREX/STREX
783e5dd7070Spatrick   if (LDREX)
784e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
785e5dd7070Spatrick 
786e5dd7070Spatrick   // ACLE 6.4.5 CLZ
787e5dd7070Spatrick   if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
788e5dd7070Spatrick       ArchVersion > 6)
789e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
790e5dd7070Spatrick 
791e5dd7070Spatrick   // ACLE 6.5.1 Hardware Floating Point
792e5dd7070Spatrick   if (HW_FP)
793e5dd7070Spatrick     Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
794e5dd7070Spatrick 
795e5dd7070Spatrick   // ACLE predefines.
796e5dd7070Spatrick   Builder.defineMacro("__ARM_ACLE", "200");
797e5dd7070Spatrick 
798e5dd7070Spatrick   // FP16 support (we currently only support IEEE format).
799e5dd7070Spatrick   Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
800e5dd7070Spatrick   Builder.defineMacro("__ARM_FP16_ARGS", "1");
801e5dd7070Spatrick 
802e5dd7070Spatrick   // ACLE 6.5.3 Fused multiply-accumulate (FMA)
803e5dd7070Spatrick   if (ArchVersion >= 7 && (FPU & VFP4FPU))
804e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_FMA", "1");
805e5dd7070Spatrick 
806e5dd7070Spatrick   // Subtarget options.
807e5dd7070Spatrick 
808e5dd7070Spatrick   // FIXME: It's more complicated than this and we don't really support
809e5dd7070Spatrick   // interworking.
810e5dd7070Spatrick   // Windows on ARM does not "support" interworking
811e5dd7070Spatrick   if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
812e5dd7070Spatrick     Builder.defineMacro("__THUMB_INTERWORK__");
813e5dd7070Spatrick 
814e5dd7070Spatrick   if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
815e5dd7070Spatrick     // Embedded targets on Darwin follow AAPCS, but not EABI.
816e5dd7070Spatrick     // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
817e5dd7070Spatrick     if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
818e5dd7070Spatrick       Builder.defineMacro("__ARM_EABI__");
819e5dd7070Spatrick     Builder.defineMacro("__ARM_PCS", "1");
820e5dd7070Spatrick   }
821e5dd7070Spatrick 
822e5dd7070Spatrick   if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
823e5dd7070Spatrick     Builder.defineMacro("__ARM_PCS_VFP", "1");
824e5dd7070Spatrick 
825*12c85518Srobert   if (SoftFloat || (SoftFloatABI && !FPU))
826e5dd7070Spatrick     Builder.defineMacro("__SOFTFP__");
827e5dd7070Spatrick 
828e5dd7070Spatrick   // ACLE position independent code macros.
829e5dd7070Spatrick   if (Opts.ROPI)
830e5dd7070Spatrick     Builder.defineMacro("__ARM_ROPI", "1");
831e5dd7070Spatrick   if (Opts.RWPI)
832e5dd7070Spatrick     Builder.defineMacro("__ARM_RWPI", "1");
833e5dd7070Spatrick 
834e5dd7070Spatrick   if (ArchKind == llvm::ARM::ArchKind::XSCALE)
835e5dd7070Spatrick     Builder.defineMacro("__XSCALE__");
836e5dd7070Spatrick 
837e5dd7070Spatrick   if (isThumb()) {
838e5dd7070Spatrick     Builder.defineMacro("__THUMBEL__");
839e5dd7070Spatrick     Builder.defineMacro("__thumb__");
840e5dd7070Spatrick     if (supportsThumb2())
841e5dd7070Spatrick       Builder.defineMacro("__thumb2__");
842e5dd7070Spatrick   }
843e5dd7070Spatrick 
844e5dd7070Spatrick   // ACLE 6.4.9 32-bit SIMD instructions
845e5dd7070Spatrick   if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
846e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
847e5dd7070Spatrick 
848e5dd7070Spatrick   // ACLE 6.4.10 Hardware Integer Divide
849e5dd7070Spatrick   if (((HWDiv & HWDivThumb) && isThumb()) ||
850e5dd7070Spatrick       ((HWDiv & HWDivARM) && !isThumb())) {
851e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
852e5dd7070Spatrick     Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
853e5dd7070Spatrick   }
854e5dd7070Spatrick 
855e5dd7070Spatrick   // Note, this is always on in gcc, even though it doesn't make sense.
856e5dd7070Spatrick   Builder.defineMacro("__APCS_32__");
857e5dd7070Spatrick 
858a9ac8606Spatrick   // __VFP_FP__ means that the floating-point format is VFP, not that a hardware
859a9ac8606Spatrick   // FPU is present. Moreover, the VFP format is the only one supported by
860a9ac8606Spatrick   // clang. For these reasons, this macro is always defined.
861e5dd7070Spatrick   Builder.defineMacro("__VFP_FP__");
862a9ac8606Spatrick 
863a9ac8606Spatrick   if (FPUModeIsVFP((FPUMode)FPU)) {
864e5dd7070Spatrick     if (FPU & VFP2FPU)
865e5dd7070Spatrick       Builder.defineMacro("__ARM_VFPV2__");
866e5dd7070Spatrick     if (FPU & VFP3FPU)
867e5dd7070Spatrick       Builder.defineMacro("__ARM_VFPV3__");
868e5dd7070Spatrick     if (FPU & VFP4FPU)
869e5dd7070Spatrick       Builder.defineMacro("__ARM_VFPV4__");
870e5dd7070Spatrick     if (FPU & FPARMV8)
871e5dd7070Spatrick       Builder.defineMacro("__ARM_FPV5__");
872e5dd7070Spatrick   }
873e5dd7070Spatrick 
874e5dd7070Spatrick   // This only gets set when Neon instructions are actually available, unlike
875e5dd7070Spatrick   // the VFP define, hence the soft float and arch check. This is subtly
876e5dd7070Spatrick   // different from gcc, we follow the intent which was that it should be set
877e5dd7070Spatrick   // when Neon instructions are actually available.
878e5dd7070Spatrick   if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
879e5dd7070Spatrick     Builder.defineMacro("__ARM_NEON", "1");
880e5dd7070Spatrick     Builder.defineMacro("__ARM_NEON__");
881e5dd7070Spatrick     // current AArch32 NEON implementations do not support double-precision
882e5dd7070Spatrick     // floating-point even when it is present in VFP.
883e5dd7070Spatrick     Builder.defineMacro("__ARM_NEON_FP",
884e5dd7070Spatrick                         "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
885e5dd7070Spatrick   }
886e5dd7070Spatrick 
887e5dd7070Spatrick   if (hasMVE()) {
888e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
889e5dd7070Spatrick   }
890e5dd7070Spatrick 
891ec727ea7Spatrick   if (hasCDE()) {
892ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_CDE", "1");
893ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
894ec727ea7Spatrick                         "0x" + Twine::utohexstr(getARMCDECoprocMask()));
895ec727ea7Spatrick   }
896ec727ea7Spatrick 
897e5dd7070Spatrick   Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
898e5dd7070Spatrick                       Twine(Opts.WCharSize ? Opts.WCharSize : 4));
899e5dd7070Spatrick 
900e5dd7070Spatrick   Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
901e5dd7070Spatrick 
902e5dd7070Spatrick   // CMSE
903e5dd7070Spatrick   if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
904e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
905e5dd7070Spatrick 
906e5dd7070Spatrick   if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
907e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
908e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
909e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
910e5dd7070Spatrick     Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
911e5dd7070Spatrick   }
912e5dd7070Spatrick 
913e5dd7070Spatrick   // ACLE 6.4.7 DSP instructions
914e5dd7070Spatrick   if (DSP) {
915e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_DSP", "1");
916e5dd7070Spatrick   }
917e5dd7070Spatrick 
918e5dd7070Spatrick   // ACLE 6.4.8 Saturation instructions
919e5dd7070Spatrick   bool SAT = false;
920e5dd7070Spatrick   if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
921e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_SAT", "1");
922e5dd7070Spatrick     SAT = true;
923e5dd7070Spatrick   }
924e5dd7070Spatrick 
925e5dd7070Spatrick   // ACLE 6.4.6 Q (saturation) flag
926e5dd7070Spatrick   if (DSP || SAT)
927e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
928e5dd7070Spatrick 
929e5dd7070Spatrick   if (Opts.UnsafeFPMath)
930e5dd7070Spatrick     Builder.defineMacro("__ARM_FP_FAST", "1");
931e5dd7070Spatrick 
932e5dd7070Spatrick   // Armv8.2-A FP16 vector intrinsic
933e5dd7070Spatrick   if ((FPU & NeonFPU) && HasLegalHalfType)
934e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
935e5dd7070Spatrick 
936e5dd7070Spatrick   // Armv8.2-A FP16 scalar intrinsics
937e5dd7070Spatrick   if (HasLegalHalfType)
938e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
939e5dd7070Spatrick 
940e5dd7070Spatrick   // Armv8.2-A dot product intrinsics
941e5dd7070Spatrick   if (DotProd)
942e5dd7070Spatrick     Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
943e5dd7070Spatrick 
944ec727ea7Spatrick   if (HasMatMul)
945ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
946ec727ea7Spatrick 
947*12c85518Srobert   if (HasPAC)
948*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_PAUTH", "1");
949*12c85518Srobert 
950*12c85518Srobert   if (HasBTI)
951*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_BTI", "1");
952*12c85518Srobert 
953ec727ea7Spatrick   if (HasBFloat16) {
954ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_BF16", "1");
955ec727ea7Spatrick     Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
956ec727ea7Spatrick     Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
957ec727ea7Spatrick   }
958ec727ea7Spatrick 
959*12c85518Srobert   if (Opts.BranchTargetEnforcement)
960*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_BTI_DEFAULT", "1");
961*12c85518Srobert 
962*12c85518Srobert   if (Opts.hasSignReturnAddress()) {
963*12c85518Srobert     unsigned Value = 1;
964*12c85518Srobert     if (Opts.isSignReturnAddressScopeAll())
965*12c85518Srobert       Value |= 1 << 2;
966*12c85518Srobert     Builder.defineMacro("__ARM_FEATURE_PAC_DEFAULT", Twine(Value));
967*12c85518Srobert   }
968*12c85518Srobert 
969e5dd7070Spatrick   switch (ArchKind) {
970e5dd7070Spatrick   default:
971e5dd7070Spatrick     break;
972e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_1A:
973e5dd7070Spatrick     getTargetDefinesARMV81A(Opts, Builder);
974e5dd7070Spatrick     break;
975e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_2A:
976e5dd7070Spatrick     getTargetDefinesARMV82A(Opts, Builder);
977e5dd7070Spatrick     break;
978e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_3A:
979e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_4A:
980e5dd7070Spatrick   case llvm::ARM::ArchKind::ARMV8_5A:
981ec727ea7Spatrick   case llvm::ARM::ArchKind::ARMV8_6A:
982*12c85518Srobert   case llvm::ARM::ArchKind::ARMV8_7A:
983*12c85518Srobert   case llvm::ARM::ArchKind::ARMV8_8A:
984*12c85518Srobert   case llvm::ARM::ArchKind::ARMV8_9A:
985*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9A:
986*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_1A:
987*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_2A:
988*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_3A:
989*12c85518Srobert   case llvm::ARM::ArchKind::ARMV9_4A:
990e5dd7070Spatrick     getTargetDefinesARMV83A(Opts, Builder);
991e5dd7070Spatrick     break;
992e5dd7070Spatrick   }
993e5dd7070Spatrick }
994e5dd7070Spatrick 
995*12c85518Srobert static constexpr Builtin::Info BuiltinInfo[] = {
996e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
997*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
998e5dd7070Spatrick #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
999*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1000*12c85518Srobert #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
1001*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1002e5dd7070Spatrick #include "clang/Basic/BuiltinsNEON.def"
1003e5dd7070Spatrick 
1004e5dd7070Spatrick #define BUILTIN(ID, TYPE, ATTRS)                                               \
1005*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1006e5dd7070Spatrick #define LANGBUILTIN(ID, TYPE, ATTRS, LANG)                                     \
1007*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG},
1008e5dd7070Spatrick #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER)                                    \
1009*12c85518Srobert   {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES},
1010*12c85518Srobert #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE)                               \
1011*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
1012e5dd7070Spatrick #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE)         \
1013*12c85518Srobert   {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS},
1014e5dd7070Spatrick #include "clang/Basic/BuiltinsARM.def"
1015e5dd7070Spatrick };
1016e5dd7070Spatrick 
getTargetBuiltins() const1017e5dd7070Spatrick ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
1018*12c85518Srobert   return llvm::ArrayRef(BuiltinInfo,
1019*12c85518Srobert                         clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin);
1020e5dd7070Spatrick }
1021e5dd7070Spatrick 
isCLZForZeroUndef() const1022e5dd7070Spatrick bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
getBuiltinVaListKind() const1023e5dd7070Spatrick TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
1024e5dd7070Spatrick   return IsAAPCS
1025e5dd7070Spatrick              ? AAPCSABIBuiltinVaList
1026e5dd7070Spatrick              : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
1027e5dd7070Spatrick                                          : TargetInfo::VoidPtrBuiltinVaList);
1028e5dd7070Spatrick }
1029e5dd7070Spatrick 
1030e5dd7070Spatrick const char *const ARMTargetInfo::GCCRegNames[] = {
1031e5dd7070Spatrick     // Integer registers
1032e5dd7070Spatrick     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
1033e5dd7070Spatrick     "r12", "sp", "lr", "pc",
1034e5dd7070Spatrick 
1035e5dd7070Spatrick     // Float registers
1036e5dd7070Spatrick     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
1037e5dd7070Spatrick     "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
1038e5dd7070Spatrick     "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
1039e5dd7070Spatrick 
1040e5dd7070Spatrick     // Double registers
1041e5dd7070Spatrick     "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
1042e5dd7070Spatrick     "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
1043e5dd7070Spatrick     "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
1044e5dd7070Spatrick 
1045e5dd7070Spatrick     // Quad registers
1046e5dd7070Spatrick     "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
1047e5dd7070Spatrick     "q12", "q13", "q14", "q15"};
1048e5dd7070Spatrick 
getGCCRegNames() const1049e5dd7070Spatrick ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
1050*12c85518Srobert   return llvm::ArrayRef(GCCRegNames);
1051e5dd7070Spatrick }
1052e5dd7070Spatrick 
1053e5dd7070Spatrick const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
1054e5dd7070Spatrick     {{"a1"}, "r0"},  {{"a2"}, "r1"},        {{"a3"}, "r2"},  {{"a4"}, "r3"},
1055e5dd7070Spatrick     {{"v1"}, "r4"},  {{"v2"}, "r5"},        {{"v3"}, "r6"},  {{"v4"}, "r7"},
1056e5dd7070Spatrick     {{"v5"}, "r8"},  {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
1057e5dd7070Spatrick     {{"ip"}, "r12"}, {{"r13"}, "sp"},       {{"r14"}, "lr"}, {{"r15"}, "pc"},
1058e5dd7070Spatrick     // The S, D and Q registers overlap, but aren't really aliases; we
1059e5dd7070Spatrick     // don't want to substitute one of these for a different-sized one.
1060e5dd7070Spatrick };
1061e5dd7070Spatrick 
getGCCRegAliases() const1062e5dd7070Spatrick ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
1063*12c85518Srobert   return llvm::ArrayRef(GCCRegAliases);
1064e5dd7070Spatrick }
1065e5dd7070Spatrick 
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const1066e5dd7070Spatrick bool ARMTargetInfo::validateAsmConstraint(
1067e5dd7070Spatrick     const char *&Name, TargetInfo::ConstraintInfo &Info) const {
1068e5dd7070Spatrick   switch (*Name) {
1069e5dd7070Spatrick   default:
1070e5dd7070Spatrick     break;
1071e5dd7070Spatrick   case 'l': // r0-r7 if thumb, r0-r15 if ARM
1072e5dd7070Spatrick     Info.setAllowsRegister();
1073e5dd7070Spatrick     return true;
1074e5dd7070Spatrick   case 'h': // r8-r15, thumb only
1075e5dd7070Spatrick     if (isThumb()) {
1076e5dd7070Spatrick       Info.setAllowsRegister();
1077e5dd7070Spatrick       return true;
1078e5dd7070Spatrick     }
1079e5dd7070Spatrick     break;
1080e5dd7070Spatrick   case 's': // An integer constant, but allowing only relocatable values.
1081e5dd7070Spatrick     return true;
1082e5dd7070Spatrick   case 't': // s0-s31, d0-d31, or q0-q15
1083e5dd7070Spatrick   case 'w': // s0-s15, d0-d7, or q0-q3
1084e5dd7070Spatrick   case 'x': // s0-s31, d0-d15, or q0-q7
1085*12c85518Srobert     if (FPRegsDisabled)
1086*12c85518Srobert       return false;
1087e5dd7070Spatrick     Info.setAllowsRegister();
1088e5dd7070Spatrick     return true;
1089e5dd7070Spatrick   case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
1090e5dd7070Spatrick     // only available in ARMv6T2 and above
1091e5dd7070Spatrick     if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
1092e5dd7070Spatrick       Info.setRequiresImmediate(0, 65535);
1093e5dd7070Spatrick       return true;
1094e5dd7070Spatrick     }
1095e5dd7070Spatrick     break;
1096e5dd7070Spatrick   case 'I':
1097e5dd7070Spatrick     if (isThumb()) {
1098e5dd7070Spatrick       if (!supportsThumb2())
1099e5dd7070Spatrick         Info.setRequiresImmediate(0, 255);
1100e5dd7070Spatrick       else
1101e5dd7070Spatrick         // FIXME: should check if immediate value would be valid for a Thumb2
1102e5dd7070Spatrick         // data-processing instruction
1103e5dd7070Spatrick         Info.setRequiresImmediate();
1104e5dd7070Spatrick     } else
1105e5dd7070Spatrick       // FIXME: should check if immediate value would be valid for an ARM
1106e5dd7070Spatrick       // data-processing instruction
1107e5dd7070Spatrick       Info.setRequiresImmediate();
1108e5dd7070Spatrick     return true;
1109e5dd7070Spatrick   case 'J':
1110e5dd7070Spatrick     if (isThumb() && !supportsThumb2())
1111e5dd7070Spatrick       Info.setRequiresImmediate(-255, -1);
1112e5dd7070Spatrick     else
1113e5dd7070Spatrick       Info.setRequiresImmediate(-4095, 4095);
1114e5dd7070Spatrick     return true;
1115e5dd7070Spatrick   case 'K':
1116e5dd7070Spatrick     if (isThumb()) {
1117e5dd7070Spatrick       if (!supportsThumb2())
1118e5dd7070Spatrick         // FIXME: should check if immediate value can be obtained from shifting
1119e5dd7070Spatrick         // a value between 0 and 255 left by any amount
1120e5dd7070Spatrick         Info.setRequiresImmediate();
1121e5dd7070Spatrick       else
1122e5dd7070Spatrick         // FIXME: should check if immediate value would be valid for a Thumb2
1123e5dd7070Spatrick         // data-processing instruction when inverted
1124e5dd7070Spatrick         Info.setRequiresImmediate();
1125e5dd7070Spatrick     } else
1126e5dd7070Spatrick       // FIXME: should check if immediate value would be valid for an ARM
1127e5dd7070Spatrick       // data-processing instruction when inverted
1128e5dd7070Spatrick       Info.setRequiresImmediate();
1129e5dd7070Spatrick     return true;
1130e5dd7070Spatrick   case 'L':
1131e5dd7070Spatrick     if (isThumb()) {
1132e5dd7070Spatrick       if (!supportsThumb2())
1133e5dd7070Spatrick         Info.setRequiresImmediate(-7, 7);
1134e5dd7070Spatrick       else
1135e5dd7070Spatrick         // FIXME: should check if immediate value would be valid for a Thumb2
1136e5dd7070Spatrick         // data-processing instruction when negated
1137e5dd7070Spatrick         Info.setRequiresImmediate();
1138e5dd7070Spatrick     } else
1139e5dd7070Spatrick       // FIXME: should check if immediate value  would be valid for an ARM
1140e5dd7070Spatrick       // data-processing instruction when negated
1141e5dd7070Spatrick       Info.setRequiresImmediate();
1142e5dd7070Spatrick     return true;
1143e5dd7070Spatrick   case 'M':
1144e5dd7070Spatrick     if (isThumb() && !supportsThumb2())
1145e5dd7070Spatrick       // FIXME: should check if immediate value is a multiple of 4 between 0 and
1146e5dd7070Spatrick       // 1020
1147e5dd7070Spatrick       Info.setRequiresImmediate();
1148e5dd7070Spatrick     else
1149e5dd7070Spatrick       // FIXME: should check if immediate value is a power of two or a integer
1150e5dd7070Spatrick       // between 0 and 32
1151e5dd7070Spatrick       Info.setRequiresImmediate();
1152e5dd7070Spatrick     return true;
1153e5dd7070Spatrick   case 'N':
1154e5dd7070Spatrick     // Thumb1 only
1155e5dd7070Spatrick     if (isThumb() && !supportsThumb2()) {
1156e5dd7070Spatrick       Info.setRequiresImmediate(0, 31);
1157e5dd7070Spatrick       return true;
1158e5dd7070Spatrick     }
1159e5dd7070Spatrick     break;
1160e5dd7070Spatrick   case 'O':
1161e5dd7070Spatrick     // Thumb1 only
1162e5dd7070Spatrick     if (isThumb() && !supportsThumb2()) {
1163e5dd7070Spatrick       // FIXME: should check if immediate value is a multiple of 4 between -508
1164e5dd7070Spatrick       // and 508
1165e5dd7070Spatrick       Info.setRequiresImmediate();
1166e5dd7070Spatrick       return true;
1167e5dd7070Spatrick     }
1168e5dd7070Spatrick     break;
1169e5dd7070Spatrick   case 'Q': // A memory address that is a single base register.
1170e5dd7070Spatrick     Info.setAllowsMemory();
1171e5dd7070Spatrick     return true;
1172e5dd7070Spatrick   case 'T':
1173e5dd7070Spatrick     switch (Name[1]) {
1174e5dd7070Spatrick     default:
1175e5dd7070Spatrick       break;
1176e5dd7070Spatrick     case 'e': // Even general-purpose register
1177e5dd7070Spatrick     case 'o': // Odd general-purpose register
1178e5dd7070Spatrick       Info.setAllowsRegister();
1179e5dd7070Spatrick       Name++;
1180e5dd7070Spatrick       return true;
1181e5dd7070Spatrick     }
1182e5dd7070Spatrick     break;
1183e5dd7070Spatrick   case 'U': // a memory reference...
1184e5dd7070Spatrick     switch (Name[1]) {
1185e5dd7070Spatrick     case 'q': // ...ARMV4 ldrsb
1186e5dd7070Spatrick     case 'v': // ...VFP load/store (reg+constant offset)
1187e5dd7070Spatrick     case 'y': // ...iWMMXt load/store
1188e5dd7070Spatrick     case 't': // address valid for load/store opaque types wider
1189e5dd7070Spatrick               // than 128-bits
1190e5dd7070Spatrick     case 'n': // valid address for Neon doubleword vector load/store
1191e5dd7070Spatrick     case 'm': // valid address for Neon element and structure load/store
1192e5dd7070Spatrick     case 's': // valid address for non-offset loads/stores of quad-word
1193e5dd7070Spatrick               // values in four ARM registers
1194e5dd7070Spatrick       Info.setAllowsMemory();
1195e5dd7070Spatrick       Name++;
1196e5dd7070Spatrick       return true;
1197e5dd7070Spatrick     }
1198e5dd7070Spatrick     break;
1199e5dd7070Spatrick   }
1200e5dd7070Spatrick   return false;
1201e5dd7070Spatrick }
1202e5dd7070Spatrick 
convertConstraint(const char * & Constraint) const1203e5dd7070Spatrick std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1204e5dd7070Spatrick   std::string R;
1205e5dd7070Spatrick   switch (*Constraint) {
1206e5dd7070Spatrick   case 'U': // Two-character constraint; add "^" hint for later parsing.
1207e5dd7070Spatrick   case 'T':
1208e5dd7070Spatrick     R = std::string("^") + std::string(Constraint, 2);
1209e5dd7070Spatrick     Constraint++;
1210e5dd7070Spatrick     break;
1211e5dd7070Spatrick   case 'p': // 'p' should be translated to 'r' by default.
1212e5dd7070Spatrick     R = std::string("r");
1213e5dd7070Spatrick     break;
1214e5dd7070Spatrick   default:
1215e5dd7070Spatrick     return std::string(1, *Constraint);
1216e5dd7070Spatrick   }
1217e5dd7070Spatrick   return R;
1218e5dd7070Spatrick }
1219e5dd7070Spatrick 
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const1220e5dd7070Spatrick bool ARMTargetInfo::validateConstraintModifier(
1221e5dd7070Spatrick     StringRef Constraint, char Modifier, unsigned Size,
1222e5dd7070Spatrick     std::string &SuggestedModifier) const {
1223e5dd7070Spatrick   bool isOutput = (Constraint[0] == '=');
1224e5dd7070Spatrick   bool isInOut = (Constraint[0] == '+');
1225e5dd7070Spatrick 
1226e5dd7070Spatrick   // Strip off constraint modifiers.
1227e5dd7070Spatrick   while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1228e5dd7070Spatrick     Constraint = Constraint.substr(1);
1229e5dd7070Spatrick 
1230e5dd7070Spatrick   switch (Constraint[0]) {
1231e5dd7070Spatrick   default:
1232e5dd7070Spatrick     break;
1233e5dd7070Spatrick   case 'r': {
1234e5dd7070Spatrick     switch (Modifier) {
1235e5dd7070Spatrick     default:
1236e5dd7070Spatrick       return (isInOut || isOutput || Size <= 64);
1237e5dd7070Spatrick     case 'q':
1238e5dd7070Spatrick       // A register of size 32 cannot fit a vector type.
1239e5dd7070Spatrick       return false;
1240e5dd7070Spatrick     }
1241e5dd7070Spatrick   }
1242e5dd7070Spatrick   }
1243e5dd7070Spatrick 
1244e5dd7070Spatrick   return true;
1245e5dd7070Spatrick }
getClobbers() const1246e5dd7070Spatrick const char *ARMTargetInfo::getClobbers() const {
1247e5dd7070Spatrick   // FIXME: Is this really right?
1248e5dd7070Spatrick   return "";
1249e5dd7070Spatrick }
1250e5dd7070Spatrick 
1251e5dd7070Spatrick TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1252e5dd7070Spatrick ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1253e5dd7070Spatrick   switch (CC) {
1254e5dd7070Spatrick   case CC_AAPCS:
1255e5dd7070Spatrick   case CC_AAPCS_VFP:
1256e5dd7070Spatrick   case CC_Swift:
1257a9ac8606Spatrick   case CC_SwiftAsync:
1258e5dd7070Spatrick   case CC_OpenCLKernel:
1259e5dd7070Spatrick     return CCCR_OK;
1260e5dd7070Spatrick   default:
1261e5dd7070Spatrick     return CCCR_Warning;
1262e5dd7070Spatrick   }
1263e5dd7070Spatrick }
1264e5dd7070Spatrick 
getEHDataRegisterNumber(unsigned RegNo) const1265e5dd7070Spatrick int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1266e5dd7070Spatrick   if (RegNo == 0)
1267e5dd7070Spatrick     return 0;
1268e5dd7070Spatrick   if (RegNo == 1)
1269e5dd7070Spatrick     return 1;
1270e5dd7070Spatrick   return -1;
1271e5dd7070Spatrick }
1272e5dd7070Spatrick 
hasSjLjLowering() const1273e5dd7070Spatrick bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1274e5dd7070Spatrick 
ARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1275e5dd7070Spatrick ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1276e5dd7070Spatrick                                  const TargetOptions &Opts)
1277e5dd7070Spatrick     : ARMTargetInfo(Triple, Opts) {}
1278e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1279e5dd7070Spatrick void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1280e5dd7070Spatrick                                        MacroBuilder &Builder) const {
1281e5dd7070Spatrick   Builder.defineMacro("__ARMEL__");
1282e5dd7070Spatrick   ARMTargetInfo::getTargetDefines(Opts, Builder);
1283e5dd7070Spatrick }
1284e5dd7070Spatrick 
ARMbeTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1285e5dd7070Spatrick ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1286e5dd7070Spatrick                                  const TargetOptions &Opts)
1287e5dd7070Spatrick     : ARMTargetInfo(Triple, Opts) {}
1288e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1289e5dd7070Spatrick void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1290e5dd7070Spatrick                                        MacroBuilder &Builder) const {
1291e5dd7070Spatrick   Builder.defineMacro("__ARMEB__");
1292e5dd7070Spatrick   Builder.defineMacro("__ARM_BIG_ENDIAN");
1293e5dd7070Spatrick   ARMTargetInfo::getTargetDefines(Opts, Builder);
1294e5dd7070Spatrick }
1295e5dd7070Spatrick 
WindowsARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1296e5dd7070Spatrick WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1297e5dd7070Spatrick                                            const TargetOptions &Opts)
1298e5dd7070Spatrick     : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1299e5dd7070Spatrick }
1300e5dd7070Spatrick 
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const1301e5dd7070Spatrick void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1302e5dd7070Spatrick                                                   MacroBuilder &Builder) const {
1303e5dd7070Spatrick   // FIXME: this is invalid for WindowsCE
1304e5dd7070Spatrick   Builder.defineMacro("_M_ARM_NT", "1");
1305e5dd7070Spatrick   Builder.defineMacro("_M_ARMT", "_M_ARM");
1306e5dd7070Spatrick   Builder.defineMacro("_M_THUMB", "_M_ARM");
1307e5dd7070Spatrick 
1308e5dd7070Spatrick   assert((Triple.getArch() == llvm::Triple::arm ||
1309e5dd7070Spatrick           Triple.getArch() == llvm::Triple::thumb) &&
1310e5dd7070Spatrick          "invalid architecture for Windows ARM target info");
1311e5dd7070Spatrick   unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1312e5dd7070Spatrick   Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1313e5dd7070Spatrick 
1314e5dd7070Spatrick   // TODO map the complete set of values
1315e5dd7070Spatrick   // 31: VFPv3 40: VFPv4
1316e5dd7070Spatrick   Builder.defineMacro("_M_ARM_FP", "31");
1317e5dd7070Spatrick }
1318e5dd7070Spatrick 
1319e5dd7070Spatrick TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const1320e5dd7070Spatrick WindowsARMTargetInfo::getBuiltinVaListKind() const {
1321e5dd7070Spatrick   return TargetInfo::CharPtrBuiltinVaList;
1322e5dd7070Spatrick }
1323e5dd7070Spatrick 
1324e5dd7070Spatrick TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1325e5dd7070Spatrick WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1326e5dd7070Spatrick   switch (CC) {
1327e5dd7070Spatrick   case CC_X86StdCall:
1328e5dd7070Spatrick   case CC_X86ThisCall:
1329e5dd7070Spatrick   case CC_X86FastCall:
1330e5dd7070Spatrick   case CC_X86VectorCall:
1331e5dd7070Spatrick     return CCCR_Ignore;
1332e5dd7070Spatrick   case CC_C:
1333e5dd7070Spatrick   case CC_OpenCLKernel:
1334e5dd7070Spatrick   case CC_PreserveMost:
1335e5dd7070Spatrick   case CC_PreserveAll:
1336e5dd7070Spatrick   case CC_Swift:
1337a9ac8606Spatrick   case CC_SwiftAsync:
1338e5dd7070Spatrick     return CCCR_OK;
1339e5dd7070Spatrick   default:
1340e5dd7070Spatrick     return CCCR_Warning;
1341e5dd7070Spatrick   }
1342e5dd7070Spatrick }
1343e5dd7070Spatrick 
1344e5dd7070Spatrick // Windows ARM + Itanium C++ ABI Target
ItaniumWindowsARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1345e5dd7070Spatrick ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1346e5dd7070Spatrick     const llvm::Triple &Triple, const TargetOptions &Opts)
1347e5dd7070Spatrick     : WindowsARMTargetInfo(Triple, Opts) {
1348e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::GenericARM);
1349e5dd7070Spatrick }
1350e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1351e5dd7070Spatrick void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1352e5dd7070Spatrick     const LangOptions &Opts, MacroBuilder &Builder) const {
1353e5dd7070Spatrick   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1354e5dd7070Spatrick 
1355e5dd7070Spatrick   if (Opts.MSVCCompat)
1356e5dd7070Spatrick     WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1357e5dd7070Spatrick }
1358e5dd7070Spatrick 
1359e5dd7070Spatrick // Windows ARM, MS (C++) ABI
MicrosoftARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1360e5dd7070Spatrick MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1361e5dd7070Spatrick                                                    const TargetOptions &Opts)
1362e5dd7070Spatrick     : WindowsARMTargetInfo(Triple, Opts) {
1363e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::Microsoft);
1364e5dd7070Spatrick }
1365e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1366e5dd7070Spatrick void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1367e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
1368e5dd7070Spatrick   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1369e5dd7070Spatrick   WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1370e5dd7070Spatrick }
1371e5dd7070Spatrick 
MinGWARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1372e5dd7070Spatrick MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1373e5dd7070Spatrick                                        const TargetOptions &Opts)
1374e5dd7070Spatrick     : WindowsARMTargetInfo(Triple, Opts) {
1375e5dd7070Spatrick   TheCXXABI.set(TargetCXXABI::GenericARM);
1376e5dd7070Spatrick }
1377e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1378e5dd7070Spatrick void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1379e5dd7070Spatrick                                           MacroBuilder &Builder) const {
1380e5dd7070Spatrick   WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1381e5dd7070Spatrick   Builder.defineMacro("_ARM_");
1382e5dd7070Spatrick }
1383e5dd7070Spatrick 
CygwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1384e5dd7070Spatrick CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1385e5dd7070Spatrick                                          const TargetOptions &Opts)
1386e5dd7070Spatrick     : ARMleTargetInfo(Triple, Opts) {
1387e5dd7070Spatrick   this->WCharType = TargetInfo::UnsignedShort;
1388e5dd7070Spatrick   TLSSupported = false;
1389e5dd7070Spatrick   DoubleAlign = LongLongAlign = 64;
1390e5dd7070Spatrick   resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1391e5dd7070Spatrick }
1392e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1393e5dd7070Spatrick void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1394e5dd7070Spatrick                                            MacroBuilder &Builder) const {
1395e5dd7070Spatrick   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1396e5dd7070Spatrick   Builder.defineMacro("_ARM_");
1397e5dd7070Spatrick   Builder.defineMacro("__CYGWIN__");
1398e5dd7070Spatrick   Builder.defineMacro("__CYGWIN32__");
1399e5dd7070Spatrick   DefineStd(Builder, "unix", Opts);
1400e5dd7070Spatrick   if (Opts.CPlusPlus)
1401e5dd7070Spatrick     Builder.defineMacro("_GNU_SOURCE");
1402e5dd7070Spatrick }
1403e5dd7070Spatrick 
DarwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1404e5dd7070Spatrick DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1405e5dd7070Spatrick                                          const TargetOptions &Opts)
1406e5dd7070Spatrick     : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1407e5dd7070Spatrick   HasAlignMac68kSupport = true;
1408e5dd7070Spatrick   // iOS always has 64-bit atomic instructions.
1409e5dd7070Spatrick   // FIXME: This should be based off of the target features in
1410e5dd7070Spatrick   // ARMleTargetInfo.
1411e5dd7070Spatrick   MaxAtomicInlineWidth = 64;
1412e5dd7070Spatrick 
1413e5dd7070Spatrick   if (Triple.isWatchABI()) {
1414e5dd7070Spatrick     // Darwin on iOS uses a variant of the ARM C++ ABI.
1415e5dd7070Spatrick     TheCXXABI.set(TargetCXXABI::WatchOS);
1416e5dd7070Spatrick 
1417e5dd7070Spatrick     // BOOL should be a real boolean on the new ABI
1418e5dd7070Spatrick     UseSignedCharForObjCBool = false;
1419e5dd7070Spatrick   } else
1420e5dd7070Spatrick     TheCXXABI.set(TargetCXXABI::iOS);
1421e5dd7070Spatrick }
1422e5dd7070Spatrick 
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const1423e5dd7070Spatrick void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1424e5dd7070Spatrick                                        const llvm::Triple &Triple,
1425e5dd7070Spatrick                                        MacroBuilder &Builder) const {
1426e5dd7070Spatrick   getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1427e5dd7070Spatrick }
1428e5dd7070Spatrick 
RenderScript32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1429e5dd7070Spatrick RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1430e5dd7070Spatrick                                                    const TargetOptions &Opts)
1431e5dd7070Spatrick     : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1432e5dd7070Spatrick                                    Triple.getOSName(),
1433e5dd7070Spatrick                                    Triple.getEnvironmentName()),
1434e5dd7070Spatrick                       Opts) {
1435e5dd7070Spatrick   IsRenderScriptTarget = true;
1436e5dd7070Spatrick   LongWidth = LongAlign = 64;
1437e5dd7070Spatrick }
1438e5dd7070Spatrick 
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1439e5dd7070Spatrick void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1440e5dd7070Spatrick                                                 MacroBuilder &Builder) const {
1441e5dd7070Spatrick   Builder.defineMacro("__RENDERSCRIPT__");
1442e5dd7070Spatrick   ARMleTargetInfo::getTargetDefines(Opts, Builder);
1443e5dd7070Spatrick }
1444