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