blob: 736c235745b0cf7cdbdca61df78e4144a034b630 [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
Tim Northoverad4c5db2017-07-24 17:06:23 +0000337 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000338 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000339
Tim Northoverad4c5db2017-07-24 17:06:23 +0000340 // get default FPU features
341 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
342 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000343
Tim Northoverad4c5db2017-07-24 17:06:23 +0000344 // get default Extension features
345 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
346 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000347
Tim Northoverad4c5db2017-07-24 17:06:23 +0000348 for (auto Feature : TargetFeatures)
349 if (Feature[0] == '+')
350 Features[Feature.drop_front(1)] = true;
351
352 // Enable or disable thumb-mode explicitly per function to enable mixed
353 // ARM and Thumb code generation.
354 if (isThumb())
355 Features["thumb-mode"] = true;
356 else
357 Features["thumb-mode"] = false;
358
359 // Convert user-provided arm and thumb GNU target attributes to
360 // [-|+]thumb-mode target features respectively.
361 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
362 for (auto &Feature : UpdatedFeaturesVec) {
363 if (Feature.compare("+arm") == 0)
364 Feature = "-thumb-mode";
365 else if (Feature.compare("+thumb") == 0)
366 Feature = "+thumb-mode";
367 }
368
369 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000370}
371
Erich Keaneebba5922017-07-21 22:37:03 +0000372
Tim Northoverad4c5db2017-07-24 17:06:23 +0000373bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
374 DiagnosticsEngine &Diags) {
375 FPU = 0;
376 CRC = 0;
377 Crypto = 0;
378 DSP = 0;
379 Unaligned = 1;
380 SoftFloat = SoftFloatABI = false;
381 HWDiv = 0;
382
383 // This does not diagnose illegal cases like having both
384 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
385 uint32_t HW_FP_remove = 0;
386 for (const auto &Feature : Features) {
387 if (Feature == "+soft-float") {
388 SoftFloat = true;
389 } else if (Feature == "+soft-float-abi") {
390 SoftFloatABI = true;
391 } else if (Feature == "+vfp2") {
392 FPU |= VFP2FPU;
393 HW_FP |= HW_FP_SP | HW_FP_DP;
394 } else if (Feature == "+vfp3") {
395 FPU |= VFP3FPU;
396 HW_FP |= HW_FP_SP | HW_FP_DP;
397 } else if (Feature == "+vfp4") {
398 FPU |= VFP4FPU;
399 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
400 } else if (Feature == "+fp-armv8") {
401 FPU |= FPARMV8;
402 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
403 } else if (Feature == "+neon") {
404 FPU |= NeonFPU;
405 HW_FP |= HW_FP_SP | HW_FP_DP;
406 } else if (Feature == "+hwdiv") {
407 HWDiv |= HWDivThumb;
408 } else if (Feature == "+hwdiv-arm") {
409 HWDiv |= HWDivARM;
410 } else if (Feature == "+crc") {
411 CRC = 1;
412 } else if (Feature == "+crypto") {
413 Crypto = 1;
414 } else if (Feature == "+dsp") {
415 DSP = 1;
416 } else if (Feature == "+fp-only-sp") {
417 HW_FP_remove |= HW_FP_DP;
418 } else if (Feature == "+strict-align") {
419 Unaligned = 0;
420 } else if (Feature == "+fp16") {
421 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000422 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000423 HasLegalHalfType = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000424 }
425 }
426 HW_FP &= ~HW_FP_remove;
427
428 switch (ArchVersion) {
429 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000430 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000431 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000432 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000433 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
434 else
435 LDREX = LDREX_W;
436 break;
437 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000438 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000439 LDREX = LDREX_W | LDREX_H | LDREX_B;
440 else
441 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
442 break;
443 case 8:
444 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
445 }
446
447 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
448 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
449 return false;
450 }
451
452 if (FPMath == FP_Neon)
453 Features.push_back("+neonfp");
454 else if (FPMath == FP_VFP)
455 Features.push_back("-neonfp");
456
457 // Remove front-end specific options which the backend handles differently.
458 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
459 if (Feature != Features.end())
460 Features.erase(Feature);
461
462 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000463}
464
Erich Keaneebba5922017-07-21 22:37:03 +0000465bool ARMTargetInfo::hasFeature(StringRef Feature) const {
466 return llvm::StringSwitch<bool>(Feature)
467 .Case("arm", true)
468 .Case("aarch32", true)
469 .Case("softfloat", SoftFloat)
470 .Case("thumb", isThumb())
471 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
472 .Case("vfp", FPU && !SoftFloat)
473 .Case("hwdiv", HWDiv & HWDivThumb)
474 .Case("hwdiv-arm", HWDiv & HWDivARM)
475 .Default(false);
476}
477
Tim Northoverad4c5db2017-07-24 17:06:23 +0000478bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
479 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000480 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000481}
482
Erich Keane3ec17432018-02-08 23:14:15 +0000483void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
484 llvm::ARM::fillValidCPUArchList(Values);
485}
486
Tim Northoverad4c5db2017-07-24 17:06:23 +0000487bool ARMTargetInfo::setCPU(const std::string &Name) {
488 if (Name != "generic")
489 setArchInfo(llvm::ARM::parseCPUArch(Name));
490
Florian Hahnef5bbd62017-07-27 16:28:39 +0000491 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000492 return false;
493 setAtomic();
494 CPU = Name;
495 return true;
496}
497
498bool ARMTargetInfo::setFPMath(StringRef Name) {
499 if (Name == "neon") {
500 FPMath = FP_Neon;
501 return true;
502 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
503 Name == "vfp4") {
504 FPMath = FP_VFP;
505 return true;
506 }
507 return false;
508}
509
510void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
511 MacroBuilder &Builder) const {
512 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
513}
514
515void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
516 MacroBuilder &Builder) const {
517 // Also include the ARMv8.1-A defines
518 getTargetDefinesARMV81A(Opts, Builder);
519}
520
Erich Keaneebba5922017-07-21 22:37:03 +0000521void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
522 MacroBuilder &Builder) const {
523 // Target identification.
524 Builder.defineMacro("__arm");
525 Builder.defineMacro("__arm__");
526 // For bare-metal none-eabi.
527 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
528 (getTriple().getEnvironment() == llvm::Triple::EABI ||
529 getTriple().getEnvironment() == llvm::Triple::EABIHF))
530 Builder.defineMacro("__ELF__");
531
532 // Target properties.
533 Builder.defineMacro("__REGISTER_PREFIX__", "");
534
535 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
536 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
537 if (getTriple().isWatchABI())
538 Builder.defineMacro("__ARM_ARCH_7K__", "2");
539
540 if (!CPUAttr.empty())
541 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
542
543 // ACLE 6.4.1 ARM/Thumb instruction set architecture
544 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
545 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
546
547 if (ArchVersion >= 8) {
548 // ACLE 6.5.7 Crypto Extension
549 if (Crypto)
550 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
551 // ACLE 6.5.8 CRC32 Extension
552 if (CRC)
553 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
554 // ACLE 6.5.10 Numeric Maximum and Minimum
555 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
556 // ACLE 6.5.9 Directed Rounding
557 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
558 }
559
560 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
561 // is not defined for the M-profile.
562 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000563 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000564 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
565
566 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
567 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
568 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
569 // v7 and v8 architectures excluding v8-M Baseline.
570 if (supportsThumb2())
571 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
572 else if (supportsThumb())
573 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
574
575 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
576 // instruction set such as ARM or Thumb.
577 Builder.defineMacro("__ARM_32BIT_STATE", "1");
578
579 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
580
581 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
582 if (!CPUProfile.empty())
583 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
584
585 // ACLE 6.4.3 Unaligned access supported in hardware
586 if (Unaligned)
587 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
588
589 // ACLE 6.4.4 LDREX/STREX
590 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000591 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000592
593 // ACLE 6.4.5 CLZ
594 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
595 ArchVersion > 6)
596 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
597
598 // ACLE 6.5.1 Hardware Floating Point
599 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000600 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000601
602 // ACLE predefines.
603 Builder.defineMacro("__ARM_ACLE", "200");
604
605 // FP16 support (we currently only support IEEE format).
606 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
607 Builder.defineMacro("__ARM_FP16_ARGS", "1");
608
609 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
610 if (ArchVersion >= 7 && (FPU & VFP4FPU))
611 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
612
613 // Subtarget options.
614
615 // FIXME: It's more complicated than this and we don't really support
616 // interworking.
617 // Windows on ARM does not "support" interworking
618 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
619 Builder.defineMacro("__THUMB_INTERWORK__");
620
621 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
622 // Embedded targets on Darwin follow AAPCS, but not EABI.
623 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
624 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
625 Builder.defineMacro("__ARM_EABI__");
626 Builder.defineMacro("__ARM_PCS", "1");
627 }
628
629 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
630 Builder.defineMacro("__ARM_PCS_VFP", "1");
631
632 if (SoftFloat)
633 Builder.defineMacro("__SOFTFP__");
634
Florian Hahnef5bbd62017-07-27 16:28:39 +0000635 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000636 Builder.defineMacro("__XSCALE__");
637
638 if (isThumb()) {
639 Builder.defineMacro("__THUMBEL__");
640 Builder.defineMacro("__thumb__");
641 if (supportsThumb2())
642 Builder.defineMacro("__thumb2__");
643 }
644
645 // ACLE 6.4.9 32-bit SIMD instructions
646 if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
647 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
648
649 // ACLE 6.4.10 Hardware Integer Divide
650 if (((HWDiv & HWDivThumb) && isThumb()) ||
651 ((HWDiv & HWDivARM) && !isThumb())) {
652 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
653 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
654 }
655
656 // Note, this is always on in gcc, even though it doesn't make sense.
657 Builder.defineMacro("__APCS_32__");
658
659 if (FPUModeIsVFP((FPUMode)FPU)) {
660 Builder.defineMacro("__VFP_FP__");
661 if (FPU & VFP2FPU)
662 Builder.defineMacro("__ARM_VFPV2__");
663 if (FPU & VFP3FPU)
664 Builder.defineMacro("__ARM_VFPV3__");
665 if (FPU & VFP4FPU)
666 Builder.defineMacro("__ARM_VFPV4__");
667 if (FPU & FPARMV8)
668 Builder.defineMacro("__ARM_FPV5__");
669 }
670
671 // This only gets set when Neon instructions are actually available, unlike
672 // the VFP define, hence the soft float and arch check. This is subtly
673 // different from gcc, we follow the intent which was that it should be set
674 // when Neon instructions are actually available.
675 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
676 Builder.defineMacro("__ARM_NEON", "1");
677 Builder.defineMacro("__ARM_NEON__");
678 // current AArch32 NEON implementations do not support double-precision
679 // floating-point even when it is present in VFP.
680 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000681 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000682 }
683
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000684 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000685 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000686
687 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
688
689 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
690 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
691 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
692 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
693 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
694 }
695
696 // ACLE 6.4.7 DSP instructions
697 if (DSP) {
698 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
699 }
700
701 // ACLE 6.4.8 Saturation instructions
702 bool SAT = false;
703 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
704 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
705 SAT = true;
706 }
707
708 // ACLE 6.4.6 Q (saturation) flag
709 if (DSP || SAT)
710 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
711
712 if (Opts.UnsafeFPMath)
713 Builder.defineMacro("__ARM_FP_FAST", "1");
714
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000715 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000716 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000717 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
718
719 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000720 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000721 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
722
723
Erich Keaneebba5922017-07-21 22:37:03 +0000724 switch (ArchKind) {
725 default:
726 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000727 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000728 getTargetDefinesARMV81A(Opts, Builder);
729 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000730 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000731 getTargetDefinesARMV82A(Opts, Builder);
732 break;
733 }
734}
735
Tim Northoverad4c5db2017-07-24 17:06:23 +0000736const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
737#define BUILTIN(ID, TYPE, ATTRS) \
738 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
739#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
740 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
741#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000742
Tim Northoverad4c5db2017-07-24 17:06:23 +0000743#define BUILTIN(ID, TYPE, ATTRS) \
744 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
745#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
746 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
747#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
748 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
749#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
750 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
751#include "clang/Basic/BuiltinsARM.def"
752};
753
754ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
755 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
756 Builtin::FirstTSBuiltin);
757}
758
759bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
760TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
761 return IsAAPCS
762 ? AAPCSABIBuiltinVaList
763 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
764 : TargetInfo::VoidPtrBuiltinVaList);
765}
766
767const char *const ARMTargetInfo::GCCRegNames[] = {
768 // Integer registers
769 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
770 "r12", "sp", "lr", "pc",
771
772 // Float registers
773 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
774 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
775 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
776
777 // Double registers
778 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
779 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
780 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
781
782 // Quad registers
783 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
784 "q12", "q13", "q14", "q15"};
785
786ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
787 return llvm::makeArrayRef(GCCRegNames);
788}
789
790const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
791 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
792 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
793 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
794 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
795 // The S, D and Q registers overlap, but aren't really aliases; we
796 // don't want to substitute one of these for a different-sized one.
797};
798
799ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
800 return llvm::makeArrayRef(GCCRegAliases);
801}
802
803bool ARMTargetInfo::validateAsmConstraint(
804 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
805 switch (*Name) {
806 default:
807 break;
808 case 'l': // r0-r7
809 case 'h': // r8-r15
810 case 't': // VFP Floating point register single precision
811 case 'w': // VFP Floating point register double precision
812 Info.setAllowsRegister();
813 return true;
814 case 'I':
815 case 'J':
816 case 'K':
817 case 'L':
818 case 'M':
819 // FIXME
820 return true;
821 case 'Q': // A memory address that is a single base register.
822 Info.setAllowsMemory();
823 return true;
824 case 'U': // a memory reference...
825 switch (Name[1]) {
826 case 'q': // ...ARMV4 ldrsb
827 case 'v': // ...VFP load/store (reg+constant offset)
828 case 'y': // ...iWMMXt load/store
829 case 't': // address valid for load/store opaque types wider
830 // than 128-bits
831 case 'n': // valid address for Neon doubleword vector load/store
832 case 'm': // valid address for Neon element and structure load/store
833 case 's': // valid address for non-offset loads/stores of quad-word
834 // values in four ARM registers
835 Info.setAllowsMemory();
836 Name++;
837 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000838 }
839 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000840 return false;
841}
Erich Keaneebba5922017-07-21 22:37:03 +0000842
Tim Northoverad4c5db2017-07-24 17:06:23 +0000843std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
844 std::string R;
845 switch (*Constraint) {
846 case 'U': // Two-character constraint; add "^" hint for later parsing.
847 R = std::string("^") + std::string(Constraint, 2);
848 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000849 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000850 case 'p': // 'p' should be translated to 'r' by default.
851 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000852 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000853 default:
854 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000855 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000856 return R;
857}
Erich Keaneebba5922017-07-21 22:37:03 +0000858
Tim Northoverad4c5db2017-07-24 17:06:23 +0000859bool ARMTargetInfo::validateConstraintModifier(
860 StringRef Constraint, char Modifier, unsigned Size,
861 std::string &SuggestedModifier) const {
862 bool isOutput = (Constraint[0] == '=');
863 bool isInOut = (Constraint[0] == '+');
864
865 // Strip off constraint modifiers.
866 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
867 Constraint = Constraint.substr(1);
868
869 switch (Constraint[0]) {
870 default:
871 break;
872 case 'r': {
873 switch (Modifier) {
874 default:
875 return (isInOut || isOutput || Size <= 64);
876 case 'q':
877 // A register of size 32 cannot fit a vector type.
878 return false;
879 }
Erich Keaneebba5922017-07-21 22:37:03 +0000880 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000881 }
Erich Keaneebba5922017-07-21 22:37:03 +0000882
883 return true;
884}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000885const char *ARMTargetInfo::getClobbers() const {
886 // FIXME: Is this really right?
887 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000888}
889
Tim Northoverad4c5db2017-07-24 17:06:23 +0000890TargetInfo::CallingConvCheckResult
891ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
892 switch (CC) {
893 case CC_AAPCS:
894 case CC_AAPCS_VFP:
895 case CC_Swift:
896 case CC_OpenCLKernel:
897 return CCCR_OK;
898 default:
899 return CCCR_Warning;
900 }
901}
902
903int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
904 if (RegNo == 0)
905 return 0;
906 if (RegNo == 1)
907 return 1;
908 return -1;
909}
910
911bool ARMTargetInfo::hasSjLjLowering() const { return true; }
912
913ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
914 const TargetOptions &Opts)
915 : ARMTargetInfo(Triple, Opts) {}
916
Erich Keaneebba5922017-07-21 22:37:03 +0000917void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
918 MacroBuilder &Builder) const {
919 Builder.defineMacro("__ARMEL__");
920 ARMTargetInfo::getTargetDefines(Opts, Builder);
921}
922
Tim Northoverad4c5db2017-07-24 17:06:23 +0000923ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
924 const TargetOptions &Opts)
925 : ARMTargetInfo(Triple, Opts) {}
926
Erich Keaneebba5922017-07-21 22:37:03 +0000927void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
928 MacroBuilder &Builder) const {
929 Builder.defineMacro("__ARMEB__");
930 Builder.defineMacro("__ARM_BIG_ENDIAN");
931 ARMTargetInfo::getTargetDefines(Opts, Builder);
932}
933
Tim Northoverad4c5db2017-07-24 17:06:23 +0000934WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
935 const TargetOptions &Opts)
936 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000937}
938
Erich Keaneebba5922017-07-21 22:37:03 +0000939void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
940 MacroBuilder &Builder) const {
941 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
942
943 // FIXME: this is invalid for WindowsCE
944 Builder.defineMacro("_M_ARM_NT", "1");
945 Builder.defineMacro("_M_ARMT", "_M_ARM");
946 Builder.defineMacro("_M_THUMB", "_M_ARM");
947
948 assert((Triple.getArch() == llvm::Triple::arm ||
949 Triple.getArch() == llvm::Triple::thumb) &&
950 "invalid architecture for Windows ARM target info");
951 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
952 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
953
954 // TODO map the complete set of values
955 // 31: VFPv3 40: VFPv4
956 Builder.defineMacro("_M_ARM_FP", "31");
957}
958
Tim Northoverad4c5db2017-07-24 17:06:23 +0000959TargetInfo::BuiltinVaListKind
960WindowsARMTargetInfo::getBuiltinVaListKind() const {
961 return TargetInfo::CharPtrBuiltinVaList;
962}
963
964TargetInfo::CallingConvCheckResult
965WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
966 switch (CC) {
967 case CC_X86StdCall:
968 case CC_X86ThisCall:
969 case CC_X86FastCall:
970 case CC_X86VectorCall:
971 return CCCR_Ignore;
972 case CC_C:
973 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +0000974 case CC_PreserveMost:
975 case CC_PreserveAll:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000976 return CCCR_OK;
977 default:
978 return CCCR_Warning;
979 }
980}
981
982// Windows ARM + Itanium C++ ABI Target
983ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
984 const llvm::Triple &Triple, const TargetOptions &Opts)
985 : WindowsARMTargetInfo(Triple, Opts) {
986 TheCXXABI.set(TargetCXXABI::GenericARM);
987}
988
989void ItaniumWindowsARMleTargetInfo::getTargetDefines(
990 const LangOptions &Opts, MacroBuilder &Builder) const {
991 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
992
993 if (Opts.MSVCCompat)
994 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
995}
996
997// Windows ARM, MS (C++) ABI
998MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
999 const TargetOptions &Opts)
1000 : WindowsARMTargetInfo(Triple, Opts) {
1001 TheCXXABI.set(TargetCXXABI::Microsoft);
1002}
1003
1004void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1005 MacroBuilder &Builder) const {
1006 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1007 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1008}
1009
1010MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1011 const TargetOptions &Opts)
1012 : WindowsARMTargetInfo(Triple, Opts) {
1013 TheCXXABI.set(TargetCXXABI::GenericARM);
1014}
1015
Erich Keaneebba5922017-07-21 22:37:03 +00001016void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1017 MacroBuilder &Builder) const {
1018 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001019 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001020}
1021
Tim Northoverad4c5db2017-07-24 17:06:23 +00001022CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1023 const TargetOptions &Opts)
1024 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001025 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001026 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001027 DoubleAlign = LongLongAlign = 64;
1028 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1029}
1030
Erich Keaneebba5922017-07-21 22:37:03 +00001031void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1032 MacroBuilder &Builder) const {
1033 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1034 Builder.defineMacro("_ARM_");
1035 Builder.defineMacro("__CYGWIN__");
1036 Builder.defineMacro("__CYGWIN32__");
1037 DefineStd(Builder, "unix", Opts);
1038 if (Opts.CPlusPlus)
1039 Builder.defineMacro("_GNU_SOURCE");
1040}
1041
Tim Northoverad4c5db2017-07-24 17:06:23 +00001042DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1043 const TargetOptions &Opts)
1044 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1045 HasAlignMac68kSupport = true;
1046 // iOS always has 64-bit atomic instructions.
1047 // FIXME: This should be based off of the target features in
1048 // ARMleTargetInfo.
1049 MaxAtomicInlineWidth = 64;
1050
1051 if (Triple.isWatchABI()) {
1052 // Darwin on iOS uses a variant of the ARM C++ ABI.
1053 TheCXXABI.set(TargetCXXABI::WatchOS);
1054
Tim Northoverad4c5db2017-07-24 17:06:23 +00001055 // BOOL should be a real boolean on the new ABI
1056 UseSignedCharForObjCBool = false;
1057 } else
1058 TheCXXABI.set(TargetCXXABI::iOS);
1059}
1060
1061void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1062 const llvm::Triple &Triple,
1063 MacroBuilder &Builder) const {
1064 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1065}
1066
1067RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1068 const TargetOptions &Opts)
1069 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1070 Triple.getOSName(),
1071 Triple.getEnvironmentName()),
1072 Opts) {
1073 IsRenderScriptTarget = true;
1074 LongWidth = LongAlign = 64;
1075}
1076
Erich Keaneebba5922017-07-21 22:37:03 +00001077void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1078 MacroBuilder &Builder) const {
1079 Builder.defineMacro("__RENDERSCRIPT__");
1080 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1081}