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