blob: 61a520bd5e0b0f987044fd1db8ece3f194cc8e9a [file] [log] [blame]
Erich Keaneebba5922017-07-21 22:37:03 +00001//===--- ARM.cpp - Implement ARM target feature support -------------------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Erich Keaneebba5922017-07-21 22:37:03 +00006//
7//===----------------------------------------------------------------------===//
8//
9// This file implements ARM TargetInfo objects.
10//
11//===----------------------------------------------------------------------===//
12
13#include "ARM.h"
14#include "clang/Basic/Builtins.h"
15#include "clang/Basic/Diagnostic.h"
16#include "clang/Basic/TargetBuiltins.h"
17#include "llvm/ADT/StringExtras.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/StringSwitch.h"
20
21using namespace clang;
22using namespace clang::targets;
23
Tim Northoverad4c5db2017-07-24 17:06:23 +000024void ARMTargetInfo::setABIAAPCS() {
25 IsAAPCS = true;
26
27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28 const llvm::Triple &T = getTriple();
29
Michal Gorny5a409d02018-12-20 13:09:30 +000030 bool IsNetBSD = T.isOSNetBSD();
31 bool IsOpenBSD = T.isOSOpenBSD();
Saleem Abdulrasool729379a2017-10-06 23:09:55 +000032 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +000033 WCharType = UnsignedInt;
Tim Northoverad4c5db2017-07-24 17:06:23 +000034
35 UseBitFieldTypeAlignment = true;
36
37 ZeroLengthBitfieldBoundary = 0;
38
39 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
40 // so set preferred for small types to 32.
41 if (T.isOSBinFormatMachO()) {
42 resetDataLayout(BigEndian
43 ? "E-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
44 : "e-m:o-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
45 } else if (T.isOSWindows()) {
46 assert(!BigEndian && "Windows on ARM does not support big endian");
47 resetDataLayout("e"
48 "-m:w"
49 "-p:32:32"
50 "-i64:64"
51 "-v128:64:128"
52 "-a:0:32"
53 "-n32"
54 "-S64");
55 } else if (T.isOSNaCl()) {
56 assert(!BigEndian && "NaCl on ARM does not support big endian");
57 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S128");
58 } else {
59 resetDataLayout(BigEndian
60 ? "E-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64"
61 : "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
62 }
63
64 // FIXME: Enumerated types are variable width in straight AAPCS.
65}
66
67void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
68 const llvm::Triple &T = getTriple();
69
70 IsAAPCS = false;
71
72 if (IsAAPCS16)
73 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
74 else
75 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
76
Tim Northoverad4c5db2017-07-24 17:06:23 +000077 WCharType = SignedInt;
78
79 // Do not respect the alignment of bit-field types when laying out
80 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
81 UseBitFieldTypeAlignment = false;
82
83 /// gcc forces the alignment to 4 bytes, regardless of the type of the
84 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
85 /// gcc.
86 ZeroLengthBitfieldBoundary = 32;
87
88 if (T.isOSBinFormatMachO() && IsAAPCS16) {
89 assert(!BigEndian && "AAPCS16 does not support big-endian");
90 resetDataLayout("e-m:o-p:32:32-i64:64-a:0:32-n32-S128");
91 } else if (T.isOSBinFormatMachO())
92 resetDataLayout(
93 BigEndian
94 ? "E-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
95 : "e-m:o-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
96 else
97 resetDataLayout(
98 BigEndian
99 ? "E-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
100 : "e-m:e-p:32:32-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
101
102 // FIXME: Override "preferred align" for double and long long.
103}
104
105void ARMTargetInfo::setArchInfo() {
106 StringRef ArchName = getTriple().getArchName();
107
108 ArchISA = llvm::ARM::parseArchISA(ArchName);
109 CPU = llvm::ARM::getDefaultCPU(ArchName);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000110 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
111 if (AK != llvm::ARM::ArchKind::INVALID)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000112 ArchKind = AK;
113 setArchInfo(ArchKind);
114}
115
Florian Hahnef5bbd62017-07-27 16:28:39 +0000116void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000117 StringRef SubArch;
118
119 // cache TargetParser info
120 ArchKind = Kind;
121 SubArch = llvm::ARM::getSubArch(ArchKind);
122 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
123 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
124
125 // cache CPU related strings
126 CPUAttr = getCPUAttr();
127 CPUProfile = getCPUProfile();
128}
129
130void ARMTargetInfo::setAtomic() {
131 // when triple does not specify a sub arch,
132 // then we are not using inline atomics
133 bool ShouldUseInlineAtomic =
Florian Hahnef5bbd62017-07-27 16:28:39 +0000134 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
135 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
Tim Northoverad4c5db2017-07-24 17:06:23 +0000136 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
Florian Hahnef5bbd62017-07-27 16:28:39 +0000137 if (ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000138 MaxAtomicPromoteWidth = 32;
139 if (ShouldUseInlineAtomic)
140 MaxAtomicInlineWidth = 32;
141 } else {
142 MaxAtomicPromoteWidth = 64;
143 if (ShouldUseInlineAtomic)
144 MaxAtomicInlineWidth = 64;
145 }
146}
147
Florian Hahnef5bbd62017-07-27 16:28:39 +0000148bool ARMTargetInfo::isThumb() const {
149 return ArchISA == llvm::ARM::ISAKind::THUMB;
150}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000151
152bool ARMTargetInfo::supportsThumb() const {
153 return CPUAttr.count('T') || ArchVersion >= 6;
154}
155
156bool ARMTargetInfo::supportsThumb2() const {
157 return CPUAttr.equals("6T2") ||
158 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
159}
160
161StringRef ARMTargetInfo::getCPUAttr() const {
162 // For most sub-arches, the build attribute CPU name is enough.
163 // For Cortex variants, it's slightly different.
164 switch (ArchKind) {
165 default:
166 return llvm::ARM::getCPUAttr(ArchKind);
Florian Hahnef5bbd62017-07-27 16:28:39 +0000167 case llvm::ARM::ArchKind::ARMV6M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000168 return "6M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000169 case llvm::ARM::ArchKind::ARMV7S:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000170 return "7S";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000171 case llvm::ARM::ArchKind::ARMV7A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000172 return "7A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000173 case llvm::ARM::ArchKind::ARMV7R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000174 return "7R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000175 case llvm::ARM::ArchKind::ARMV7M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000176 return "7M";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000177 case llvm::ARM::ArchKind::ARMV7EM:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000178 return "7EM";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000179 case llvm::ARM::ArchKind::ARMV7VE:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000180 return "7VE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000181 case llvm::ARM::ArchKind::ARMV8A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000182 return "8A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000183 case llvm::ARM::ArchKind::ARMV8_1A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000184 return "8_1A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000185 case llvm::ARM::ArchKind::ARMV8_2A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000186 return "8_2A";
Sjoerd Meijere6e4f312018-08-01 12:41:10 +0000187 case llvm::ARM::ArchKind::ARMV8_3A:
188 return "8_3A";
189 case llvm::ARM::ArchKind::ARMV8_4A:
190 return "8_4A";
Oliver Stannarda30b48d2018-09-26 14:20:29 +0000191 case llvm::ARM::ArchKind::ARMV8_5A:
192 return "8_5A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000193 case llvm::ARM::ArchKind::ARMV8MBaseline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000194 return "8M_BASE";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000195 case llvm::ARM::ArchKind::ARMV8MMainline:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000196 return "8M_MAIN";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000197 case llvm::ARM::ArchKind::ARMV8R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000198 return "8R";
199 }
200}
201
202StringRef ARMTargetInfo::getCPUProfile() const {
203 switch (ArchProfile) {
Florian Hahnef5bbd62017-07-27 16:28:39 +0000204 case llvm::ARM::ProfileKind::A:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000205 return "A";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000206 case llvm::ARM::ProfileKind::R:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000207 return "R";
Florian Hahnef5bbd62017-07-27 16:28:39 +0000208 case llvm::ARM::ProfileKind::M:
Tim Northoverad4c5db2017-07-24 17:06:23 +0000209 return "M";
210 default:
211 return "";
212 }
213}
214
215ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
216 const TargetOptions &Opts)
217 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
218 HW_FP(0) {
Michal Gorny5a409d02018-12-20 13:09:30 +0000219 bool IsOpenBSD = Triple.isOSOpenBSD();
220 bool IsNetBSD = Triple.isOSNetBSD();
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000221
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000222 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
223 // environment where size_t is `unsigned long` rather than `unsigned int`
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000224
225 PtrDiffType = IntPtrType =
226 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
227 IsNetBSD)
228 ? SignedLong
229 : SignedInt;
230
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000231 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
232 IsNetBSD)
233 ? UnsignedLong
234 : UnsignedInt;
235
236 // ptrdiff_t is inconsistent on Darwin
Saleem Abdulrasool1924b242017-10-28 06:00:43 +0000237 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
238 !Triple.isWatchABI())
Saleem Abdulrasool418a8162017-10-27 23:04:27 +0000239 PtrDiffType = SignedInt;
240
Tim Northoverad4c5db2017-07-24 17:06:23 +0000241 // Cache arch related info.
242 setArchInfo();
243
244 // {} in inline assembly are neon specifiers, not assembly variant
245 // specifiers.
246 NoAsmVariants = true;
247
248 // FIXME: This duplicates code from the driver that sets the -target-abi
249 // option - this code is used if -target-abi isn't passed and should
250 // be unified in some way.
251 if (Triple.isOSBinFormatMachO()) {
252 // The backend is hardwired to assume AAPCS for M-class processors, ensure
253 // the frontend matches that.
254 if (Triple.getEnvironment() == llvm::Triple::EABI ||
255 Triple.getOS() == llvm::Triple::UnknownOS ||
Florian Hahnef5bbd62017-07-27 16:28:39 +0000256 ArchProfile == llvm::ARM::ProfileKind::M) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000257 setABI("aapcs");
258 } else if (Triple.isWatchABI()) {
259 setABI("aapcs16");
260 } else {
261 setABI("apcs-gnu");
262 }
263 } else if (Triple.isOSWindows()) {
264 // FIXME: this is invalid for WindowsCE
265 setABI("aapcs");
266 } else {
267 // Select the default based on the platform.
268 switch (Triple.getEnvironment()) {
269 case llvm::Triple::Android:
270 case llvm::Triple::GNUEABI:
271 case llvm::Triple::GNUEABIHF:
272 case llvm::Triple::MuslEABI:
273 case llvm::Triple::MuslEABIHF:
274 setABI("aapcs-linux");
275 break;
276 case llvm::Triple::EABIHF:
277 case llvm::Triple::EABI:
278 setABI("aapcs");
279 break;
280 case llvm::Triple::GNU:
281 setABI("apcs-gnu");
282 break;
283 default:
Michal Gorny5a409d02018-12-20 13:09:30 +0000284 if (IsNetBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000285 setABI("apcs-gnu");
Michal Gorny5a409d02018-12-20 13:09:30 +0000286 else if (IsOpenBSD)
Tim Northoverad4c5db2017-07-24 17:06:23 +0000287 setABI("aapcs-linux");
288 else
289 setABI("aapcs");
290 break;
291 }
292 }
293
294 // ARM targets default to using the ARM C++ ABI.
295 TheCXXABI.set(TargetCXXABI::GenericARM);
296
297 // ARM has atomics up to 8 bytes
298 setAtomic();
299
300 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
301 if (IsAAPCS && (Triple.getEnvironment() != llvm::Triple::Android))
302 MaxVectorAlign = 64;
303
304 // Do force alignment of members that follow zero length bitfields. If
305 // the alignment of the zero-length bitfield is greater than the member
306 // that follows it, `bar', `bar' will be aligned as the type of the
307 // zero length bitfield.
308 UseZeroLengthBitfieldAlignment = true;
309
310 if (Triple.getOS() == llvm::Triple::Linux ||
311 Triple.getOS() == llvm::Triple::UnknownOS)
312 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
313 ? "\01__gnu_mcount_nc"
314 : "\01mcount";
315}
316
317StringRef ARMTargetInfo::getABI() const { return ABI; }
318
319bool ARMTargetInfo::setABI(const std::string &Name) {
320 ABI = Name;
321
322 // The defaults (above) are for AAPCS, check if we need to change them.
323 //
324 // FIXME: We need support for -meabi... we could just mangle it into the
325 // name.
326 if (Name == "apcs-gnu" || Name == "aapcs16") {
327 setABIAPCS(Name == "aapcs16");
Erich Keaneebba5922017-07-21 22:37:03 +0000328 return true;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000329 }
330 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
331 setABIAAPCS();
Erich Keaneebba5922017-07-21 22:37:03 +0000332 return true;
333 }
334 return false;
335}
336
Tim Northoverad4c5db2017-07-24 17:06:23 +0000337// FIXME: This should be based on Arch attributes, not CPU names.
338bool ARMTargetInfo::initFeatureMap(
339 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
340 const std::vector<std::string> &FeaturesVec) const {
Erich Keaneebba5922017-07-21 22:37:03 +0000341
Eli Friedman642a5ee2018-04-16 23:52:58 +0000342 std::string ArchFeature;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000343 std::vector<StringRef> TargetFeatures;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000344 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
Erich Keaneebba5922017-07-21 22:37:03 +0000345
Eli Friedman642a5ee2018-04-16 23:52:58 +0000346 // Map the base architecture to an appropriate target feature, so we don't
347 // rely on the target triple.
348 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
349 if (CPUArch == llvm::ARM::ArchKind::INVALID)
350 CPUArch = Arch;
351 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
352 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
353 TargetFeatures.push_back(ArchFeature);
354 }
355
Tim Northoverad4c5db2017-07-24 17:06:23 +0000356 // get default FPU features
357 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
358 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000359
Tim Northoverad4c5db2017-07-24 17:06:23 +0000360 // get default Extension features
361 unsigned Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
362 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
Erich Keaneebba5922017-07-21 22:37:03 +0000363
Tim Northoverad4c5db2017-07-24 17:06:23 +0000364 for (auto Feature : TargetFeatures)
365 if (Feature[0] == '+')
366 Features[Feature.drop_front(1)] = true;
367
368 // Enable or disable thumb-mode explicitly per function to enable mixed
369 // ARM and Thumb code generation.
370 if (isThumb())
371 Features["thumb-mode"] = true;
372 else
373 Features["thumb-mode"] = false;
374
375 // Convert user-provided arm and thumb GNU target attributes to
376 // [-|+]thumb-mode target features respectively.
377 std::vector<std::string> UpdatedFeaturesVec(FeaturesVec);
378 for (auto &Feature : UpdatedFeaturesVec) {
379 if (Feature.compare("+arm") == 0)
380 Feature = "-thumb-mode";
381 else if (Feature.compare("+thumb") == 0)
382 Feature = "+thumb-mode";
383 }
384
385 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
Erich Keaneebba5922017-07-21 22:37:03 +0000386}
387
Erich Keaneebba5922017-07-21 22:37:03 +0000388
Tim Northoverad4c5db2017-07-24 17:06:23 +0000389bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
390 DiagnosticsEngine &Diags) {
391 FPU = 0;
392 CRC = 0;
393 Crypto = 0;
394 DSP = 0;
395 Unaligned = 1;
396 SoftFloat = SoftFloatABI = false;
397 HWDiv = 0;
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000398 DotProd = 0;
Erich Keane1d1d4382019-01-25 17:27:57 +0000399 HasFloat16 = true;
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
Oliver Stannarde3c8ce82019-02-18 12:39:47 +0000655 // ACLE position independent code macros.
656 if (Opts.ROPI)
657 Builder.defineMacro("__ARM_ROPI", "1");
658 if (Opts.RWPI)
659 Builder.defineMacro("__ARM_RWPI", "1");
660
Florian Hahnef5bbd62017-07-27 16:28:39 +0000661 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
Erich Keaneebba5922017-07-21 22:37:03 +0000662 Builder.defineMacro("__XSCALE__");
663
664 if (isThumb()) {
665 Builder.defineMacro("__THUMBEL__");
666 Builder.defineMacro("__thumb__");
667 if (supportsThumb2())
668 Builder.defineMacro("__thumb2__");
669 }
670
671 // ACLE 6.4.9 32-bit SIMD instructions
Sam Parkerd476cd32018-09-28 10:18:02 +0000672 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
Erich Keaneebba5922017-07-21 22:37:03 +0000673 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
674
675 // ACLE 6.4.10 Hardware Integer Divide
676 if (((HWDiv & HWDivThumb) && isThumb()) ||
677 ((HWDiv & HWDivARM) && !isThumb())) {
678 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
679 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
680 }
681
682 // Note, this is always on in gcc, even though it doesn't make sense.
683 Builder.defineMacro("__APCS_32__");
684
685 if (FPUModeIsVFP((FPUMode)FPU)) {
686 Builder.defineMacro("__VFP_FP__");
687 if (FPU & VFP2FPU)
688 Builder.defineMacro("__ARM_VFPV2__");
689 if (FPU & VFP3FPU)
690 Builder.defineMacro("__ARM_VFPV3__");
691 if (FPU & VFP4FPU)
692 Builder.defineMacro("__ARM_VFPV4__");
693 if (FPU & FPARMV8)
694 Builder.defineMacro("__ARM_FPV5__");
695 }
696
697 // This only gets set when Neon instructions are actually available, unlike
698 // the VFP define, hence the soft float and arch check. This is subtly
699 // different from gcc, we follow the intent which was that it should be set
700 // when Neon instructions are actually available.
701 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
702 Builder.defineMacro("__ARM_NEON", "1");
703 Builder.defineMacro("__ARM_NEON__");
704 // current AArch32 NEON implementations do not support double-precision
705 // floating-point even when it is present in VFP.
706 Builder.defineMacro("__ARM_NEON_FP",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000707 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
Erich Keaneebba5922017-07-21 22:37:03 +0000708 }
709
Saleem Abdulrasool729379a2017-10-06 23:09:55 +0000710 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
Benjamin Kramer3a13ed62017-12-28 16:58:54 +0000711 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
Erich Keaneebba5922017-07-21 22:37:03 +0000712
713 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
714
715 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
716 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
717 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
718 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
719 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
720 }
721
722 // ACLE 6.4.7 DSP instructions
723 if (DSP) {
724 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
725 }
726
727 // ACLE 6.4.8 Saturation instructions
728 bool SAT = false;
729 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
730 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
731 SAT = true;
732 }
733
734 // ACLE 6.4.6 Q (saturation) flag
735 if (DSP || SAT)
736 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
737
738 if (Opts.UnsafeFPMath)
739 Builder.defineMacro("__ARM_FP_FAST", "1");
740
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000741 // Armv8.2-A FP16 vector intrinsic
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000742 if ((FPU & NeonFPU) && HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000743 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
744
745 // Armv8.2-A FP16 scalar intrinsics
Sjoerd Meijer87793e72018-03-19 13:22:49 +0000746 if (HasLegalHalfType)
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000747 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
748
Oliver Stannard39ee9de2018-04-27 13:56:02 +0000749 // Armv8.2-A dot product intrinsics
750 if (DotProd)
751 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
Sjoerd Meijera7463df2018-03-13 22:11:06 +0000752
Erich Keaneebba5922017-07-21 22:37:03 +0000753 switch (ArchKind) {
754 default:
755 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000756 case llvm::ARM::ArchKind::ARMV8_1A:
Erich Keaneebba5922017-07-21 22:37:03 +0000757 getTargetDefinesARMV81A(Opts, Builder);
758 break;
Florian Hahnef5bbd62017-07-27 16:28:39 +0000759 case llvm::ARM::ArchKind::ARMV8_2A:
Erich Keaneebba5922017-07-21 22:37:03 +0000760 getTargetDefinesARMV82A(Opts, Builder);
761 break;
762 }
763}
764
Tim Northoverad4c5db2017-07-24 17:06:23 +0000765const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
766#define BUILTIN(ID, TYPE, ATTRS) \
767 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
768#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
769 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
770#include "clang/Basic/BuiltinsNEON.def"
Erich Keaneebba5922017-07-21 22:37:03 +0000771
Tim Northoverad4c5db2017-07-24 17:06:23 +0000772#define BUILTIN(ID, TYPE, ATTRS) \
773 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
774#define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
775 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
776#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
777 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
778#define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
779 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
780#include "clang/Basic/BuiltinsARM.def"
781};
782
783ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
784 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
785 Builtin::FirstTSBuiltin);
786}
787
788bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
789TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
790 return IsAAPCS
791 ? AAPCSABIBuiltinVaList
792 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
793 : TargetInfo::VoidPtrBuiltinVaList);
794}
795
796const char *const ARMTargetInfo::GCCRegNames[] = {
797 // Integer registers
798 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
799 "r12", "sp", "lr", "pc",
800
801 // Float registers
802 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
803 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
804 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
805
806 // Double registers
807 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
808 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
809 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
810
811 // Quad registers
812 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
813 "q12", "q13", "q14", "q15"};
814
815ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
816 return llvm::makeArrayRef(GCCRegNames);
817}
818
819const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
820 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
821 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
822 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
823 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
824 // The S, D and Q registers overlap, but aren't really aliases; we
825 // don't want to substitute one of these for a different-sized one.
826};
827
828ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
829 return llvm::makeArrayRef(GCCRegAliases);
830}
831
832bool ARMTargetInfo::validateAsmConstraint(
833 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
834 switch (*Name) {
835 default:
836 break;
837 case 'l': // r0-r7
838 case 'h': // r8-r15
839 case 't': // VFP Floating point register single precision
840 case 'w': // VFP Floating point register double precision
841 Info.setAllowsRegister();
842 return true;
843 case 'I':
844 case 'J':
845 case 'K':
846 case 'L':
847 case 'M':
848 // FIXME
849 return true;
850 case 'Q': // A memory address that is a single base register.
851 Info.setAllowsMemory();
852 return true;
853 case 'U': // a memory reference...
854 switch (Name[1]) {
855 case 'q': // ...ARMV4 ldrsb
856 case 'v': // ...VFP load/store (reg+constant offset)
857 case 'y': // ...iWMMXt load/store
858 case 't': // address valid for load/store opaque types wider
859 // than 128-bits
860 case 'n': // valid address for Neon doubleword vector load/store
861 case 'm': // valid address for Neon element and structure load/store
862 case 's': // valid address for non-offset loads/stores of quad-word
863 // values in four ARM registers
864 Info.setAllowsMemory();
865 Name++;
866 return true;
Erich Keaneebba5922017-07-21 22:37:03 +0000867 }
868 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000869 return false;
870}
Erich Keaneebba5922017-07-21 22:37:03 +0000871
Tim Northoverad4c5db2017-07-24 17:06:23 +0000872std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
873 std::string R;
874 switch (*Constraint) {
875 case 'U': // Two-character constraint; add "^" hint for later parsing.
876 R = std::string("^") + std::string(Constraint, 2);
877 Constraint++;
Erich Keaneebba5922017-07-21 22:37:03 +0000878 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000879 case 'p': // 'p' should be translated to 'r' by default.
880 R = std::string("r");
Erich Keaneebba5922017-07-21 22:37:03 +0000881 break;
Tim Northoverad4c5db2017-07-24 17:06:23 +0000882 default:
883 return std::string(1, *Constraint);
Erich Keaneebba5922017-07-21 22:37:03 +0000884 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000885 return R;
886}
Erich Keaneebba5922017-07-21 22:37:03 +0000887
Tim Northoverad4c5db2017-07-24 17:06:23 +0000888bool ARMTargetInfo::validateConstraintModifier(
889 StringRef Constraint, char Modifier, unsigned Size,
890 std::string &SuggestedModifier) const {
891 bool isOutput = (Constraint[0] == '=');
892 bool isInOut = (Constraint[0] == '+');
893
894 // Strip off constraint modifiers.
895 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
896 Constraint = Constraint.substr(1);
897
898 switch (Constraint[0]) {
899 default:
900 break;
901 case 'r': {
902 switch (Modifier) {
903 default:
904 return (isInOut || isOutput || Size <= 64);
905 case 'q':
906 // A register of size 32 cannot fit a vector type.
907 return false;
908 }
Erich Keaneebba5922017-07-21 22:37:03 +0000909 }
Tim Northoverad4c5db2017-07-24 17:06:23 +0000910 }
Erich Keaneebba5922017-07-21 22:37:03 +0000911
912 return true;
913}
Tim Northoverad4c5db2017-07-24 17:06:23 +0000914const char *ARMTargetInfo::getClobbers() const {
915 // FIXME: Is this really right?
916 return "";
Erich Keaneebba5922017-07-21 22:37:03 +0000917}
918
Tim Northoverad4c5db2017-07-24 17:06:23 +0000919TargetInfo::CallingConvCheckResult
920ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
921 switch (CC) {
922 case CC_AAPCS:
923 case CC_AAPCS_VFP:
924 case CC_Swift:
925 case CC_OpenCLKernel:
926 return CCCR_OK;
927 default:
928 return CCCR_Warning;
929 }
930}
931
932int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
933 if (RegNo == 0)
934 return 0;
935 if (RegNo == 1)
936 return 1;
937 return -1;
938}
939
940bool ARMTargetInfo::hasSjLjLowering() const { return true; }
941
942ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
943 const TargetOptions &Opts)
944 : ARMTargetInfo(Triple, Opts) {}
945
Erich Keaneebba5922017-07-21 22:37:03 +0000946void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
947 MacroBuilder &Builder) const {
948 Builder.defineMacro("__ARMEL__");
949 ARMTargetInfo::getTargetDefines(Opts, Builder);
950}
951
Tim Northoverad4c5db2017-07-24 17:06:23 +0000952ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
953 const TargetOptions &Opts)
954 : ARMTargetInfo(Triple, Opts) {}
955
Erich Keaneebba5922017-07-21 22:37:03 +0000956void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
957 MacroBuilder &Builder) const {
958 Builder.defineMacro("__ARMEB__");
959 Builder.defineMacro("__ARM_BIG_ENDIAN");
960 ARMTargetInfo::getTargetDefines(Opts, Builder);
961}
962
Tim Northoverad4c5db2017-07-24 17:06:23 +0000963WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
964 const TargetOptions &Opts)
965 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
Tim Northoverad4c5db2017-07-24 17:06:23 +0000966}
967
Erich Keaneebba5922017-07-21 22:37:03 +0000968void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
969 MacroBuilder &Builder) const {
970 WindowsTargetInfo<ARMleTargetInfo>::getVisualStudioDefines(Opts, Builder);
971
972 // FIXME: this is invalid for WindowsCE
973 Builder.defineMacro("_M_ARM_NT", "1");
974 Builder.defineMacro("_M_ARMT", "_M_ARM");
975 Builder.defineMacro("_M_THUMB", "_M_ARM");
976
977 assert((Triple.getArch() == llvm::Triple::arm ||
978 Triple.getArch() == llvm::Triple::thumb) &&
979 "invalid architecture for Windows ARM target info");
980 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
981 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
982
983 // TODO map the complete set of values
984 // 31: VFPv3 40: VFPv4
985 Builder.defineMacro("_M_ARM_FP", "31");
986}
987
Tim Northoverad4c5db2017-07-24 17:06:23 +0000988TargetInfo::BuiltinVaListKind
989WindowsARMTargetInfo::getBuiltinVaListKind() const {
990 return TargetInfo::CharPtrBuiltinVaList;
991}
992
993TargetInfo::CallingConvCheckResult
994WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
995 switch (CC) {
996 case CC_X86StdCall:
997 case CC_X86ThisCall:
998 case CC_X86FastCall:
999 case CC_X86VectorCall:
1000 return CCCR_Ignore;
1001 case CC_C:
1002 case CC_OpenCLKernel:
Saleem Abdulrasool29149d52018-03-20 17:33:26 +00001003 case CC_PreserveMost:
1004 case CC_PreserveAll:
Saleem Abdulrasoolf5878572018-12-06 03:28:37 +00001005 case CC_Swift:
Tim Northoverad4c5db2017-07-24 17:06:23 +00001006 return CCCR_OK;
1007 default:
1008 return CCCR_Warning;
1009 }
1010}
1011
1012// Windows ARM + Itanium C++ ABI Target
1013ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1014 const llvm::Triple &Triple, const TargetOptions &Opts)
1015 : WindowsARMTargetInfo(Triple, Opts) {
1016 TheCXXABI.set(TargetCXXABI::GenericARM);
1017}
1018
1019void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1020 const LangOptions &Opts, MacroBuilder &Builder) const {
1021 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1022
1023 if (Opts.MSVCCompat)
1024 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1025}
1026
1027// Windows ARM, MS (C++) ABI
1028MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1029 const TargetOptions &Opts)
1030 : WindowsARMTargetInfo(Triple, Opts) {
1031 TheCXXABI.set(TargetCXXABI::Microsoft);
1032}
1033
1034void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1035 MacroBuilder &Builder) const {
1036 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1037 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1038}
1039
1040MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1041 const TargetOptions &Opts)
1042 : WindowsARMTargetInfo(Triple, Opts) {
1043 TheCXXABI.set(TargetCXXABI::GenericARM);
1044}
1045
Erich Keaneebba5922017-07-21 22:37:03 +00001046void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1047 MacroBuilder &Builder) const {
1048 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
Erich Keaneebba5922017-07-21 22:37:03 +00001049 Builder.defineMacro("_ARM_");
Erich Keaneebba5922017-07-21 22:37:03 +00001050}
1051
Tim Northoverad4c5db2017-07-24 17:06:23 +00001052CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1053 const TargetOptions &Opts)
1054 : ARMleTargetInfo(Triple, Opts) {
Saleem Abdulrasool729379a2017-10-06 23:09:55 +00001055 this->WCharType = TargetInfo::UnsignedShort;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001056 TLSSupported = false;
Tim Northoverad4c5db2017-07-24 17:06:23 +00001057 DoubleAlign = LongLongAlign = 64;
1058 resetDataLayout("e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64");
1059}
1060
Erich Keaneebba5922017-07-21 22:37:03 +00001061void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1062 MacroBuilder &Builder) const {
1063 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1064 Builder.defineMacro("_ARM_");
1065 Builder.defineMacro("__CYGWIN__");
1066 Builder.defineMacro("__CYGWIN32__");
1067 DefineStd(Builder, "unix", Opts);
1068 if (Opts.CPlusPlus)
1069 Builder.defineMacro("_GNU_SOURCE");
1070}
1071
Tim Northoverad4c5db2017-07-24 17:06:23 +00001072DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1073 const TargetOptions &Opts)
1074 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1075 HasAlignMac68kSupport = true;
1076 // iOS always has 64-bit atomic instructions.
1077 // FIXME: This should be based off of the target features in
1078 // ARMleTargetInfo.
1079 MaxAtomicInlineWidth = 64;
1080
1081 if (Triple.isWatchABI()) {
1082 // Darwin on iOS uses a variant of the ARM C++ ABI.
1083 TheCXXABI.set(TargetCXXABI::WatchOS);
1084
Tim Northoverad4c5db2017-07-24 17:06:23 +00001085 // BOOL should be a real boolean on the new ABI
1086 UseSignedCharForObjCBool = false;
1087 } else
1088 TheCXXABI.set(TargetCXXABI::iOS);
1089}
1090
1091void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1092 const llvm::Triple &Triple,
1093 MacroBuilder &Builder) const {
1094 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1095}
1096
1097RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1098 const TargetOptions &Opts)
1099 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1100 Triple.getOSName(),
1101 Triple.getEnvironmentName()),
1102 Opts) {
1103 IsRenderScriptTarget = true;
1104 LongWidth = LongAlign = 64;
1105}
1106
Erich Keaneebba5922017-07-21 22:37:03 +00001107void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1108 MacroBuilder &Builder) const {
1109 Builder.defineMacro("__RENDERSCRIPT__");
1110 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1111}