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