blob: 1b236dd22084115c14010e2e0619ccd11fdcb05a [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 Abdulrasoole5696582017-10-20 04:11:28 +0000239 bool IsOpenBSD = Triple.getOS() == llvm::Triple::OpenBSD;
240 bool IsNetBSD = Triple.getOS() == llvm::Triple::NetBSD;
241 IntPtrType =
242 (Triple.isOSDarwin() || IsOpenBSD || IsNetBSD) ? SignedLong : SignedInt;
Saleem Abdulrasool8d799f82017-10-18 00:00:50 +0000243
Tim Northoverad4c5db2017-07-24 17:06:23 +0000244 // Cache arch related info.
245 setArchInfo();
246
247 // {} in inline assembly are neon specifiers, not assembly variant
248 // specifiers.
249 NoAsmVariants = true;
250
251 // FIXME: This duplicates code from the driver that sets the -target-abi
252 // option - this code is used if -target-abi isn't passed and should
253 // be unified in some way.
254 if (Triple.isOSBinFormatMachO()) {
255 // The backend is hardwired to assume AAPCS for M-class processors, ensure
256 // the frontend matches that.
257 if (Triple.getEnvironment() == llvm::Triple::EABI ||
258 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000259 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000260 setABI("aapcs");
261 } else if (Triple.isWatchABI()) {
262 setABI("aapcs16");
263 } else {
264 setABI("apcs-gnu");
265 }
266 } else if (Triple.isOSWindows()) {
267 // FIXME: this is invalid for WindowsCE
268 setABI("aapcs");
269 } else {
270 // Select the default based on the platform.
271 switch (Triple.getEnvironment()) {
272 case llvm::Triple::Android:
273 case llvm::Triple::GNUEABI:
274 case llvm::Triple::GNUEABIHF:
275 case llvm::Triple::MuslEABI:
276 case llvm::Triple::MuslEABIHF:
277 setABI("aapcs-linux");
278 break;
279 case llvm::Triple::EABIHF:
280 case llvm::Triple::EABI:
281 setABI("aapcs");
282 break;
283 case llvm::Triple::GNU:
284 setABI("apcs-gnu");
285 break;
286 default:
287 if (Triple.getOS() == llvm::Triple::NetBSD)
288 setABI("apcs-gnu");
289 else if (Triple.getOS() == llvm::Triple::OpenBSD)
290 setABI("aapcs-linux");
291 else
292 setABI("aapcs");
293 break;
294 }
295 }
296
297 // ARM targets default to using the ARM C++ ABI.
298 TheCXXABI.set(TargetCXXABI::GenericARM);
299
300 // ARM has atomics up to 8 bytes
301 setAtomic();
302
303 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
304 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
305 MaxVectorAlign = 64;
306
307 // Do force alignment of members that follow zero length bitfields. If
308 // the alignment of the zero-length bitfield is greater than the member
309 // that follows it, `bar', `bar' will be aligned as the type of the
310 // zero length bitfield.
311 UseZeroLengthBitfieldAlignment = true;
312
313 if (Triple.getOS() == llvm::Triple::Linux ||
314 Triple.getOS() == llvm::Triple::UnknownOS)
315 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
316 ? "\01__gnu_mcount_nc"
317 : "\01mcount";
318}
319
320StringRef ARMTargetInfo::getABI() const { return ABI; }
321
322bool ARMTargetInfo::setABI(const std::string &Name) {
323 ABI = Name;
324
325 // The defaults (above) are for AAPCS, check if we need to change them.
326 //
327 // FIXME: We need support for -meabi... we could just mangle it into the
328 // name.
329 if (Name == "apcs-gnu" || Name == "aapcs16") {
330 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000331 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000332 }
333 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
334 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000335 return true;
336 }
337 return false;
338}
339
Tim Northoverad4c5db2017-07-24 17:06:23 +0000340// FIXME: This should be based on Arch attributes, not CPU names.
341bool ARMTargetInfo::initFeatureMap(
342 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
343 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000344
Tim Northoverad4c5db2017-07-24 17:06:23 +0000345 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000346 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000347
Tim Northoverad4c5db2017-07-24 17:06:23 +0000348 // get default FPU features
349 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
350 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000351
Tim Northoverad4c5db2017-07-24 17:06:23 +0000352 // get default Extension features
353 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
354 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000355
Tim Northoverad4c5db2017-07-24 17:06:23 +0000356 for (auto Feature : TargetFeatures)
357 if (Feature[0] == '+')
358 Features[Feature.drop_front(1)] = true;
359
360 // Enable or disable thumb-mode explicitly per function to enable mixed
361 // ARM and Thumb code generation.
362 if (isThumb())
363 Features["thumb-mode"] = true;
364 else
365 Features["thumb-mode"] = false;
366
367 // Convert user-provided arm and thumb GNU target attributes to
368 // [-|+]thumb-mode target features respectively.
369 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
370 for (auto &Feature : UpdatedFeaturesVec) {
371 if (Feature.compare("+arm") == 0)
372 Feature = "-thumb-mode";
373 else if (Feature.compare("+thumb") == 0)
374 Feature = "+thumb-mode";
375 }
376
377 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000378}
379
Erich Keaneebba5922017-07-21 22:37:03 +0000380
Tim Northoverad4c5db2017-07-24 17:06:23 +0000381bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
382 DiagnosticsEngine &Diags) {
383 FPU = 0;
384 CRC = 0;
385 Crypto = 0;
386 DSP = 0;
387 Unaligned = 1;
388 SoftFloat = SoftFloatABI = false;
389 HWDiv = 0;
390
391 // This does not diagnose illegal cases like having both
392 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
393 uint32_t HW_FP_remove = 0;
394 for (const auto &Feature : Features) {
395 if (Feature == "+soft-float") {
396 SoftFloat = true;
397 } else if (Feature == "+soft-float-abi") {
398 SoftFloatABI = true;
399 } else if (Feature == "+vfp2") {
400 FPU |= VFP2FPU;
401 HW_FP |= HW_FP_SP | HW_FP_DP;
402 } else if (Feature == "+vfp3") {
403 FPU |= VFP3FPU;
404 HW_FP |= HW_FP_SP | HW_FP_DP;
405 } else if (Feature == "+vfp4") {
406 FPU |= VFP4FPU;
407 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
408 } else if (Feature == "+fp-armv8") {
409 FPU |= FPARMV8;
410 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
411 } else if (Feature == "+neon") {
412 FPU |= NeonFPU;
413 HW_FP |= HW_FP_SP | HW_FP_DP;
414 } else if (Feature == "+hwdiv") {
415 HWDiv |= HWDivThumb;
416 } else if (Feature == "+hwdiv-arm") {
417 HWDiv |= HWDivARM;
418 } else if (Feature == "+crc") {
419 CRC = 1;
420 } else if (Feature == "+crypto") {
421 Crypto = 1;
422 } else if (Feature == "+dsp") {
423 DSP = 1;
424 } else if (Feature == "+fp-only-sp") {
425 HW_FP_remove |= HW_FP_DP;
426 } else if (Feature == "+strict-align") {
427 Unaligned = 0;
428 } else if (Feature == "+fp16") {
429 HW_FP |= HW_FP_HP;
430 }
431 }
432 HW_FP &= ~HW_FP_remove;
433
434 switch (ArchVersion) {
435 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000436 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000437 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000438 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000439 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
440 else
441 LDREX = LDREX_W;
442 break;
443 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000444 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000445 LDREX = LDREX_W | LDREX_H | LDREX_B;
446 else
447 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
448 break;
449 case 8:
450 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
451 }
452
453 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
454 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
455 return false;
456 }
457
458 if (FPMath == FP_Neon)
459 Features.push_back("+neonfp");
460 else if (FPMath == FP_VFP)
461 Features.push_back("-neonfp");
462
463 // Remove front-end specific options which the backend handles differently.
464 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
465 if (Feature != Features.end())
466 Features.erase(Feature);
467
468 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000469}
470
Erich Keaneebba5922017-07-21 22:37:03 +0000471bool ARMTargetInfo::hasFeature(StringRef Feature) const {
472 return llvm::StringSwitch<bool>(Feature)
473 .Case("arm", true)
474 .Case("aarch32", true)
475 .Case("softfloat", SoftFloat)
476 .Case("thumb", isThumb())
477 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
478 .Case("vfp", FPU && !SoftFloat)
479 .Case("hwdiv", HWDiv & HWDivThumb)
480 .Case("hwdiv-arm", HWDiv & HWDivARM)
481 .Default(false);
482}
483
Tim Northoverad4c5db2017-07-24 17:06:23 +0000484bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
485 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000486 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000487}
488
489bool ARMTargetInfo::setCPU(const std::string &Name) {
490 if (Name != "generic")
491 setArchInfo(llvm::ARM::parseCPUArch(Name));
492
Florian Hahnef5bbd62017-07-27 16:28:39 +0000493 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000494 return false;
495 setAtomic();
496 CPU = Name;
497 return true;
498}
499
500bool ARMTargetInfo::setFPMath(StringRef Name) {
501 if (Name == "neon") {
502 FPMath = FP_Neon;
503 return true;
504 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
505 Name == "vfp4") {
506 FPMath = FP_VFP;
507 return true;
508 }
509 return false;
510}
511
512void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
513 MacroBuilder &Builder) const {
514 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
515}
516
517void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
518 MacroBuilder &Builder) const {
519 // Also include the ARMv8.1-A defines
520 getTargetDefinesARMV81A(Opts, Builder);
521}
522
Erich Keaneebba5922017-07-21 22:37:03 +0000523void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
524 MacroBuilder &Builder) const {
525 // Target identification.
526 Builder.defineMacro("__arm");
527 Builder.defineMacro("__arm__");
528 // For bare-metal none-eabi.
529 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
530 (getTriple().getEnvironment() == llvm::Triple::EABI ||
531 getTriple().getEnvironment() == llvm::Triple::EABIHF))
532 Builder.defineMacro("__ELF__");
533
534 // Target properties.
535 Builder.defineMacro("__REGISTER_PREFIX__", "");
536
537 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
538 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
539 if (getTriple().isWatchABI())
540 Builder.defineMacro("__ARM_ARCH_7K__", "2");
541
542 if (!CPUAttr.empty())
543 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
544
545 // ACLE 6.4.1 ARM/Thumb instruction set architecture
546 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
547 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
548
549 if (ArchVersion >= 8) {
550 // ACLE 6.5.7 Crypto Extension
551 if (Crypto)
552 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
553 // ACLE 6.5.8 CRC32 Extension
554 if (CRC)
555 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
556 // ACLE 6.5.10 Numeric Maximum and Minimum
557 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
558 // ACLE 6.5.9 Directed Rounding
559 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
560 }
561
562 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
563 // is not defined for the M-profile.
564 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000565 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000566 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
567
568 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
569 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
570 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
571 // v7 and v8 architectures excluding v8-M Baseline.
572 if (supportsThumb2())
573 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
574 else if (supportsThumb())
575 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
576
577 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
578 // instruction set such as ARM or Thumb.
579 Builder.defineMacro("__ARM_32BIT_STATE", "1");
580
581 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
582
583 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
584 if (!CPUProfile.empty())
585 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
586
587 // ACLE 6.4.3 Unaligned access supported in hardware
588 if (Unaligned)
589 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
590
591 // ACLE 6.4.4 LDREX/STREX
592 if (LDREX)
593 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + llvm::utohexstr(LDREX));
594
595 // ACLE 6.4.5 CLZ
596 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
597 ArchVersion > 6)
598 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
599
600 // ACLE 6.5.1 Hardware Floating Point
601 if (HW_FP)
602 Builder.defineMacro("__ARM_FP", "0x" + llvm::utohexstr(HW_FP));
603
604 // ACLE predefines.
605 Builder.defineMacro("__ARM_ACLE", "200");
606
607 // FP16 support (we currently only support IEEE format).
608 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
609 Builder.defineMacro("__ARM_FP16_ARGS", "1");
610
611 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
612 if (ArchVersion >= 7 && (FPU & VFP4FPU))
613 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
614
615 // Subtarget options.
616
617 // FIXME: It's more complicated than this and we don't really support
618 // interworking.
619 // Windows on ARM does not "support" interworking
620 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
621 Builder.defineMacro("__THUMB_INTERWORK__");
622
623 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
624 // Embedded targets on Darwin follow AAPCS, but not EABI.
625 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
626 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
627 Builder.defineMacro("__ARM_EABI__");
628 Builder.defineMacro("__ARM_PCS", "1");
629 }
630
631 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
632 Builder.defineMacro("__ARM_PCS_VFP", "1");
633
634 if (SoftFloat)
635 Builder.defineMacro("__SOFTFP__");
636
Florian Hahnef5bbd62017-07-27 16:28:39 +0000637 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000638 Builder.defineMacro("__XSCALE__");
639
640 if (isThumb()) {
641 Builder.defineMacro("__THUMBEL__");
642 Builder.defineMacro("__thumb__");
643 if (supportsThumb2())
644 Builder.defineMacro("__thumb2__");
645 }
646
647 // ACLE 6.4.9 32-bit SIMD instructions
648 if (ArchVersion >= 6 && (CPUProfile != "M" || CPUAttr == "7EM"))
649 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
650
651 // ACLE 6.4.10 Hardware Integer Divide
652 if (((HWDiv & HWDivThumb) && isThumb()) ||
653 ((HWDiv & HWDivARM) && !isThumb())) {
654 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
655 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
656 }
657
658 // Note, this is always on in gcc, even though it doesn't make sense.
659 Builder.defineMacro("__APCS_32__");
660
661 if (FPUModeIsVFP((FPUMode)FPU)) {
662 Builder.defineMacro("__VFP_FP__");
663 if (FPU & VFP2FPU)
664 Builder.defineMacro("__ARM_VFPV2__");
665 if (FPU & VFP3FPU)
666 Builder.defineMacro("__ARM_VFPV3__");
667 if (FPU & VFP4FPU)
668 Builder.defineMacro("__ARM_VFPV4__");
669 if (FPU & FPARMV8)
670 Builder.defineMacro("__ARM_FPV5__");
671 }
672
673 // This only gets set when Neon instructions are actually available, unlike
674 // the VFP define, hence the soft float and arch check. This is subtly
675 // different from gcc, we follow the intent which was that it should be set
676 // when Neon instructions are actually available.
677 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
678 Builder.defineMacro("__ARM_NEON", "1");
679 Builder.defineMacro("__ARM_NEON__");
680 // current AArch32 NEON implementations do not support double-precision
681 // floating-point even when it is present in VFP.
682 Builder.defineMacro("__ARM_NEON_FP",
683 "0x" + llvm::utohexstr(HW_FP & ~HW_FP_DP));
684 }
685
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000686 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
687 llvm::utostr(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000688
689 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
690
691 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
692 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
693 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
694 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
695 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
696 }
697
698 // ACLE 6.4.7 DSP instructions
699 if (DSP) {
700 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
701 }
702
703 // ACLE 6.4.8 Saturation instructions
704 bool SAT = false;
705 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
706 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
707 SAT = true;
708 }
709
710 // ACLE 6.4.6 Q (saturation) flag
711 if (DSP || SAT)
712 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
713
714 if (Opts.UnsafeFPMath)
715 Builder.defineMacro("__ARM_FP_FAST", "1");
716
717 switch (ArchKind) {
718 default:
719 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000720 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000721 getTargetDefinesARMV81A(Opts, Builder);
722 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000723 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000724 getTargetDefinesARMV82A(Opts, Builder);
725 break;
726 }
727}
728
Tim Northoverad4c5db2017-07-24 17:06:23 +0000729const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
730#define BUILTIN(ID, TYPE, ATTRS) \
731 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
732#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
733 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
734#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000735
Tim Northoverad4c5db2017-07-24 17:06:23 +0000736#define BUILTIN(ID, TYPE, ATTRS) \
737 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
738#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
739 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
740#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
741 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
742#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
743 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
744#include "clang/Basic/BuiltinsARM.def"
745};
746
747ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
748 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
749 Builtin::FirstTSBuiltin);
750}
751
752bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
753TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
754 return IsAAPCS
755 ? AAPCSABIBuiltinVaList
756 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
757 : TargetInfo::VoidPtrBuiltinVaList);
758}
759
760const char *const ARMTargetInfo::GCCRegNames[] = {
761 // Integer registers
762 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
763 "r12", "sp", "lr", "pc",
764
765 // Float registers
766 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
767 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
768 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
769
770 // Double registers
771 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
772 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
773 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
774
775 // Quad registers
776 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
777 "q12", "q13", "q14", "q15"};
778
779ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
780 return llvm::makeArrayRef(GCCRegNames);
781}
782
783const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
784 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
785 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
786 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
787 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
788 // The S, D and Q registers overlap, but aren't really aliases; we
789 // don't want to substitute one of these for a different-sized one.
790};
791
792ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
793 return llvm::makeArrayRef(GCCRegAliases);
794}
795
796bool ARMTargetInfo::validateAsmConstraint(
797 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
798 switch (*Name) {
799 default:
800 break;
801 case 'l': // r0-r7
802 case 'h': // r8-r15
803 case 't': // VFP Floating point register single precision
804 case 'w': // VFP Floating point register double precision
805 Info.setAllowsRegister();
806 return true;
807 case 'I':
808 case 'J':
809 case 'K':
810 case 'L':
811 case 'M':
812 // FIXME
813 return true;
814 case 'Q': // A memory address that is a single base register.
815 Info.setAllowsMemory();
816 return true;
817 case 'U': // a memory reference...
818 switch (Name[1]) {
819 case 'q': // ...ARMV4 ldrsb
820 case 'v': // ...VFP load/store (reg+constant offset)
821 case 'y': // ...iWMMXt load/store
822 case 't': // address valid for load/store opaque types wider
823 // than 128-bits
824 case 'n': // valid address for Neon doubleword vector load/store
825 case 'm': // valid address for Neon element and structure load/store
826 case 's': // valid address for non-offset loads/stores of quad-word
827 // values in four ARM registers
828 Info.setAllowsMemory();
829 Name++;
830 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000831 }
832 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000833 return false;
834}
Erich Keaneebba5922017-07-21 22:37:03 +0000835
Tim Northoverad4c5db2017-07-24 17:06:23 +0000836std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
837 std::string R;
838 switch (*Constraint) {
839 case 'U': // Two-character constraint; add "^" hint for later parsing.
840 R = std::string("^") + std::string(Constraint, 2);
841 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000842 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000843 case 'p': // 'p' should be translated to 'r' by default.
844 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000845 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000846 default:
847 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000848 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000849 return R;
850}
Erich Keaneebba5922017-07-21 22:37:03 +0000851
Tim Northoverad4c5db2017-07-24 17:06:23 +0000852bool ARMTargetInfo::validateConstraintModifier(
853 StringRef Constraint, char Modifier, unsigned Size,
854 std::string &SuggestedModifier) const {
855 bool isOutput = (Constraint[0] == '=');
856 bool isInOut = (Constraint[0] == '+');
857
858 // Strip off constraint modifiers.
859 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
860 Constraint = Constraint.substr(1);
861
862 switch (Constraint[0]) {
863 default:
864 break;
865 case 'r': {
866 switch (Modifier) {
867 default:
868 return (isInOut || isOutput || Size <= 64);
869 case 'q':
870 // A register of size 32 cannot fit a vector type.
871 return false;
872 }
Erich Keaneebba5922017-07-21 22:37:03 +0000873 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000874 }
Erich Keaneebba5922017-07-21 22:37:03 +0000875
876 return true;
877}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000878const char *ARMTargetInfo::getClobbers() const {
879 // FIXME: Is this really right?
880 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000881}
882
Tim Northoverad4c5db2017-07-24 17:06:23 +0000883TargetInfo::CallingConvCheckResult
884ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
885 switch (CC) {
886 case CC_AAPCS:
887 case CC_AAPCS_VFP:
888 case CC_Swift:
889 case CC_OpenCLKernel:
890 return CCCR_OK;
891 default:
892 return CCCR_Warning;
893 }
894}
895
896int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
897 if (RegNo == 0)
898 return 0;
899 if (RegNo == 1)
900 return 1;
901 return -1;
902}
903
904bool ARMTargetInfo::hasSjLjLowering() const { return true; }
905
906ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
907 const TargetOptions &Opts)
908 : ARMTargetInfo(Triple, Opts) {}
909
Erich Keaneebba5922017-07-21 22:37:03 +0000910void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
911 MacroBuilder &Builder) const {
912 Builder.defineMacro("__ARMEL__");
913 ARMTargetInfo::getTargetDefines(Opts, Builder);
914}
915
Tim Northoverad4c5db2017-07-24 17:06:23 +0000916ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
917 const TargetOptions &Opts)
918 : ARMTargetInfo(Triple, Opts) {}
919
Erich Keaneebba5922017-07-21 22:37:03 +0000920void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
921 MacroBuilder &Builder) const {
922 Builder.defineMacro("__ARMEB__");
923 Builder.defineMacro("__ARM_BIG_ENDIAN");
924 ARMTargetInfo::getTargetDefines(Opts, Builder);
925}
926
Tim Northoverad4c5db2017-07-24 17:06:23 +0000927WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
928 const TargetOptions &Opts)
929 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000930 SizeType = UnsignedInt;
931}
932
Erich Keaneebba5922017-07-21 22:37:03 +0000933void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
934 MacroBuilder &Builder) const {
935 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
936
937 // FIXME: this is invalid for WindowsCE
938 Builder.defineMacro("_M_ARM_NT", "1");
939 Builder.defineMacro("_M_ARMT", "_M_ARM");
940 Builder.defineMacro("_M_THUMB", "_M_ARM");
941
942 assert((Triple.getArch() == llvm::Triple::arm ||
943 Triple.getArch() == llvm::Triple::thumb) &&
944 "invalid architecture for Windows ARM target info");
945 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
946 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
947
948 // TODO map the complete set of values
949 // 31: VFPv3 40: VFPv4
950 Builder.defineMacro("_M_ARM_FP", "31");
951}
952
Tim Northoverad4c5db2017-07-24 17:06:23 +0000953TargetInfo::BuiltinVaListKind
954WindowsARMTargetInfo::getBuiltinVaListKind() const {
955 return TargetInfo::CharPtrBuiltinVaList;
956}
957
958TargetInfo::CallingConvCheckResult
959WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
960 switch (CC) {
961 case CC_X86StdCall:
962 case CC_X86ThisCall:
963 case CC_X86FastCall:
964 case CC_X86VectorCall:
965 return CCCR_Ignore;
966 case CC_C:
967 case CC_OpenCLKernel:
968 return CCCR_OK;
969 default:
970 return CCCR_Warning;
971 }
972}
973
974// Windows ARM + Itanium C++ ABI Target
975ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
976 const llvm::Triple &Triple, const TargetOptions &Opts)
977 : WindowsARMTargetInfo(Triple, Opts) {
978 TheCXXABI.set(TargetCXXABI::GenericARM);
979}
980
981void ItaniumWindowsARMleTargetInfo::getTargetDefines(
982 const LangOptions &Opts, MacroBuilder &Builder) const {
983 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
984
985 if (Opts.MSVCCompat)
986 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
987}
988
989// Windows ARM, MS (C++) ABI
990MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
991 const TargetOptions &Opts)
992 : WindowsARMTargetInfo(Triple, Opts) {
993 TheCXXABI.set(TargetCXXABI::Microsoft);
994}
995
996void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
997 MacroBuilder &Builder) const {
998 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
999 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1000}
1001
1002MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1003 const TargetOptions &Opts)
1004 : WindowsARMTargetInfo(Triple, Opts) {
1005 TheCXXABI.set(TargetCXXABI::GenericARM);
1006}
1007
Erich Keaneebba5922017-07-21 22:37:03 +00001008void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1009 MacroBuilder &Builder) const {
1010 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1011 DefineStd(Builder, "WIN32", Opts);
1012 DefineStd(Builder, "WINNT", Opts);
1013 Builder.defineMacro("_ARM_");
1014 addMinGWDefines(Opts, Builder);
1015}
1016
Tim Northoverad4c5db2017-07-24 17:06:23 +00001017CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1018 const TargetOptions &Opts)
1019 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001020 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001021 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001022 DoubleAlign = LongLongAlign = 64;
1023 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1024}
1025
Erich Keaneebba5922017-07-21 22:37:03 +00001026void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1027 MacroBuilder &Builder) const {
1028 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1029 Builder.defineMacro("_ARM_");
1030 Builder.defineMacro("__CYGWIN__");
1031 Builder.defineMacro("__CYGWIN32__");
1032 DefineStd(Builder, "unix", Opts);
1033 if (Opts.CPlusPlus)
1034 Builder.defineMacro("_GNU_SOURCE");
1035}
1036
Tim Northoverad4c5db2017-07-24 17:06:23 +00001037DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1038 const TargetOptions &Opts)
1039 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1040 HasAlignMac68kSupport = true;
1041 // iOS always has 64-bit atomic instructions.
1042 // FIXME: This should be based off of the target features in
1043 // ARMleTargetInfo.
1044 MaxAtomicInlineWidth = 64;
1045
1046 if (Triple.isWatchABI()) {
1047 // Darwin on iOS uses a variant of the ARM C++ ABI.
1048 TheCXXABI.set(TargetCXXABI::WatchOS);
1049
1050 // The 32-bit ABI is silent on what ptrdiff_t should be, but given that
1051 // size_t is long, it's a bit weird for it to be int.
1052 PtrDiffType = SignedLong;
1053
1054 // BOOL should be a real boolean on the new ABI
1055 UseSignedCharForObjCBool = false;
1056 } else
1057 TheCXXABI.set(TargetCXXABI::iOS);
1058}
1059
1060void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1061 const llvm::Triple &Triple,
1062 MacroBuilder &Builder) const {
1063 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1064}
1065
1066RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1067 const TargetOptions &Opts)
1068 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1069 Triple.getOSName(),
1070 Triple.getEnvironmentName()),
1071 Opts) {
1072 IsRenderScriptTarget = true;
1073 LongWidth = LongAlign = 64;
1074}
1075
Erich Keaneebba5922017-07-21 22:37:03 +00001076void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1077 MacroBuilder &Builder) const {
1078 Builder.defineMacro("__RENDERSCRIPT__");
1079 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1080}