blob: 992cfbde364ca961896940e9817cd3ad10b30915 [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
31 // size_t is unsigned long on MachO-derived environments, NetBSD, and
32 // OpenBSD.
33 if (T.isOSBinFormatMachO() || T.getOS() == llvm::Triple::NetBSD ||
34 T.getOS() == llvm::Triple::OpenBSD)
35 SizeType = UnsignedLong;
36 else
37 SizeType = UnsignedInt;
38
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000039 bool IsNetBSD = T.getOS() == llvm::Triple::NetBSD;
40 bool IsOpenBSD = T.getOS() == llvm::Triple::OpenBSD;
41 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +000042 WCharType = UnsignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +000043
44 UseBitFieldTypeAlignment = true;
45
46 ZeroLengthBitfieldBoundary = 0;
47
48 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
49 // so set preferred for small types to 32.
50 if (T.isOSBinFormatMachO()) {
51 resetDataLayout(BigEndian
52 ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
53 : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
54 } else if (T.isOSWindows()) {
55 assert(!BigEndian && "Windows on ARM does not support big endian");
56 resetDataLayout("e"
57 "-m:w"
58 "-p:32:32"
59 "-i64:64"
60 "-v128:64:128"
61 "-a:0:32"
62 "-n32"
63 "-S64");
64 } else if (T.isOSNaCl()) {
65 assert(!BigEndian && "NaCl on ARM does not support big endian");
66 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
67 } else {
68 resetDataLayout(BigEndian
69 ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
70 : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
71 }
72
73 // FIXME: Enumerated types are variable width in straight AAPCS.
74}
75
76void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
77 const llvm::Triple &T = getTriple();
78
79 IsAAPCS = false;
80
81 if (IsAAPCS16)
82 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
83 else
84 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
85
86 // size_t is unsigned int on FreeBSD.
87 if (T.getOS() == llvm::Triple::FreeBSD)
88 SizeType = UnsignedInt;
89 else
90 SizeType = UnsignedLong;
91
Tim Northoverad4c5db2017-07-24 17:06:23 +000092 WCharType = SignedInt;
93
94 // Do not respect the alignment of bit-field types when laying out
95 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
96 UseBitFieldTypeAlignment = false;
97
98 /// gcc forces the alignment to 4 bytes, regardless of the type of the
99 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
100 /// gcc.
101 ZeroLengthBitfieldBoundary = 32;
102
103 if (T.isOSBinFormatMachO() && IsAAPCS16) {
104 assert(!BigEndian && "AAPCS16 does not support big-endian");
105 resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
106 } else if (T.isOSBinFormatMachO())
107 resetDataLayout(
108 BigEndian
109 ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
110 : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
111 else
112 resetDataLayout(
113 BigEndian
114 ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
115 : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
116
117 // FIXME: Override "preferred align" for double and long long.
118}
119
120void ARMTargetInfo::setArchInfo() {
121 StringRef ArchName = getTriple().getArchName();
122
123 ArchISA = llvm::ARM::parseArchISA(ArchName);
124 CPU = llvm::ARM::getDefaultCPU(ArchName);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000125 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
126 if (AK != llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000127 ArchKind = AK;
128 setArchInfo(ArchKind);
129}
130
Florian Hahnef5bbd62017-07-27 16:28:39 +0000131void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000132 StringRef SubArch;
133
134 // cache TargetParser info
135 ArchKind = Kind;
136 SubArch = llvm::ARM::getSubArch(ArchKind);
137 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
138 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
139
140 // cache CPU related strings
141 CPUAttr = getCPUAttr();
142 CPUProfile = getCPUProfile();
143}
144
145void ARMTargetInfo::setAtomic() {
146 // when triple does not specify a sub arch,
147 // then we are not using inline atomics
148 bool ShouldUseInlineAtomic =
Florian Hahnef5bbd62017-07-27 16:28:39 +0000149 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
150 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000151 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
Florian Hahnef5bbd62017-07-27 16:28:39 +0000152 if (ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000153 MaxAtomicPromoteWidth = 32;
154 if (ShouldUseInlineAtomic)
155 MaxAtomicInlineWidth = 32;
156 } else {
157 MaxAtomicPromoteWidth = 64;
158 if (ShouldUseInlineAtomic)
159 MaxAtomicInlineWidth = 64;
160 }
161}
162
Florian Hahnef5bbd62017-07-27 16:28:39 +0000163bool ARMTargetInfo::isThumb() const {
164 return ArchISA == llvm::ARM::ISAKind::THUMB;
165}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000166
167bool ARMTargetInfo::supportsThumb() const {
168 return CPUAttr.count('T') || ArchVersion >= 6;
169}
170
171bool ARMTargetInfo::supportsThumb2() const {
172 return CPUAttr.equals("6T2") ||
173 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
174}
175
176StringRef ARMTargetInfo::getCPUAttr() const {
177 // For most sub-arches, the build attribute CPU name is enough.
178 // For Cortex variants, it's slightly different.
179 switch (ArchKind) {
180 default:
181 return llvm::ARM::getCPUAttr(ArchKind);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000182 case llvm::ARM::ArchKind::ARMV6M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000183 return "6M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000184 case llvm::ARM::ArchKind::ARMV7S:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000185 return "7S";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000186 case llvm::ARM::ArchKind::ARMV7A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000187 return "7A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000188 case llvm::ARM::ArchKind::ARMV7R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000189 return "7R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000190 case llvm::ARM::ArchKind::ARMV7M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000191 return "7M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000192 case llvm::ARM::ArchKind::ARMV7EM:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000193 return "7EM";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000194 case llvm::ARM::ArchKind::ARMV7VE:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000195 return "7VE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000196 case llvm::ARM::ArchKind::ARMV8A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000197 return "8A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000198 case llvm::ARM::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000199 return "8_1A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000200 case llvm::ARM::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000201 return "8_2A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000202 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000203 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000204 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000205 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000206 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000207 return "8R";
208 }
209}
210
211StringRef ARMTargetInfo::getCPUProfile() const {
212 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000213 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000214 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000215 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000216 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000217 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000218 return "M";
219 default:
220 return "";
221 }
222}
223
224ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
225 const TargetOptions &Opts)
226 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
227 HW_FP(0) {
228
229 switch (getTriple().getOS()) {
230 case llvm::Triple::NetBSD:
231 case llvm::Triple::OpenBSD:
232 PtrDiffType = SignedLong;
233 break;
234 default:
235 PtrDiffType = SignedInt;
236 break;
237 }
238
Saleem Abdulrasool8d799f82017-10-18 00:00:50 +0000239 IntPtrType = (Triple.isOSDarwin() || Triple.getOS() == llvm::Triple::OpenBSD)
240 ? SignedLong
241 : SignedInt;
242
Tim Northoverad4c5db2017-07-24 17:06:23 +0000243 // Cache arch related info.
244 setArchInfo();
245
246 // {} in inline assembly are neon specifiers, not assembly variant
247 // specifiers.
248 NoAsmVariants = true;
249
250 // FIXME: This duplicates code from the driver that sets the -target-abi
251 // option - this code is used if -target-abi isn't passed and should
252 // be unified in some way.
253 if (Triple.isOSBinFormatMachO()) {
254 // The backend is hardwired to assume AAPCS for M-class processors, ensure
255 // the frontend matches that.
256 if (Triple.getEnvironment() == llvm::Triple::EABI ||
257 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000258 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000259 setABI("aapcs");
260 } else if (Triple.isWatchABI()) {
261 setABI("aapcs16");
262 } else {
263 setABI("apcs-gnu");
264 }
265 } else if (Triple.isOSWindows()) {
266 // FIXME: this is invalid for WindowsCE
267 setABI("aapcs");
268 } else {
269 // Select the default based on the platform.
270 switch (Triple.getEnvironment()) {
271 case llvm::Triple::Android:
272 case llvm::Triple::GNUEABI:
273 case llvm::Triple::GNUEABIHF:
274 case llvm::Triple::MuslEABI:
275 case llvm::Triple::MuslEABIHF:
276 setABI("aapcs-linux");
277 break;
278 case llvm::Triple::EABIHF:
279 case llvm::Triple::EABI:
280 setABI("aapcs");
281 break;
282 case llvm::Triple::GNU:
283 setABI("apcs-gnu");
284 break;
285 default:
286 if (Triple.getOS() == llvm::Triple::NetBSD)
287 setABI("apcs-gnu");
288 else if (Triple.getOS() == llvm::Triple::OpenBSD)
289 setABI("aapcs-linux");
290 else
291 setABI("aapcs");
292 break;
293 }
294 }
295
296 // ARM targets default to using the ARM C++ ABI.
297 TheCXXABI.set(TargetCXXABI::GenericARM);
298
299 // ARM has atomics up to 8 bytes
300 setAtomic();
301
302 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
303 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
304 MaxVectorAlign = 64;
305
306 // Do force alignment of members that follow zero length bitfields. If
307 // the alignment of the zero-length bitfield is greater than the member
308 // that follows it, `bar', `bar' will be aligned as the type of the
309 // zero length bitfield.
310 UseZeroLengthBitfieldAlignment = true;
311
312 if (Triple.getOS() == llvm::Triple::Linux ||
313 Triple.getOS() == llvm::Triple::UnknownOS)
314 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
315 ? "\01__gnu_mcount_nc"
316 : "\01mcount";
317}
318
319StringRef ARMTargetInfo::getABI() const { return ABI; }
320
321bool ARMTargetInfo::setABI(const std::string &Name) {
322 ABI = Name;
323
324 // The defaults (above) are for AAPCS, check if we need to change them.
325 //
326 // FIXME: We need support for -meabi... we could just mangle it into the
327 // name.
328 if (Name == "apcs-gnu" || Name == "aapcs16") {
329 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000330 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000331 }
332 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
333 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000334 return true;
335 }
336 return false;
337}
338
Tim Northoverad4c5db2017-07-24 17:06:23 +0000339// FIXME: This should be based on Arch attributes, not CPU names.
340bool ARMTargetInfo::initFeatureMap(
341 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
342 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000343
Tim Northoverad4c5db2017-07-24 17:06:23 +0000344 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000345 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000346
Tim Northoverad4c5db2017-07-24 17:06:23 +0000347 // get default FPU features
348 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
349 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000350
Tim Northoverad4c5db2017-07-24 17:06:23 +0000351 // get default Extension features
352 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
353 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000354
Tim Northoverad4c5db2017-07-24 17:06:23 +0000355 for (auto Feature : TargetFeatures)
356 if (Feature[0] == '+')
357 Features[Feature.drop_front(1)] = true;
358
359 // Enable or disable thumb-mode explicitly per function to enable mixed
360 // ARM and Thumb code generation.
361 if (isThumb())
362 Features["thumb-mode"] = true;
363 else
364 Features["thumb-mode"] = false;
365
366 // Convert user-provided arm and thumb GNU target attributes to
367 // [-|+]thumb-mode target features respectively.
368 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
369 for (auto &Feature : UpdatedFeaturesVec) {
370 if (Feature.compare("+arm") == 0)
371 Feature = "-thumb-mode";
372 else if (Feature.compare("+thumb") == 0)
373 Feature = "+thumb-mode";
374 }
375
376 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000377}
378
Erich Keaneebba5922017-07-21 22:37:03 +0000379
Tim Northoverad4c5db2017-07-24 17:06:23 +0000380bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
381 DiagnosticsEngine &Diags) {
382 FPU = 0;
383 CRC = 0;
384 Crypto = 0;
385 DSP = 0;
386 Unaligned = 1;
387 SoftFloat = SoftFloatABI = false;
388 HWDiv = 0;
389
390 // This does not diagnose illegal cases like having both
391 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
392 uint32_t HW_FP_remove = 0;
393 for (const auto &Feature : Features) {
394 if (Feature == "+soft-float") {
395 SoftFloat = true;
396 } else if (Feature == "+soft-float-abi") {
397 SoftFloatABI = true;
398 } else if (Feature == "+vfp2") {
399 FPU |= VFP2FPU;
400 HW_FP |= HW_FP_SP | HW_FP_DP;
401 } else if (Feature == "+vfp3") {
402 FPU |= VFP3FPU;
403 HW_FP |= HW_FP_SP | HW_FP_DP;
404 } else if (Feature == "+vfp4") {
405 FPU |= VFP4FPU;
406 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
407 } else if (Feature == "+fp-armv8") {
408 FPU |= FPARMV8;
409 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
410 } else if (Feature == "+neon") {
411 FPU |= NeonFPU;
412 HW_FP |= HW_FP_SP | HW_FP_DP;
413 } else if (Feature == "+hwdiv") {
414 HWDiv |= HWDivThumb;
415 } else if (Feature == "+hwdiv-arm") {
416 HWDiv |= HWDivARM;
417 } else if (Feature == "+crc") {
418 CRC = 1;
419 } else if (Feature == "+crypto") {
420 Crypto = 1;
421 } else if (Feature == "+dsp") {
422 DSP = 1;
423 } else if (Feature == "+fp-only-sp") {
424 HW_FP_remove |= HW_FP_DP;
425 } else if (Feature == "+strict-align") {
426 Unaligned = 0;
427 } else if (Feature == "+fp16") {
428 HW_FP |= HW_FP_HP;
429 }
430 }
431 HW_FP &= ~HW_FP_remove;
432
433 switch (ArchVersion) {
434 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000435 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000436 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000437 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000438 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
439 else
440 LDREX = LDREX_W;
441 break;
442 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000443 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000444 LDREX = LDREX_W | LDREX_H | LDREX_B;
445 else
446 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
447 break;
448 case 8:
449 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
450 }
451
452 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
453 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
454 return false;
455 }
456
457 if (FPMath == FP_Neon)
458 Features.push_back("+neonfp");
459 else if (FPMath == FP_VFP)
460 Features.push_back("-neonfp");
461
462 // Remove front-end specific options which the backend handles differently.
463 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
464 if (Feature != Features.end())
465 Features.erase(Feature);
466
467 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000468}
469
Erich Keaneebba5922017-07-21 22:37:03 +0000470bool ARMTargetInfo::hasFeature(StringRef Feature) const {
471 return llvm::StringSwitch<bool>(Feature)
472 .Case("arm", true)
473 .Case("aarch32", true)
474 .Case("softfloat", SoftFloat)
475 .Case("thumb", isThumb())
476 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
477 .Case("vfp", FPU && !SoftFloat)
478 .Case("hwdiv", HWDiv & HWDivThumb)
479 .Case("hwdiv-arm", HWDiv & HWDivARM)
480 .Default(false);
481}
482
Tim Northoverad4c5db2017-07-24 17:06:23 +0000483bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
484 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000485 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000486}
487
488bool ARMTargetInfo::setCPU(const std::string &Name) {
489 if (Name != "generic")
490 setArchInfo(llvm::ARM::parseCPUArch(Name));
491
Florian Hahnef5bbd62017-07-27 16:28:39 +0000492 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000493 return false;
494 setAtomic();
495 CPU = Name;
496 return true;
497}
498
499bool ARMTargetInfo::setFPMath(StringRef Name) {
500 if (Name == "neon") {
501 FPMath = FP_Neon;
502 return true;
503 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
504 Name == "vfp4") {
505 FPMath = FP_VFP;
506 return true;
507 }
508 return false;
509}
510
511void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
512 MacroBuilder &Builder) const {
513 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
514}
515
516void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
517 MacroBuilder &Builder) const {
518 // Also include the ARMv8.1-A defines
519 getTargetDefinesARMV81A(Opts, Builder);
520}
521
Erich Keaneebba5922017-07-21 22:37:03 +0000522void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
523 MacroBuilder &Builder) const {
524 // Target identification.
525 Builder.defineMacro("__arm");
526 Builder.defineMacro("__arm__");
527 // For bare-metal none-eabi.
528 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
529 (getTriple().getEnvironment() == llvm::Triple::EABI ||
530 getTriple().getEnvironment() == llvm::Triple::EABIHF))
531 Builder.defineMacro("__ELF__");
532
533 // Target properties.
534 Builder.defineMacro("__REGISTER_PREFIX__", "");
535
536 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
537 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
538 if (getTriple().isWatchABI())
539 Builder.defineMacro("__ARM_ARCH_7K__", "2");
540
541 if (!CPUAttr.empty())
542 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
543
544 // ACLE 6.4.1 ARM/Thumb instruction set architecture
545 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
546 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
547
548 if (ArchVersion >= 8) {
549 // ACLE 6.5.7 Crypto Extension
550 if (Crypto)
551 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
552 // ACLE 6.5.8 CRC32 Extension
553 if (CRC)
554 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
555 // ACLE 6.5.10 Numeric Maximum and Minimum
556 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
557 // ACLE 6.5.9 Directed Rounding
558 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
559 }
560
561 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
562 // is not defined for the M-profile.
563 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000564 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000565 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
566
567 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
568 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
569 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
570 // v7 and v8 architectures excluding v8-M Baseline.
571 if (supportsThumb2())
572 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
573 else if (supportsThumb())
574 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
575
576 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
577 // instruction set such as ARM or Thumb.
578 Builder.defineMacro("__ARM_32BIT_STATE", "1");
579
580 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
581
582 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
583 if (!CPUProfile.empty())
584 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
585
586 // ACLE 6.4.3 Unaligned access supported in hardware
587 if (Unaligned)
588 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
589
590 // ACLE 6.4.4 LDREX/STREX
591 if (LDREX)
592 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + llvm::utohexstr(LDREX));
593
594 // ACLE 6.4.5 CLZ
595 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
596 ArchVersion > 6)
597 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
598
599 // ACLE 6.5.1 Hardware Floating Point
600 if (HW_FP)
601 Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
602
603 // ACLE predefines.
604 Builder.defineMacro("__ARM_ACLE", "200");
605
606 // FP16 support (we currently only support IEEE format).
607 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
608 Builder.defineMacro("__ARM_FP16_ARGS", "1");
609
610 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
611 if (ArchVersion >= 7 && (FPU & VFP4FPU))
612 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
613
614 // Subtarget options.
615
616 // FIXME: It's more complicated than this and we don't really support
617 // interworking.
618 // Windows on ARM does not "support" interworking
619 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
620 Builder.defineMacro("__THUMB_INTERWORK__");
621
622 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
623 // Embedded targets on Darwin follow AAPCS, but not EABI.
624 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
625 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
626 Builder.defineMacro("__ARM_EABI__");
627 Builder.defineMacro("__ARM_PCS", "1");
628 }
629
630 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
631 Builder.defineMacro("__ARM_PCS_VFP", "1");
632
633 if (SoftFloat)
634 Builder.defineMacro("__SOFTFP__");
635
Florian Hahnef5bbd62017-07-27 16:28:39 +0000636 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000637 Builder.defineMacro("__XSCALE__");
638
639 if (isThumb()) {
640 Builder.defineMacro("__THUMBEL__");
641 Builder.defineMacro("__thumb__");
642 if (supportsThumb2())
643 Builder.defineMacro("__thumb2__");
644 }
645
646 // ACLE 6.4.9 32-bit SIMD instructions
647 if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
648 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
649
650 // ACLE 6.4.10 Hardware Integer Divide
651 if (((HWDiv & HWDivThumb) && isThumb()) ||
652 ((HWDiv & HWDivARM) && !isThumb())) {
653 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
654 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
655 }
656
657 // Note, this is always on in gcc, even though it doesn't make sense.
658 Builder.defineMacro("__APCS_32__");
659
660 if (FPUModeIsVFP((FPUMode)FPU)) {
661 Builder.defineMacro("__VFP_FP__");
662 if (FPU & VFP2FPU)
663 Builder.defineMacro("__ARM_VFPV2__");
664 if (FPU & VFP3FPU)
665 Builder.defineMacro("__ARM_VFPV3__");
666 if (FPU & VFP4FPU)
667 Builder.defineMacro("__ARM_VFPV4__");
668 if (FPU & FPARMV8)
669 Builder.defineMacro("__ARM_FPV5__");
670 }
671
672 // This only gets set when Neon instructions are actually available, unlike
673 // the VFP define, hence the soft float and arch check. This is subtly
674 // different from gcc, we follow the intent which was that it should be set
675 // when Neon instructions are actually available.
676 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
677 Builder.defineMacro("__ARM_NEON", "1");
678 Builder.defineMacro("__ARM_NEON__");
679 // current AArch32 NEON implementations do not support double-precision
680 // floating-point even when it is present in VFP.
681 Builder.defineMacro("__ARM_NEON_FP",
682 "0x" + llvm::utohexstr(HW_FP & ~HW_FP_DP));
683 }
684
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000685 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
686 llvm::utostr(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000687
688 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
689
690 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
691 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
692 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
693 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
694 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
695 }
696
697 // ACLE 6.4.7 DSP instructions
698 if (DSP) {
699 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
700 }
701
702 // ACLE 6.4.8 Saturation instructions
703 bool SAT = false;
704 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
705 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
706 SAT = true;
707 }
708
709 // ACLE 6.4.6 Q (saturation) flag
710 if (DSP || SAT)
711 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
712
713 if (Opts.UnsafeFPMath)
714 Builder.defineMacro("__ARM_FP_FAST", "1");
715
716 switch (ArchKind) {
717 default:
718 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000719 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000720 getTargetDefinesARMV81A(Opts, Builder);
721 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000722 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000723 getTargetDefinesARMV82A(Opts, Builder);
724 break;
725 }
726}
727
Tim Northoverad4c5db2017-07-24 17:06:23 +0000728const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
729#define BUILTIN(ID, TYPE, ATTRS) \
730 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
731#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
732 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
733#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000734
Tim Northoverad4c5db2017-07-24 17:06:23 +0000735#define BUILTIN(ID, TYPE, ATTRS) \
736 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
737#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
738 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
739#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
740 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
741#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
742 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
743#include "clang/Basic/BuiltinsARM.def"
744};
745
746ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
747 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
748 Builtin::FirstTSBuiltin);
749}
750
751bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
752TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
753 return IsAAPCS
754 ? AAPCSABIBuiltinVaList
755 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
756 : TargetInfo::VoidPtrBuiltinVaList);
757}
758
759const char *const ARMTargetInfo::GCCRegNames[] = {
760 // Integer registers
761 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
762 "r12", "sp", "lr", "pc",
763
764 // Float registers
765 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
766 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
767 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
768
769 // Double registers
770 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
771 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
772 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
773
774 // Quad registers
775 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
776 "q12", "q13", "q14", "q15"};
777
778ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
779 return llvm::makeArrayRef(GCCRegNames);
780}
781
782const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
783 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
784 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
785 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
786 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
787 // The S, D and Q registers overlap, but aren't really aliases; we
788 // don't want to substitute one of these for a different-sized one.
789};
790
791ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
792 return llvm::makeArrayRef(GCCRegAliases);
793}
794
795bool ARMTargetInfo::validateAsmConstraint(
796 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
797 switch (*Name) {
798 default:
799 break;
800 case 'l': // r0-r7
801 case 'h': // r8-r15
802 case 't': // VFP Floating point register single precision
803 case 'w': // VFP Floating point register double precision
804 Info.setAllowsRegister();
805 return true;
806 case 'I':
807 case 'J':
808 case 'K':
809 case 'L':
810 case 'M':
811 // FIXME
812 return true;
813 case 'Q': // A memory address that is a single base register.
814 Info.setAllowsMemory();
815 return true;
816 case 'U': // a memory reference...
817 switch (Name[1]) {
818 case 'q': // ...ARMV4 ldrsb
819 case 'v': // ...VFP load/store (reg+constant offset)
820 case 'y': // ...iWMMXt load/store
821 case 't': // address valid for load/store opaque types wider
822 // than 128-bits
823 case 'n': // valid address for Neon doubleword vector load/store
824 case 'm': // valid address for Neon element and structure load/store
825 case 's': // valid address for non-offset loads/stores of quad-word
826 // values in four ARM registers
827 Info.setAllowsMemory();
828 Name++;
829 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000830 }
831 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000832 return false;
833}
Erich Keaneebba5922017-07-21 22:37:03 +0000834
Tim Northoverad4c5db2017-07-24 17:06:23 +0000835std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
836 std::string R;
837 switch (*Constraint) {
838 case 'U': // Two-character constraint; add "^" hint for later parsing.
839 R = std::string("^") + std::string(Constraint, 2);
840 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000841 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000842 case 'p': // 'p' should be translated to 'r' by default.
843 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000844 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000845 default:
846 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000847 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000848 return R;
849}
Erich Keaneebba5922017-07-21 22:37:03 +0000850
Tim Northoverad4c5db2017-07-24 17:06:23 +0000851bool ARMTargetInfo::validateConstraintModifier(
852 StringRef Constraint, char Modifier, unsigned Size,
853 std::string &SuggestedModifier) const {
854 bool isOutput = (Constraint[0] == '=');
855 bool isInOut = (Constraint[0] == '+');
856
857 // Strip off constraint modifiers.
858 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
859 Constraint = Constraint.substr(1);
860
861 switch (Constraint[0]) {
862 default:
863 break;
864 case 'r': {
865 switch (Modifier) {
866 default:
867 return (isInOut || isOutput || Size <= 64);
868 case 'q':
869 // A register of size 32 cannot fit a vector type.
870 return false;
871 }
Erich Keaneebba5922017-07-21 22:37:03 +0000872 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000873 }
Erich Keaneebba5922017-07-21 22:37:03 +0000874
875 return true;
876}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000877const char *ARMTargetInfo::getClobbers() const {
878 // FIXME: Is this really right?
879 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000880}
881
Tim Northoverad4c5db2017-07-24 17:06:23 +0000882TargetInfo::CallingConvCheckResult
883ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
884 switch (CC) {
885 case CC_AAPCS:
886 case CC_AAPCS_VFP:
887 case CC_Swift:
888 case CC_OpenCLKernel:
889 return CCCR_OK;
890 default:
891 return CCCR_Warning;
892 }
893}
894
895int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
896 if (RegNo == 0)
897 return 0;
898 if (RegNo == 1)
899 return 1;
900 return -1;
901}
902
903bool ARMTargetInfo::hasSjLjLowering() const { return true; }
904
905ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
906 const TargetOptions &Opts)
907 : ARMTargetInfo(Triple, Opts) {}
908
Erich Keaneebba5922017-07-21 22:37:03 +0000909void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
910 MacroBuilder &Builder) const {
911 Builder.defineMacro("__ARMEL__");
912 ARMTargetInfo::getTargetDefines(Opts, Builder);
913}
914
Tim Northoverad4c5db2017-07-24 17:06:23 +0000915ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
916 const TargetOptions &Opts)
917 : ARMTargetInfo(Triple, Opts) {}
918
Erich Keaneebba5922017-07-21 22:37:03 +0000919void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
920 MacroBuilder &Builder) const {
921 Builder.defineMacro("__ARMEB__");
922 Builder.defineMacro("__ARM_BIG_ENDIAN");
923 ARMTargetInfo::getTargetDefines(Opts, Builder);
924}
925
Tim Northoverad4c5db2017-07-24 17:06:23 +0000926WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
927 const TargetOptions &Opts)
928 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000929 SizeType = UnsignedInt;
930}
931
Erich Keaneebba5922017-07-21 22:37:03 +0000932void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
933 MacroBuilder &Builder) const {
934 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
935
936 // FIXME: this is invalid for WindowsCE
937 Builder.defineMacro("_M_ARM_NT", "1");
938 Builder.defineMacro("_M_ARMT", "_M_ARM");
939 Builder.defineMacro("_M_THUMB", "_M_ARM");
940
941 assert((Triple.getArch() == llvm::Triple::arm ||
942 Triple.getArch() == llvm::Triple::thumb) &&
943 "invalid architecture for Windows ARM target info");
944 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
945 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
946
947 // TODO map the complete set of values
948 // 31: VFPv3 40: VFPv4
949 Builder.defineMacro("_M_ARM_FP", "31");
950}
951
Tim Northoverad4c5db2017-07-24 17:06:23 +0000952TargetInfo::BuiltinVaListKind
953WindowsARMTargetInfo::getBuiltinVaListKind() const {
954 return TargetInfo::CharPtrBuiltinVaList;
955}
956
957TargetInfo::CallingConvCheckResult
958WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
959 switch (CC) {
960 case CC_X86StdCall:
961 case CC_X86ThisCall:
962 case CC_X86FastCall:
963 case CC_X86VectorCall:
964 return CCCR_Ignore;
965 case CC_C:
966 case CC_OpenCLKernel:
967 return CCCR_OK;
968 default:
969 return CCCR_Warning;
970 }
971}
972
973// Windows ARM + Itanium C++ ABI Target
974ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
975 const llvm::Triple &Triple, const TargetOptions &Opts)
976 : WindowsARMTargetInfo(Triple, Opts) {
977 TheCXXABI.set(TargetCXXABI::GenericARM);
978}
979
980void ItaniumWindowsARMleTargetInfo::getTargetDefines(
981 const LangOptions &Opts, MacroBuilder &Builder) const {
982 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
983
984 if (Opts.MSVCCompat)
985 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
986}
987
988// Windows ARM, MS (C++) ABI
989MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
990 const TargetOptions &Opts)
991 : WindowsARMTargetInfo(Triple, Opts) {
992 TheCXXABI.set(TargetCXXABI::Microsoft);
993}
994
995void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
996 MacroBuilder &Builder) const {
997 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
998 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
999}
1000
1001MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1002 const TargetOptions &Opts)
1003 : WindowsARMTargetInfo(Triple, Opts) {
1004 TheCXXABI.set(TargetCXXABI::GenericARM);
1005}
1006
Erich Keaneebba5922017-07-21 22:37:03 +00001007void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1008 MacroBuilder &Builder) const {
1009 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1010 DefineStd(Builder, "WIN32", Opts);
1011 DefineStd(Builder, "WINNT", Opts);
1012 Builder.defineMacro("_ARM_");
1013 addMinGWDefines(Opts, Builder);
1014}
1015
Tim Northoverad4c5db2017-07-24 17:06:23 +00001016CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1017 const TargetOptions &Opts)
1018 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001019 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001020 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001021 DoubleAlign = LongLongAlign = 64;
1022 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1023}
1024
Erich Keaneebba5922017-07-21 22:37:03 +00001025void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1026 MacroBuilder &Builder) const {
1027 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1028 Builder.defineMacro("_ARM_");
1029 Builder.defineMacro("__CYGWIN__");
1030 Builder.defineMacro("__CYGWIN32__");
1031 DefineStd(Builder, "unix", Opts);
1032 if (Opts.CPlusPlus)
1033 Builder.defineMacro("_GNU_SOURCE");
1034}
1035
Tim Northoverad4c5db2017-07-24 17:06:23 +00001036DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1037 const TargetOptions &Opts)
1038 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1039 HasAlignMac68kSupport = true;
1040 // iOS always has 64-bit atomic instructions.
1041 // FIXME: This should be based off of the target features in
1042 // ARMleTargetInfo.
1043 MaxAtomicInlineWidth = 64;
1044
1045 if (Triple.isWatchABI()) {
1046 // Darwin on iOS uses a variant of the ARM C++ ABI.
1047 TheCXXABI.set(TargetCXXABI::WatchOS);
1048
1049 // The 32-bit ABI is silent on what ptrdiff_t should be, but given that
1050 // size_t is long, it's a bit weird for it to be int.
1051 PtrDiffType = SignedLong;
1052
1053 // BOOL should be a real boolean on the new ABI
1054 UseSignedCharForObjCBool = false;
1055 } else
1056 TheCXXABI.set(TargetCXXABI::iOS);
1057}
1058
1059void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1060 const llvm::Triple &Triple,
1061 MacroBuilder &Builder) const {
1062 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1063}
1064
1065RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1066 const TargetOptions &Opts)
1067 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1068 Triple.getOSName(),
1069 Triple.getEnvironmentName()),
1070 Opts) {
1071 IsRenderScriptTarget = true;
1072 LongWidth = LongAlign = 64;
1073}
1074
Erich Keaneebba5922017-07-21 22:37:03 +00001075void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1076 MacroBuilder &Builder) const {
1077 Builder.defineMacro("__RENDERSCRIPT__");
1078 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1079}