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