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