blob: cb202eac98588f11bbc5a95112ceba1796ab22ea [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";
Sjoerd Meijere6e4f312018-08-01 12:41:10 +0000188 case llvm::ARM::ArchKind::ARMV8_3A:
189 return "8_3A";
190 case llvm::ARM::ArchKind::ARMV8_4A:
191 return "8_4A";
Oliver Stannarda30b48d2018-09-26 14:20:29 +0000192 case llvm::ARM::ArchKind::ARMV8_5A:
193 return "8_5A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000194 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000195 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000196 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000197 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000198 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000199 return "8R";
200 }
201}
202
203StringRef ARMTargetInfo::getCPUProfile() const {
204 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000205 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000206 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000207 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000208 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000209 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000210 return "M";
211 default:
212 return "";
213 }
214}
215
216ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
217 const TargetOptions &Opts)
218 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
219 HW_FP(0) {
Saleem Abdulrasoole5696582017-10-20 04:11:28 +0000220 bool IsOpenBSD = Triple.getOS() == llvm::Triple::OpenBSD;
221 bool IsNetBSD = Triple.getOS() == llvm::Triple::NetBSD;
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000222
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000223 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
224 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000225
226 PtrDiffType = IntPtrType =
227 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
228 IsNetBSD)
229 ? SignedLong
230 : SignedInt;
231
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000232 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
233 IsNetBSD)
234 ? UnsignedLong
235 : UnsignedInt;
236
237 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000238 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
239 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000240 PtrDiffType = SignedInt;
241
Tim Northoverad4c5db2017-07-24 17:06:23 +0000242 // Cache arch related info.
243 setArchInfo();
244
245 // {} in inline assembly are neon specifiers, not assembly variant
246 // specifiers.
247 NoAsmVariants = true;
248
249 // FIXME: This duplicates code from the driver that sets the -target-abi
250 // option - this code is used if -target-abi isn't passed and should
251 // be unified in some way.
252 if (Triple.isOSBinFormatMachO()) {
253 // The backend is hardwired to assume AAPCS for M-class processors, ensure
254 // the frontend matches that.
255 if (Triple.getEnvironment() == llvm::Triple::EABI ||
256 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000257 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000258 setABI("aapcs");
259 } else if (Triple.isWatchABI()) {
260 setABI("aapcs16");
261 } else {
262 setABI("apcs-gnu");
263 }
264 } else if (Triple.isOSWindows()) {
265 // FIXME: this is invalid for WindowsCE
266 setABI("aapcs");
267 } else {
268 // Select the default based on the platform.
269 switch (Triple.getEnvironment()) {
270 case llvm::Triple::Android:
271 case llvm::Triple::GNUEABI:
272 case llvm::Triple::GNUEABIHF:
273 case llvm::Triple::MuslEABI:
274 case llvm::Triple::MuslEABIHF:
275 setABI("aapcs-linux");
276 break;
277 case llvm::Triple::EABIHF:
278 case llvm::Triple::EABI:
279 setABI("aapcs");
280 break;
281 case llvm::Triple::GNU:
282 setABI("apcs-gnu");
283 break;
284 default:
285 if (Triple.getOS() == llvm::Triple::NetBSD)
286 setABI("apcs-gnu");
287 else if (Triple.getOS() == llvm::Triple::OpenBSD)
288 setABI("aapcs-linux");
289 else
290 setABI("aapcs");
291 break;
292 }
293 }
294
295 // ARM targets default to using the ARM C++ ABI.
296 TheCXXABI.set(TargetCXXABI::GenericARM);
297
298 // ARM has atomics up to 8 bytes
299 setAtomic();
300
301 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
302 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
303 MaxVectorAlign = 64;
304
305 // Do force alignment of members that follow zero length bitfields. If
306 // the alignment of the zero-length bitfield is greater than the member
307 // that follows it, `bar', `bar' will be aligned as the type of the
308 // zero length bitfield.
309 UseZeroLengthBitfieldAlignment = true;
310
311 if (Triple.getOS() == llvm::Triple::Linux ||
312 Triple.getOS() == llvm::Triple::UnknownOS)
313 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
314 ? "\01__gnu_mcount_nc"
315 : "\01mcount";
316}
317
318StringRef ARMTargetInfo::getABI() const { return ABI; }
319
320bool ARMTargetInfo::setABI(const std::string &Name) {
321 ABI = Name;
322
323 // The defaults (above) are for AAPCS, check if we need to change them.
324 //
325 // FIXME: We need support for -meabi... we could just mangle it into the
326 // name.
327 if (Name == "apcs-gnu" || Name == "aapcs16") {
328 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000329 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000330 }
331 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
332 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000333 return true;
334 }
335 return false;
336}
337
Tim Northoverad4c5db2017-07-24 17:06:23 +0000338// FIXME: This should be based on Arch attributes, not CPU names.
339bool ARMTargetInfo::initFeatureMap(
340 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
341 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000342
Eli Friedman642a5ee2018-04-16 23:52:58 +0000343 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000344 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000345 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000346
Eli Friedman642a5ee2018-04-16 23:52:58 +0000347 // Map the base architecture to an appropriate target feature, so we don't
348 // rely on the target triple.
349 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
350 if (CPUArch == llvm::ARM::ArchKind::INVALID)
351 CPUArch = Arch;
352 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
353 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
354 TargetFeatures.push_back(ArchFeature);
355 }
356
Tim Northoverad4c5db2017-07-24 17:06:23 +0000357 // get default FPU features
358 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
359 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000360
Tim Northoverad4c5db2017-07-24 17:06:23 +0000361 // get default Extension features
362 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
363 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000364
Tim Northoverad4c5db2017-07-24 17:06:23 +0000365 for (auto Feature : TargetFeatures)
366 if (Feature[0] == '+')
367 Features[Feature.drop_front(1)] = true;
368
369 // Enable or disable thumb-mode explicitly per function to enable mixed
370 // ARM and Thumb code generation.
371 if (isThumb())
372 Features["thumb-mode"] = true;
373 else
374 Features["thumb-mode"] = false;
375
376 // Convert user-provided arm and thumb GNU target attributes to
377 // [-|+]thumb-mode target features respectively.
378 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
379 for (auto &Feature : UpdatedFeaturesVec) {
380 if (Feature.compare("+arm") == 0)
381 Feature = "-thumb-mode";
382 else if (Feature.compare("+thumb") == 0)
383 Feature = "+thumb-mode";
384 }
385
386 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000387}
388
Erich Keaneebba5922017-07-21 22:37:03 +0000389
Tim Northoverad4c5db2017-07-24 17:06:23 +0000390bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
391 DiagnosticsEngine &Diags) {
392 FPU = 0;
393 CRC = 0;
394 Crypto = 0;
395 DSP = 0;
396 Unaligned = 1;
397 SoftFloat = SoftFloatABI = false;
398 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000399 DotProd = 0;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000400
401 // This does not diagnose illegal cases like having both
402 // "+vfpv2" and "+vfpv3" or having "+neon" and "+fp-only-sp".
403 uint32_t HW_FP_remove = 0;
404 for (const auto &Feature : Features) {
405 if (Feature == "+soft-float") {
406 SoftFloat = true;
407 } else if (Feature == "+soft-float-abi") {
408 SoftFloatABI = true;
409 } else if (Feature == "+vfp2") {
410 FPU |= VFP2FPU;
411 HW_FP |= HW_FP_SP | HW_FP_DP;
412 } else if (Feature == "+vfp3") {
413 FPU |= VFP3FPU;
414 HW_FP |= HW_FP_SP | HW_FP_DP;
415 } else if (Feature == "+vfp4") {
416 FPU |= VFP4FPU;
417 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
418 } else if (Feature == "+fp-armv8") {
419 FPU |= FPARMV8;
420 HW_FP |= HW_FP_SP | HW_FP_DP | HW_FP_HP;
421 } else if (Feature == "+neon") {
422 FPU |= NeonFPU;
423 HW_FP |= HW_FP_SP | HW_FP_DP;
424 } else if (Feature == "+hwdiv") {
425 HWDiv |= HWDivThumb;
426 } else if (Feature == "+hwdiv-arm") {
427 HWDiv |= HWDivARM;
428 } else if (Feature == "+crc") {
429 CRC = 1;
430 } else if (Feature == "+crypto") {
431 Crypto = 1;
432 } else if (Feature == "+dsp") {
433 DSP = 1;
434 } else if (Feature == "+fp-only-sp") {
435 HW_FP_remove |= HW_FP_DP;
436 } else if (Feature == "+strict-align") {
437 Unaligned = 0;
438 } else if (Feature == "+fp16") {
439 HW_FP |= HW_FP_HP;
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000440 } else if (Feature == "+fullfp16") {
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000441 HasLegalHalfType = true;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000442 } else if (Feature == "+dotprod") {
443 DotProd = true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000444 }
445 }
446 HW_FP &= ~HW_FP_remove;
447
448 switch (ArchVersion) {
449 case 6:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000450 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000451 LDREX = 0;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000452 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000453 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
454 else
455 LDREX = LDREX_W;
456 break;
457 case 7:
Florian Hahnef5bbd62017-07-27 16:28:39 +0000458 if (ArchProfile == llvm::ARM::ProfileKind::M)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000459 LDREX = LDREX_W | LDREX_H | LDREX_B;
460 else
461 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
462 break;
463 case 8:
464 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
465 }
466
467 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
468 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
469 return false;
470 }
471
472 if (FPMath == FP_Neon)
473 Features.push_back("+neonfp");
474 else if (FPMath == FP_VFP)
475 Features.push_back("-neonfp");
476
477 // Remove front-end specific options which the backend handles differently.
478 auto Feature = std::find(Features.begin(), Features.end(), "+soft-float-abi");
479 if (Feature != Features.end())
480 Features.erase(Feature);
481
482 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000483}
484
Erich Keaneebba5922017-07-21 22:37:03 +0000485bool ARMTargetInfo::hasFeature(StringRef Feature) const {
486 return llvm::StringSwitch<bool>(Feature)
487 .Case("arm", true)
488 .Case("aarch32", true)
489 .Case("softfloat", SoftFloat)
490 .Case("thumb", isThumb())
491 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
492 .Case("vfp", FPU && !SoftFloat)
493 .Case("hwdiv", HWDiv & HWDivThumb)
494 .Case("hwdiv-arm", HWDiv & HWDivARM)
495 .Default(false);
496}
497
Tim Northoverad4c5db2017-07-24 17:06:23 +0000498bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
499 return Name == "generic" ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000500 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000501}
502
Erich Keane3ec17432018-02-08 23:14:15 +0000503void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
504 llvm::ARM::fillValidCPUArchList(Values);
505}
506
Tim Northoverad4c5db2017-07-24 17:06:23 +0000507bool ARMTargetInfo::setCPU(const std::string &Name) {
508 if (Name != "generic")
509 setArchInfo(llvm::ARM::parseCPUArch(Name));
510
Florian Hahnef5bbd62017-07-27 16:28:39 +0000511 if (ArchKind == llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000512 return false;
513 setAtomic();
514 CPU = Name;
515 return true;
516}
517
518bool ARMTargetInfo::setFPMath(StringRef Name) {
519 if (Name == "neon") {
520 FPMath = FP_Neon;
521 return true;
522 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
523 Name == "vfp4") {
524 FPMath = FP_VFP;
525 return true;
526 }
527 return false;
528}
529
530void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
531 MacroBuilder &Builder) const {
532 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
533}
534
535void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
536 MacroBuilder &Builder) const {
537 // Also include the ARMv8.1-A defines
538 getTargetDefinesARMV81A(Opts, Builder);
539}
540
Erich Keaneebba5922017-07-21 22:37:03 +0000541void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
542 MacroBuilder &Builder) const {
543 // Target identification.
544 Builder.defineMacro("__arm");
545 Builder.defineMacro("__arm__");
546 // For bare-metal none-eabi.
547 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
548 (getTriple().getEnvironment() == llvm::Triple::EABI ||
549 getTriple().getEnvironment() == llvm::Triple::EABIHF))
550 Builder.defineMacro("__ELF__");
551
552 // Target properties.
553 Builder.defineMacro("__REGISTER_PREFIX__", "");
554
555 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
556 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
557 if (getTriple().isWatchABI())
558 Builder.defineMacro("__ARM_ARCH_7K__", "2");
559
560 if (!CPUAttr.empty())
561 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
562
563 // ACLE 6.4.1 ARM/Thumb instruction set architecture
564 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
565 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
566
567 if (ArchVersion >= 8) {
568 // ACLE 6.5.7 Crypto Extension
569 if (Crypto)
570 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
571 // ACLE 6.5.8 CRC32 Extension
572 if (CRC)
573 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
574 // ACLE 6.5.10 Numeric Maximum and Minimum
575 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
576 // ACLE 6.5.9 Directed Rounding
577 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
578 }
579
580 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
581 // is not defined for the M-profile.
582 // NOTE that the default profile is assumed to be 'A'
Florian Hahnef5bbd62017-07-27 16:28:39 +0000583 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
Erich Keaneebba5922017-07-21 22:37:03 +0000584 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
585
586 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
587 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
588 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
589 // v7 and v8 architectures excluding v8-M Baseline.
590 if (supportsThumb2())
591 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
592 else if (supportsThumb())
593 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
594
595 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
596 // instruction set such as ARM or Thumb.
597 Builder.defineMacro("__ARM_32BIT_STATE", "1");
598
599 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
600
601 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
602 if (!CPUProfile.empty())
603 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
604
605 // ACLE 6.4.3 Unaligned access supported in hardware
606 if (Unaligned)
607 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
608
609 // ACLE 6.4.4 LDREX/STREX
610 if (LDREX)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000611 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
Erich Keaneebba5922017-07-21 22:37:03 +0000612
613 // ACLE 6.4.5 CLZ
614 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
615 ArchVersion > 6)
616 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
617
618 // ACLE 6.5.1 Hardware Floating Point
619 if (HW_FP)
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000620 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
Erich Keaneebba5922017-07-21 22:37:03 +0000621
622 // ACLE predefines.
623 Builder.defineMacro("__ARM_ACLE", "200");
624
625 // FP16 support (we currently only support IEEE format).
626 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
627 Builder.defineMacro("__ARM_FP16_ARGS", "1");
628
629 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
630 if (ArchVersion >= 7 && (FPU & VFP4FPU))
631 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
632
633 // Subtarget options.
634
635 // FIXME: It's more complicated than this and we don't really support
636 // interworking.
637 // Windows on ARM does not "support" interworking
638 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
639 Builder.defineMacro("__THUMB_INTERWORK__");
640
641 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
642 // Embedded targets on Darwin follow AAPCS, but not EABI.
643 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
644 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
645 Builder.defineMacro("__ARM_EABI__");
646 Builder.defineMacro("__ARM_PCS", "1");
647 }
648
649 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
650 Builder.defineMacro("__ARM_PCS_VFP", "1");
651
652 if (SoftFloat)
653 Builder.defineMacro("__SOFTFP__");
654
Florian Hahnef5bbd62017-07-27 16:28:39 +0000655 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000656 Builder.defineMacro("__XSCALE__");
657
658 if (isThumb()) {
659 Builder.defineMacro("__THUMBEL__");
660 Builder.defineMacro("__thumb__");
661 if (supportsThumb2())
662 Builder.defineMacro("__thumb2__");
663 }
664
665 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000666 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000667 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
668
669 // ACLE 6.4.10 Hardware Integer Divide
670 if (((HWDiv & HWDivThumb) && isThumb()) ||
671 ((HWDiv & HWDivARM) && !isThumb())) {
672 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
673 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
674 }
675
676 // Note, this is always on in gcc, even though it doesn't make sense.
677 Builder.defineMacro("__APCS_32__");
678
679 if (FPUModeIsVFP((FPUMode)FPU)) {
680 Builder.defineMacro("__VFP_FP__");
681 if (FPU & VFP2FPU)
682 Builder.defineMacro("__ARM_VFPV2__");
683 if (FPU & VFP3FPU)
684 Builder.defineMacro("__ARM_VFPV3__");
685 if (FPU & VFP4FPU)
686 Builder.defineMacro("__ARM_VFPV4__");
687 if (FPU & FPARMV8)
688 Builder.defineMacro("__ARM_FPV5__");
689 }
690
691 // This only gets set when Neon instructions are actually available, unlike
692 // the VFP define, hence the soft float and arch check. This is subtly
693 // different from gcc, we follow the intent which was that it should be set
694 // when Neon instructions are actually available.
695 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
696 Builder.defineMacro("__ARM_NEON", "1");
697 Builder.defineMacro("__ARM_NEON__");
698 // current AArch32 NEON implementations do not support double-precision
699 // floating-point even when it is present in VFP.
700 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000701 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000702 }
703
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000704 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000705 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000706
707 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
708
709 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
710 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
711 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
712 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
713 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
714 }
715
716 // ACLE 6.4.7 DSP instructions
717 if (DSP) {
718 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
719 }
720
721 // ACLE 6.4.8 Saturation instructions
722 bool SAT = false;
723 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
724 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
725 SAT = true;
726 }
727
728 // ACLE 6.4.6 Q (saturation) flag
729 if (DSP || SAT)
730 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
731
732 if (Opts.UnsafeFPMath)
733 Builder.defineMacro("__ARM_FP_FAST", "1");
734
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000735 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000736 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000737 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
738
739 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000740 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000741 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
742
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000743 // Armv8.2-A dot product intrinsics
744 if (DotProd)
745 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000746
Erich Keaneebba5922017-07-21 22:37:03 +0000747 switch (ArchKind) {
748 default:
749 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000750 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000751 getTargetDefinesARMV81A(Opts, Builder);
752 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000753 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000754 getTargetDefinesARMV82A(Opts, Builder);
755 break;
756 }
757}
758
Tim Northoverad4c5db2017-07-24 17:06:23 +0000759const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
760#define BUILTIN(ID, TYPE, ATTRS) \
761 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
762#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
763 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
764#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000765
Tim Northoverad4c5db2017-07-24 17:06:23 +0000766#define BUILTIN(ID, TYPE, ATTRS) \
767 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
768#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
769 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
770#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
771 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
772#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
773 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
774#include "clang/Basic/BuiltinsARM.def"
775};
776
777ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
778 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
779 Builtin::FirstTSBuiltin);
780}
781
782bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
783TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
784 return IsAAPCS
785 ? AAPCSABIBuiltinVaList
786 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
787 : TargetInfo::VoidPtrBuiltinVaList);
788}
789
790const char *const ARMTargetInfo::GCCRegNames[] = {
791 // Integer registers
792 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
793 "r12", "sp", "lr", "pc",
794
795 // Float registers
796 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
797 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
798 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
799
800 // Double registers
801 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
802 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
803 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
804
805 // Quad registers
806 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
807 "q12", "q13", "q14", "q15"};
808
809ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
810 return llvm::makeArrayRef(GCCRegNames);
811}
812
813const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
814 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
815 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
816 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
817 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
818 // The S, D and Q registers overlap, but aren't really aliases; we
819 // don't want to substitute one of these for a different-sized one.
820};
821
822ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
823 return llvm::makeArrayRef(GCCRegAliases);
824}
825
826bool ARMTargetInfo::validateAsmConstraint(
827 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
828 switch (*Name) {
829 default:
830 break;
831 case 'l': // r0-r7
832 case 'h': // r8-r15
833 case 't': // VFP Floating point register single precision
834 case 'w': // VFP Floating point register double precision
835 Info.setAllowsRegister();
836 return true;
837 case 'I':
838 case 'J':
839 case 'K':
840 case 'L':
841 case 'M':
842 // FIXME
843 return true;
844 case 'Q': // A memory address that is a single base register.
845 Info.setAllowsMemory();
846 return true;
847 case 'U': // a memory reference...
848 switch (Name[1]) {
849 case 'q': // ...ARMV4 ldrsb
850 case 'v': // ...VFP load/store (reg+constant offset)
851 case 'y': // ...iWMMXt load/store
852 case 't': // address valid for load/store opaque types wider
853 // than 128-bits
854 case 'n': // valid address for Neon doubleword vector load/store
855 case 'm': // valid address for Neon element and structure load/store
856 case 's': // valid address for non-offset loads/stores of quad-word
857 // values in four ARM registers
858 Info.setAllowsMemory();
859 Name++;
860 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000861 }
862 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000863 return false;
864}
Erich Keaneebba5922017-07-21 22:37:03 +0000865
Tim Northoverad4c5db2017-07-24 17:06:23 +0000866std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
867 std::string R;
868 switch (*Constraint) {
869 case 'U': // Two-character constraint; add "^" hint for later parsing.
870 R = std::string("^") + std::string(Constraint, 2);
871 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000872 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000873 case 'p': // 'p' should be translated to 'r' by default.
874 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000875 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000876 default:
877 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000878 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000879 return R;
880}
Erich Keaneebba5922017-07-21 22:37:03 +0000881
Tim Northoverad4c5db2017-07-24 17:06:23 +0000882bool ARMTargetInfo::validateConstraintModifier(
883 StringRef Constraint, char Modifier, unsigned Size,
884 std::string &SuggestedModifier) const {
885 bool isOutput = (Constraint[0] == '=');
886 bool isInOut = (Constraint[0] == '+');
887
888 // Strip off constraint modifiers.
889 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
890 Constraint = Constraint.substr(1);
891
892 switch (Constraint[0]) {
893 default:
894 break;
895 case 'r': {
896 switch (Modifier) {
897 default:
898 return (isInOut || isOutput || Size <= 64);
899 case 'q':
900 // A register of size 32 cannot fit a vector type.
901 return false;
902 }
Erich Keaneebba5922017-07-21 22:37:03 +0000903 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000904 }
Erich Keaneebba5922017-07-21 22:37:03 +0000905
906 return true;
907}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000908const char *ARMTargetInfo::getClobbers() const {
909 // FIXME: Is this really right?
910 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000911}
912
Tim Northoverad4c5db2017-07-24 17:06:23 +0000913TargetInfo::CallingConvCheckResult
914ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
915 switch (CC) {
916 case CC_AAPCS:
917 case CC_AAPCS_VFP:
918 case CC_Swift:
919 case CC_OpenCLKernel:
920 return CCCR_OK;
921 default:
922 return CCCR_Warning;
923 }
924}
925
926int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
927 if (RegNo == 0)
928 return 0;
929 if (RegNo == 1)
930 return 1;
931 return -1;
932}
933
934bool ARMTargetInfo::hasSjLjLowering() const { return true; }
935
936ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
937 const TargetOptions &Opts)
938 : ARMTargetInfo(Triple, Opts) {}
939
Erich Keaneebba5922017-07-21 22:37:03 +0000940void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
941 MacroBuilder &Builder) const {
942 Builder.defineMacro("__ARMEL__");
943 ARMTargetInfo::getTargetDefines(Opts, Builder);
944}
945
Tim Northoverad4c5db2017-07-24 17:06:23 +0000946ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
947 const TargetOptions &Opts)
948 : ARMTargetInfo(Triple, Opts) {}
949
Erich Keaneebba5922017-07-21 22:37:03 +0000950void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
951 MacroBuilder &Builder) const {
952 Builder.defineMacro("__ARMEB__");
953 Builder.defineMacro("__ARM_BIG_ENDIAN");
954 ARMTargetInfo::getTargetDefines(Opts, Builder);
955}
956
Tim Northoverad4c5db2017-07-24 17:06:23 +0000957WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
958 const TargetOptions &Opts)
959 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000960}
961
Erich Keaneebba5922017-07-21 22:37:03 +0000962void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
963 MacroBuilder &Builder) const {
964 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
965
966 // FIXME: this is invalid for WindowsCE
967 Builder.defineMacro("_M_ARM_NT", "1");
968 Builder.defineMacro("_M_ARMT", "_M_ARM");
969 Builder.defineMacro("_M_THUMB", "_M_ARM");
970
971 assert((Triple.getArch() == llvm::Triple::arm ||
972 Triple.getArch() == llvm::Triple::thumb) &&
973 "invalid architecture for Windows ARM target info");
974 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
975 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
976
977 // TODO map the complete set of values
978 // 31: VFPv3 40: VFPv4
979 Builder.defineMacro("_M_ARM_FP", "31");
980}
981
Tim Northoverad4c5db2017-07-24 17:06:23 +0000982TargetInfo::BuiltinVaListKind
983WindowsARMTargetInfo::getBuiltinVaListKind() const {
984 return TargetInfo::CharPtrBuiltinVaList;
985}
986
987TargetInfo::CallingConvCheckResult
988WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
989 switch (CC) {
990 case CC_X86StdCall:
991 case CC_X86ThisCall:
992 case CC_X86FastCall:
993 case CC_X86VectorCall:
994 return CCCR_Ignore;
995 case CC_C:
996 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +0000997 case CC_PreserveMost:
998 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +0000999 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001000 return CCCR_OK;
1001 default:
1002 return CCCR_Warning;
1003 }
1004}
1005
1006// Windows ARM + Itanium C++ ABI Target
1007ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1008 const llvm::Triple &Triple, const TargetOptions &Opts)
1009 : WindowsARMTargetInfo(Triple, Opts) {
1010 TheCXXABI.set(TargetCXXABI::GenericARM);
1011}
1012
1013void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1014 const LangOptions &Opts, MacroBuilder &Builder) const {
1015 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1016
1017 if (Opts.MSVCCompat)
1018 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1019}
1020
1021// Windows ARM, MS (C++) ABI
1022MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1023 const TargetOptions &Opts)
1024 : WindowsARMTargetInfo(Triple, Opts) {
1025 TheCXXABI.set(TargetCXXABI::Microsoft);
1026}
1027
1028void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1029 MacroBuilder &Builder) const {
1030 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1031 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1032}
1033
1034MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1035 const TargetOptions &Opts)
1036 : WindowsARMTargetInfo(Triple, Opts) {
1037 TheCXXABI.set(TargetCXXABI::GenericARM);
1038}
1039
Erich Keaneebba5922017-07-21 22:37:03 +00001040void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1041 MacroBuilder &Builder) const {
1042 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001043 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001044}
1045
Tim Northoverad4c5db2017-07-24 17:06:23 +00001046CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1047 const TargetOptions &Opts)
1048 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001049 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001050 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001051 DoubleAlign = LongLongAlign = 64;
1052 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1053}
1054
Erich Keaneebba5922017-07-21 22:37:03 +00001055void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1056 MacroBuilder &Builder) const {
1057 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1058 Builder.defineMacro("_ARM_");
1059 Builder.defineMacro("__CYGWIN__");
1060 Builder.defineMacro("__CYGWIN32__");
1061 DefineStd(Builder, "unix", Opts);
1062 if (Opts.CPlusPlus)
1063 Builder.defineMacro("_GNU_SOURCE");
1064}
1065
Tim Northoverad4c5db2017-07-24 17:06:23 +00001066DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1067 const TargetOptions &Opts)
1068 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1069 HasAlignMac68kSupport = true;
1070 // iOS always has 64-bit atomic instructions.
1071 // FIXME: This should be based off of the target features in
1072 // ARMleTargetInfo.
1073 MaxAtomicInlineWidth = 64;
1074
1075 if (Triple.isWatchABI()) {
1076 // Darwin on iOS uses a variant of the ARM C++ ABI.
1077 TheCXXABI.set(TargetCXXABI::WatchOS);
1078
Tim Northoverad4c5db2017-07-24 17:06:23 +00001079 // BOOL should be a real boolean on the new ABI
1080 UseSignedCharForObjCBool = false;
1081 } else
1082 TheCXXABI.set(TargetCXXABI::iOS);
1083}
1084
1085void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1086 const llvm::Triple &Triple,
1087 MacroBuilder &Builder) const {
1088 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1089}
1090
1091RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1092 const TargetOptions &Opts)
1093 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1094 Triple.getOSName(),
1095 Triple.getEnvironmentName()),
1096 Opts) {
1097 IsRenderScriptTarget = true;
1098 LongWidth = LongAlign = 64;
1099}
1100
Erich Keaneebba5922017-07-21 22:37:03 +00001101void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1102 MacroBuilder &Builder) const {
1103 Builder.defineMacro("__RENDERSCRIPT__");
1104 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1105}