1 //===--- ARM.cpp - Implement ARM target feature support -------------------===//
2 //
3 // 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
6 //
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
21 using namespace clang;
22 using namespace clang::targets;
23
setABIAAPCS()24 void ARMTargetInfo::setABIAAPCS() {
25 IsAAPCS = true;
26
27 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
28 BFloat16Width = BFloat16Align = 16;
29 BFloat16Format = &llvm::APFloat::BFloat();
30
31 const llvm::Triple &T = getTriple();
32
33 bool IsNetBSD = T.isOSNetBSD();
34 bool IsOpenBSD = T.isOSOpenBSD();
35 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD)
36 WCharType = UnsignedInt;
37
38 UseBitFieldTypeAlignment = true;
39
40 ZeroLengthBitfieldBoundary = 0;
41
42 // Thumb1 add sp, #imm requires the immediate value be multiple of 4,
43 // so set preferred for small types to 32.
44 if (T.isOSBinFormatMachO()) {
45 resetDataLayout(BigEndian
46 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
47 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
48 } else if (T.isOSWindows()) {
49 assert(!BigEndian && "Windows on ARM does not support big endian");
50 resetDataLayout("e"
51 "-m:w"
52 "-p:32:32"
53 "-Fi8"
54 "-i64:64"
55 "-v128:64:128"
56 "-a:0:32"
57 "-n32"
58 "-S64");
59 } else if (T.isOSNaCl()) {
60 assert(!BigEndian && "NaCl on ARM does not support big endian");
61 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128");
62 } else {
63 resetDataLayout(BigEndian
64 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"
65 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
66 }
67
68 // FIXME: Enumerated types are variable width in straight AAPCS.
69 }
70
setABIAPCS(bool IsAAPCS16)71 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) {
72 const llvm::Triple &T = getTriple();
73
74 IsAAPCS = false;
75
76 if (IsAAPCS16)
77 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64;
78 else
79 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32;
80 BFloat16Width = BFloat16Align = 16;
81 BFloat16Format = &llvm::APFloat::BFloat();
82
83 WCharType = SignedInt;
84
85 // Do not respect the alignment of bit-field types when laying out
86 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc.
87 UseBitFieldTypeAlignment = false;
88
89 /// gcc forces the alignment to 4 bytes, regardless of the type of the
90 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in
91 /// gcc.
92 ZeroLengthBitfieldBoundary = 32;
93
94 if (T.isOSBinFormatMachO() && IsAAPCS16) {
95 assert(!BigEndian && "AAPCS16 does not support big-endian");
96 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128");
97 } else if (T.isOSBinFormatMachO())
98 resetDataLayout(
99 BigEndian
100 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
101 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
102 else
103 resetDataLayout(
104 BigEndian
105 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"
106 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32");
107
108 // FIXME: Override "preferred align" for double and long long.
109 }
110
setArchInfo()111 void ARMTargetInfo::setArchInfo() {
112 StringRef ArchName = getTriple().getArchName();
113
114 ArchISA = llvm::ARM::parseArchISA(ArchName);
115 CPU = std::string(llvm::ARM::getDefaultCPU(ArchName));
116 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName);
117 if (AK != llvm::ARM::ArchKind::INVALID)
118 ArchKind = AK;
119 setArchInfo(ArchKind);
120 }
121
setArchInfo(llvm::ARM::ArchKind Kind)122 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) {
123 StringRef SubArch;
124
125 // cache TargetParser info
126 ArchKind = Kind;
127 SubArch = llvm::ARM::getSubArch(ArchKind);
128 ArchProfile = llvm::ARM::parseArchProfile(SubArch);
129 ArchVersion = llvm::ARM::parseArchVersion(SubArch);
130
131 // cache CPU related strings
132 CPUAttr = getCPUAttr();
133 CPUProfile = getCPUProfile();
134 }
135
setAtomic()136 void ARMTargetInfo::setAtomic() {
137 // when triple does not specify a sub arch,
138 // then we are not using inline atomics
139 bool ShouldUseInlineAtomic =
140 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) ||
141 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7);
142 // Cortex M does not support 8 byte atomics, while general Thumb2 does.
143 if (ArchProfile == llvm::ARM::ProfileKind::M) {
144 MaxAtomicPromoteWidth = 32;
145 if (ShouldUseInlineAtomic)
146 MaxAtomicInlineWidth = 32;
147 } else {
148 MaxAtomicPromoteWidth = 64;
149 if (ShouldUseInlineAtomic)
150 MaxAtomicInlineWidth = 64;
151 }
152 }
153
hasMVE() const154 bool ARMTargetInfo::hasMVE() const {
155 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0;
156 }
157
hasMVEFloat() const158 bool ARMTargetInfo::hasMVEFloat() const {
159 return hasMVE() && (MVE & MVE_FP);
160 }
161
hasCDE() const162 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; }
163
isThumb() const164 bool ARMTargetInfo::isThumb() const {
165 return ArchISA == llvm::ARM::ISAKind::THUMB;
166 }
167
supportsThumb() const168 bool ARMTargetInfo::supportsThumb() const {
169 return CPUAttr.count('T') || ArchVersion >= 6;
170 }
171
supportsThumb2() const172 bool ARMTargetInfo::supportsThumb2() const {
173 return CPUAttr.equals("6T2") ||
174 (ArchVersion >= 7 && !CPUAttr.equals("8M_BASE"));
175 }
176
getCPUAttr() const177 StringRef ARMTargetInfo::getCPUAttr() const {
178 // For most sub-arches, the build attribute CPU name is enough.
179 // For Cortex variants, it's slightly different.
180 switch (ArchKind) {
181 default:
182 return llvm::ARM::getCPUAttr(ArchKind);
183 case llvm::ARM::ArchKind::ARMV6M:
184 return "6M";
185 case llvm::ARM::ArchKind::ARMV7S:
186 return "7S";
187 case llvm::ARM::ArchKind::ARMV7A:
188 return "7A";
189 case llvm::ARM::ArchKind::ARMV7R:
190 return "7R";
191 case llvm::ARM::ArchKind::ARMV7M:
192 return "7M";
193 case llvm::ARM::ArchKind::ARMV7EM:
194 return "7EM";
195 case llvm::ARM::ArchKind::ARMV7VE:
196 return "7VE";
197 case llvm::ARM::ArchKind::ARMV8A:
198 return "8A";
199 case llvm::ARM::ArchKind::ARMV8_1A:
200 return "8_1A";
201 case llvm::ARM::ArchKind::ARMV8_2A:
202 return "8_2A";
203 case llvm::ARM::ArchKind::ARMV8_3A:
204 return "8_3A";
205 case llvm::ARM::ArchKind::ARMV8_4A:
206 return "8_4A";
207 case llvm::ARM::ArchKind::ARMV8_5A:
208 return "8_5A";
209 case llvm::ARM::ArchKind::ARMV8_6A:
210 return "8_6A";
211 case llvm::ARM::ArchKind::ARMV8_7A:
212 return "8_7A";
213 case llvm::ARM::ArchKind::ARMV8MBaseline:
214 return "8M_BASE";
215 case llvm::ARM::ArchKind::ARMV8MMainline:
216 return "8M_MAIN";
217 case llvm::ARM::ArchKind::ARMV8R:
218 return "8R";
219 case llvm::ARM::ArchKind::ARMV8_1MMainline:
220 return "8_1M_MAIN";
221 }
222 }
223
getCPUProfile() const224 StringRef ARMTargetInfo::getCPUProfile() const {
225 switch (ArchProfile) {
226 case llvm::ARM::ProfileKind::A:
227 return "A";
228 case llvm::ARM::ProfileKind::R:
229 return "R";
230 case llvm::ARM::ProfileKind::M:
231 return "M";
232 default:
233 return "";
234 }
235 }
236
ARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)237 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple,
238 const TargetOptions &Opts)
239 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0),
240 HW_FP(0) {
241 bool IsOpenBSD = Triple.isOSOpenBSD();
242 bool IsNetBSD = Triple.isOSNetBSD();
243
244 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like
245 // environment where size_t is `unsigned long` rather than `unsigned int`
246
247 PtrDiffType = IntPtrType =
248 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
249 IsNetBSD)
250 ? SignedLong
251 : SignedInt;
252
253 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD ||
254 IsNetBSD)
255 ? UnsignedLong
256 : UnsignedInt;
257
258 // ptrdiff_t is inconsistent on Darwin
259 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) &&
260 !Triple.isWatchABI())
261 PtrDiffType = SignedInt;
262
263 // Cache arch related info.
264 setArchInfo();
265
266 // {} in inline assembly are neon specifiers, not assembly variant
267 // specifiers.
268 NoAsmVariants = true;
269
270 // FIXME: This duplicates code from the driver that sets the -target-abi
271 // option - this code is used if -target-abi isn't passed and should
272 // be unified in some way.
273 if (Triple.isOSBinFormatMachO()) {
274 // The backend is hardwired to assume AAPCS for M-class processors, ensure
275 // the frontend matches that.
276 if (Triple.getEnvironment() == llvm::Triple::EABI ||
277 Triple.getOS() == llvm::Triple::UnknownOS ||
278 ArchProfile == llvm::ARM::ProfileKind::M) {
279 setABI("aapcs");
280 } else if (Triple.isWatchABI()) {
281 setABI("aapcs16");
282 } else {
283 setABI("apcs-gnu");
284 }
285 } else if (Triple.isOSWindows()) {
286 // FIXME: this is invalid for WindowsCE
287 setABI("aapcs");
288 } else {
289 // Select the default based on the platform.
290 switch (Triple.getEnvironment()) {
291 case llvm::Triple::Android:
292 case llvm::Triple::GNUEABI:
293 case llvm::Triple::GNUEABIHF:
294 case llvm::Triple::MuslEABI:
295 case llvm::Triple::MuslEABIHF:
296 setABI("aapcs-linux");
297 break;
298 case llvm::Triple::EABIHF:
299 case llvm::Triple::EABI:
300 setABI("aapcs");
301 break;
302 case llvm::Triple::GNU:
303 setABI("apcs-gnu");
304 break;
305 default:
306 if (IsNetBSD)
307 setABI("apcs-gnu");
308 else if (IsOpenBSD)
309 setABI("aapcs-linux");
310 else
311 setABI("aapcs");
312 break;
313 }
314 }
315
316 // ARM targets default to using the ARM C++ ABI.
317 TheCXXABI.set(TargetCXXABI::GenericARM);
318
319 // ARM has atomics up to 8 bytes
320 setAtomic();
321
322 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS)
323 // as well the default alignment
324 if (IsAAPCS && !Triple.isAndroid())
325 DefaultAlignForAttributeAligned = MaxVectorAlign = 64;
326
327 // Do force alignment of members that follow zero length bitfields. If
328 // the alignment of the zero-length bitfield is greater than the member
329 // that follows it, `bar', `bar' will be aligned as the type of the
330 // zero length bitfield.
331 UseZeroLengthBitfieldAlignment = true;
332
333 if (Triple.getOS() == llvm::Triple::Linux ||
334 Triple.getOS() == llvm::Triple::UnknownOS)
335 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU
336 ? "llvm.arm.gnu.eabi.mcount"
337 : "\01mcount";
338
339 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi");
340 }
341
getABI() const342 StringRef ARMTargetInfo::getABI() const { return ABI; }
343
setABI(const std::string & Name)344 bool ARMTargetInfo::setABI(const std::string &Name) {
345 ABI = Name;
346
347 // The defaults (above) are for AAPCS, check if we need to change them.
348 //
349 // FIXME: We need support for -meabi... we could just mangle it into the
350 // name.
351 if (Name == "apcs-gnu" || Name == "aapcs16") {
352 setABIAPCS(Name == "aapcs16");
353 return true;
354 }
355 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") {
356 setABIAAPCS();
357 return true;
358 }
359 return false;
360 }
361
362 // FIXME: This should be based on Arch attributes, not CPU names.
initFeatureMap(llvm::StringMap<bool> & Features,DiagnosticsEngine & Diags,StringRef CPU,const std::vector<std::string> & FeaturesVec) const363 bool ARMTargetInfo::initFeatureMap(
364 llvm::StringMap<bool> &Features, DiagnosticsEngine &Diags, StringRef CPU,
365 const std::vector<std::string> &FeaturesVec) const {
366
367 std::string ArchFeature;
368 std::vector<StringRef> TargetFeatures;
369 llvm::ARM::ArchKind Arch = llvm::ARM::parseArch(getTriple().getArchName());
370
371 // Map the base architecture to an appropriate target feature, so we don't
372 // rely on the target triple.
373 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(CPU);
374 if (CPUArch == llvm::ARM::ArchKind::INVALID)
375 CPUArch = Arch;
376 if (CPUArch != llvm::ARM::ArchKind::INVALID) {
377 ArchFeature = ("+" + llvm::ARM::getArchName(CPUArch)).str();
378 TargetFeatures.push_back(ArchFeature);
379 }
380
381 // get default FPU features
382 unsigned FPUKind = llvm::ARM::getDefaultFPU(CPU, Arch);
383 llvm::ARM::getFPUFeatures(FPUKind, TargetFeatures);
384
385 // get default Extension features
386 uint64_t Extensions = llvm::ARM::getDefaultExtensions(CPU, Arch);
387 llvm::ARM::getExtensionFeatures(Extensions, TargetFeatures);
388
389 for (auto Feature : TargetFeatures)
390 if (Feature[0] == '+')
391 Features[Feature.drop_front(1)] = true;
392
393 // Enable or disable thumb-mode explicitly per function to enable mixed
394 // ARM and Thumb code generation.
395 if (isThumb())
396 Features["thumb-mode"] = true;
397 else
398 Features["thumb-mode"] = false;
399
400 // Convert user-provided arm and thumb GNU target attributes to
401 // [-|+]thumb-mode target features respectively.
402 std::vector<std::string> UpdatedFeaturesVec;
403 for (const auto &Feature : FeaturesVec) {
404 // Skip soft-float-abi; it's something we only use to initialize a bit of
405 // class state, and is otherwise unrecognized.
406 if (Feature == "+soft-float-abi")
407 continue;
408
409 StringRef FixedFeature;
410 if (Feature == "+arm")
411 FixedFeature = "-thumb-mode";
412 else if (Feature == "+thumb")
413 FixedFeature = "+thumb-mode";
414 else
415 FixedFeature = Feature;
416 UpdatedFeaturesVec.push_back(FixedFeature.str());
417 }
418
419 return TargetInfo::initFeatureMap(Features, Diags, CPU, UpdatedFeaturesVec);
420 }
421
422
handleTargetFeatures(std::vector<std::string> & Features,DiagnosticsEngine & Diags)423 bool ARMTargetInfo::handleTargetFeatures(std::vector<std::string> &Features,
424 DiagnosticsEngine &Diags) {
425 FPU = 0;
426 MVE = 0;
427 CRC = 0;
428 Crypto = 0;
429 DSP = 0;
430 Unaligned = 1;
431 SoftFloat = false;
432 // Note that SoftFloatABI is initialized in our constructor.
433 HWDiv = 0;
434 DotProd = 0;
435 HasMatMul = 0;
436 HasFloat16 = true;
437 ARMCDECoprocMask = 0;
438 HasBFloat16 = false;
439
440 // This does not diagnose illegal cases like having both
441 // "+vfpv2" and "+vfpv3" or having "+neon" and "-fp64".
442 for (const auto &Feature : Features) {
443 if (Feature == "+soft-float") {
444 SoftFloat = true;
445 } else if (Feature == "+vfp2sp" || Feature == "+vfp2") {
446 FPU |= VFP2FPU;
447 HW_FP |= HW_FP_SP;
448 if (Feature == "+vfp2")
449 HW_FP |= HW_FP_DP;
450 } else if (Feature == "+vfp3sp" || Feature == "+vfp3d16sp" ||
451 Feature == "+vfp3" || Feature == "+vfp3d16") {
452 FPU |= VFP3FPU;
453 HW_FP |= HW_FP_SP;
454 if (Feature == "+vfp3" || Feature == "+vfp3d16")
455 HW_FP |= HW_FP_DP;
456 } else if (Feature == "+vfp4sp" || Feature == "+vfp4d16sp" ||
457 Feature == "+vfp4" || Feature == "+vfp4d16") {
458 FPU |= VFP4FPU;
459 HW_FP |= HW_FP_SP | HW_FP_HP;
460 if (Feature == "+vfp4" || Feature == "+vfp4d16")
461 HW_FP |= HW_FP_DP;
462 } else if (Feature == "+fp-armv8sp" || Feature == "+fp-armv8d16sp" ||
463 Feature == "+fp-armv8" || Feature == "+fp-armv8d16") {
464 FPU |= FPARMV8;
465 HW_FP |= HW_FP_SP | HW_FP_HP;
466 if (Feature == "+fp-armv8" || Feature == "+fp-armv8d16")
467 HW_FP |= HW_FP_DP;
468 } else if (Feature == "+neon") {
469 FPU |= NeonFPU;
470 HW_FP |= HW_FP_SP;
471 } else if (Feature == "+hwdiv") {
472 HWDiv |= HWDivThumb;
473 } else if (Feature == "+hwdiv-arm") {
474 HWDiv |= HWDivARM;
475 } else if (Feature == "+crc") {
476 CRC = 1;
477 } else if (Feature == "+crypto") {
478 Crypto = 1;
479 } else if (Feature == "+dsp") {
480 DSP = 1;
481 } else if (Feature == "+fp64") {
482 HW_FP |= HW_FP_DP;
483 } else if (Feature == "+8msecext") {
484 if (CPUProfile != "M" || ArchVersion != 8) {
485 Diags.Report(diag::err_target_unsupported_mcmse) << CPU;
486 return false;
487 }
488 } else if (Feature == "+strict-align") {
489 Unaligned = 0;
490 } else if (Feature == "+fp16") {
491 HW_FP |= HW_FP_HP;
492 } else if (Feature == "+fullfp16") {
493 HasLegalHalfType = true;
494 } else if (Feature == "+dotprod") {
495 DotProd = true;
496 } else if (Feature == "+mve") {
497 MVE |= MVE_INT;
498 } else if (Feature == "+mve.fp") {
499 HasLegalHalfType = true;
500 FPU |= FPARMV8;
501 MVE |= MVE_INT | MVE_FP;
502 HW_FP |= HW_FP_SP | HW_FP_HP;
503 } else if (Feature == "+i8mm") {
504 HasMatMul = 1;
505 } else if (Feature.size() == strlen("+cdecp0") && Feature >= "+cdecp0" &&
506 Feature <= "+cdecp7") {
507 unsigned Coproc = Feature.back() - '0';
508 ARMCDECoprocMask |= (1U << Coproc);
509 } else if (Feature == "+bf16") {
510 HasBFloat16 = true;
511 }
512 }
513
514 switch (ArchVersion) {
515 case 6:
516 if (ArchProfile == llvm::ARM::ProfileKind::M)
517 LDREX = 0;
518 else if (ArchKind == llvm::ARM::ArchKind::ARMV6K)
519 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
520 else
521 LDREX = LDREX_W;
522 break;
523 case 7:
524 if (ArchProfile == llvm::ARM::ProfileKind::M)
525 LDREX = LDREX_W | LDREX_H | LDREX_B;
526 else
527 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
528 break;
529 case 8:
530 LDREX = LDREX_D | LDREX_W | LDREX_H | LDREX_B;
531 }
532
533 if (!(FPU & NeonFPU) && FPMath == FP_Neon) {
534 Diags.Report(diag::err_target_unsupported_fpmath) << "neon";
535 return false;
536 }
537
538 if (FPMath == FP_Neon)
539 Features.push_back("+neonfp");
540 else if (FPMath == FP_VFP)
541 Features.push_back("-neonfp");
542
543 return true;
544 }
545
hasFeature(StringRef Feature) const546 bool ARMTargetInfo::hasFeature(StringRef Feature) const {
547 return llvm::StringSwitch<bool>(Feature)
548 .Case("arm", true)
549 .Case("aarch32", true)
550 .Case("softfloat", SoftFloat)
551 .Case("thumb", isThumb())
552 .Case("neon", (FPU & NeonFPU) && !SoftFloat)
553 .Case("vfp", FPU && !SoftFloat)
554 .Case("hwdiv", HWDiv & HWDivThumb)
555 .Case("hwdiv-arm", HWDiv & HWDivARM)
556 .Case("mve", hasMVE())
557 .Default(false);
558 }
559
hasBFloat16Type() const560 bool ARMTargetInfo::hasBFloat16Type() const {
561 return HasBFloat16 && !SoftFloat;
562 }
563
isValidCPUName(StringRef Name) const564 bool ARMTargetInfo::isValidCPUName(StringRef Name) const {
565 return Name == "generic" ||
566 llvm::ARM::parseCPUArch(Name) != llvm::ARM::ArchKind::INVALID;
567 }
568
fillValidCPUList(SmallVectorImpl<StringRef> & Values) const569 void ARMTargetInfo::fillValidCPUList(SmallVectorImpl<StringRef> &Values) const {
570 llvm::ARM::fillValidCPUArchList(Values);
571 }
572
setCPU(const std::string & Name)573 bool ARMTargetInfo::setCPU(const std::string &Name) {
574 if (Name != "generic")
575 setArchInfo(llvm::ARM::parseCPUArch(Name));
576
577 if (ArchKind == llvm::ARM::ArchKind::INVALID)
578 return false;
579 setAtomic();
580 CPU = Name;
581 return true;
582 }
583
setFPMath(StringRef Name)584 bool ARMTargetInfo::setFPMath(StringRef Name) {
585 if (Name == "neon") {
586 FPMath = FP_Neon;
587 return true;
588 } else if (Name == "vfp" || Name == "vfp2" || Name == "vfp3" ||
589 Name == "vfp4") {
590 FPMath = FP_VFP;
591 return true;
592 }
593 return false;
594 }
595
getTargetDefinesARMV81A(const LangOptions & Opts,MacroBuilder & Builder) const596 void ARMTargetInfo::getTargetDefinesARMV81A(const LangOptions &Opts,
597 MacroBuilder &Builder) const {
598 Builder.defineMacro("__ARM_FEATURE_QRDMX", "1");
599 }
600
getTargetDefinesARMV82A(const LangOptions & Opts,MacroBuilder & Builder) const601 void ARMTargetInfo::getTargetDefinesARMV82A(const LangOptions &Opts,
602 MacroBuilder &Builder) const {
603 // Also include the ARMv8.1-A defines
604 getTargetDefinesARMV81A(Opts, Builder);
605 }
606
getTargetDefinesARMV83A(const LangOptions & Opts,MacroBuilder & Builder) const607 void ARMTargetInfo::getTargetDefinesARMV83A(const LangOptions &Opts,
608 MacroBuilder &Builder) const {
609 // Also include the ARMv8.2-A defines
610 Builder.defineMacro("__ARM_FEATURE_COMPLEX", "1");
611 getTargetDefinesARMV82A(Opts, Builder);
612 }
613
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const614 void ARMTargetInfo::getTargetDefines(const LangOptions &Opts,
615 MacroBuilder &Builder) const {
616 // Target identification.
617 Builder.defineMacro("__arm");
618 Builder.defineMacro("__arm__");
619 // For bare-metal none-eabi.
620 if (getTriple().getOS() == llvm::Triple::UnknownOS &&
621 (getTriple().getEnvironment() == llvm::Triple::EABI ||
622 getTriple().getEnvironment() == llvm::Triple::EABIHF))
623 Builder.defineMacro("__ELF__");
624
625 // Target properties.
626 Builder.defineMacro("__REGISTER_PREFIX__", "");
627
628 // Unfortunately, __ARM_ARCH_7K__ is now more of an ABI descriptor. The CPU
629 // happens to be Cortex-A7 though, so it should still get __ARM_ARCH_7A__.
630 if (getTriple().isWatchABI())
631 Builder.defineMacro("__ARM_ARCH_7K__", "2");
632
633 if (!CPUAttr.empty())
634 Builder.defineMacro("__ARM_ARCH_" + CPUAttr + "__");
635
636 // ACLE 6.4.1 ARM/Thumb instruction set architecture
637 // __ARM_ARCH is defined as an integer value indicating the current ARM ISA
638 Builder.defineMacro("__ARM_ARCH", Twine(ArchVersion));
639
640 if (ArchVersion >= 8) {
641 // ACLE 6.5.7 Crypto Extension
642 if (Crypto)
643 Builder.defineMacro("__ARM_FEATURE_CRYPTO", "1");
644 // ACLE 6.5.8 CRC32 Extension
645 if (CRC)
646 Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
647 // ACLE 6.5.10 Numeric Maximum and Minimum
648 Builder.defineMacro("__ARM_FEATURE_NUMERIC_MAXMIN", "1");
649 // ACLE 6.5.9 Directed Rounding
650 Builder.defineMacro("__ARM_FEATURE_DIRECTED_ROUNDING", "1");
651 }
652
653 // __ARM_ARCH_ISA_ARM is defined to 1 if the core supports the ARM ISA. It
654 // is not defined for the M-profile.
655 // NOTE that the default profile is assumed to be 'A'
656 if (CPUProfile.empty() || ArchProfile != llvm::ARM::ProfileKind::M)
657 Builder.defineMacro("__ARM_ARCH_ISA_ARM", "1");
658
659 // __ARM_ARCH_ISA_THUMB is defined to 1 if the core supports the original
660 // Thumb ISA (including v6-M and v8-M Baseline). It is set to 2 if the
661 // core supports the Thumb-2 ISA as found in the v6T2 architecture and all
662 // v7 and v8 architectures excluding v8-M Baseline.
663 if (supportsThumb2())
664 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "2");
665 else if (supportsThumb())
666 Builder.defineMacro("__ARM_ARCH_ISA_THUMB", "1");
667
668 // __ARM_32BIT_STATE is defined to 1 if code is being generated for a 32-bit
669 // instruction set such as ARM or Thumb.
670 Builder.defineMacro("__ARM_32BIT_STATE", "1");
671
672 // ACLE 6.4.2 Architectural Profile (A, R, M or pre-Cortex)
673
674 // __ARM_ARCH_PROFILE is defined as 'A', 'R', 'M' or 'S', or unset.
675 if (!CPUProfile.empty())
676 Builder.defineMacro("__ARM_ARCH_PROFILE", "'" + CPUProfile + "'");
677
678 // ACLE 6.4.3 Unaligned access supported in hardware
679 if (Unaligned)
680 Builder.defineMacro("__ARM_FEATURE_UNALIGNED", "1");
681
682 // ACLE 6.4.4 LDREX/STREX
683 if (LDREX)
684 Builder.defineMacro("__ARM_FEATURE_LDREX", "0x" + Twine::utohexstr(LDREX));
685
686 // ACLE 6.4.5 CLZ
687 if (ArchVersion == 5 || (ArchVersion == 6 && CPUProfile != "M") ||
688 ArchVersion > 6)
689 Builder.defineMacro("__ARM_FEATURE_CLZ", "1");
690
691 // ACLE 6.5.1 Hardware Floating Point
692 if (HW_FP)
693 Builder.defineMacro("__ARM_FP", "0x" + Twine::utohexstr(HW_FP));
694
695 // ACLE predefines.
696 Builder.defineMacro("__ARM_ACLE", "200");
697
698 // FP16 support (we currently only support IEEE format).
699 Builder.defineMacro("__ARM_FP16_FORMAT_IEEE", "1");
700 Builder.defineMacro("__ARM_FP16_ARGS", "1");
701
702 // ACLE 6.5.3 Fused multiply-accumulate (FMA)
703 if (ArchVersion >= 7 && (FPU & VFP4FPU))
704 Builder.defineMacro("__ARM_FEATURE_FMA", "1");
705
706 // Subtarget options.
707
708 // FIXME: It's more complicated than this and we don't really support
709 // interworking.
710 // Windows on ARM does not "support" interworking
711 if (5 <= ArchVersion && ArchVersion <= 8 && !getTriple().isOSWindows())
712 Builder.defineMacro("__THUMB_INTERWORK__");
713
714 if (ABI == "aapcs" || ABI == "aapcs-linux" || ABI == "aapcs-vfp") {
715 // Embedded targets on Darwin follow AAPCS, but not EABI.
716 // Windows on ARM follows AAPCS VFP, but does not conform to EABI.
717 if (!getTriple().isOSBinFormatMachO() && !getTriple().isOSWindows())
718 Builder.defineMacro("__ARM_EABI__");
719 Builder.defineMacro("__ARM_PCS", "1");
720 }
721
722 if ((!SoftFloat && !SoftFloatABI) || ABI == "aapcs-vfp" || ABI == "aapcs16")
723 Builder.defineMacro("__ARM_PCS_VFP", "1");
724
725 if (SoftFloat)
726 Builder.defineMacro("__SOFTFP__");
727
728 // ACLE position independent code macros.
729 if (Opts.ROPI)
730 Builder.defineMacro("__ARM_ROPI", "1");
731 if (Opts.RWPI)
732 Builder.defineMacro("__ARM_RWPI", "1");
733
734 if (ArchKind == llvm::ARM::ArchKind::XSCALE)
735 Builder.defineMacro("__XSCALE__");
736
737 if (isThumb()) {
738 Builder.defineMacro("__THUMBEL__");
739 Builder.defineMacro("__thumb__");
740 if (supportsThumb2())
741 Builder.defineMacro("__thumb2__");
742 }
743
744 // ACLE 6.4.9 32-bit SIMD instructions
745 if ((CPUProfile != "M" && ArchVersion >= 6) || (CPUProfile == "M" && DSP))
746 Builder.defineMacro("__ARM_FEATURE_SIMD32", "1");
747
748 // ACLE 6.4.10 Hardware Integer Divide
749 if (((HWDiv & HWDivThumb) && isThumb()) ||
750 ((HWDiv & HWDivARM) && !isThumb())) {
751 Builder.defineMacro("__ARM_FEATURE_IDIV", "1");
752 Builder.defineMacro("__ARM_ARCH_EXT_IDIV__", "1");
753 }
754
755 // Note, this is always on in gcc, even though it doesn't make sense.
756 Builder.defineMacro("__APCS_32__");
757
758 if (FPUModeIsVFP((FPUMode)FPU)) {
759 Builder.defineMacro("__VFP_FP__");
760 if (FPU & VFP2FPU)
761 Builder.defineMacro("__ARM_VFPV2__");
762 if (FPU & VFP3FPU)
763 Builder.defineMacro("__ARM_VFPV3__");
764 if (FPU & VFP4FPU)
765 Builder.defineMacro("__ARM_VFPV4__");
766 if (FPU & FPARMV8)
767 Builder.defineMacro("__ARM_FPV5__");
768 }
769
770 // This only gets set when Neon instructions are actually available, unlike
771 // the VFP define, hence the soft float and arch check. This is subtly
772 // different from gcc, we follow the intent which was that it should be set
773 // when Neon instructions are actually available.
774 if ((FPU & NeonFPU) && !SoftFloat && ArchVersion >= 7) {
775 Builder.defineMacro("__ARM_NEON", "1");
776 Builder.defineMacro("__ARM_NEON__");
777 // current AArch32 NEON implementations do not support double-precision
778 // floating-point even when it is present in VFP.
779 Builder.defineMacro("__ARM_NEON_FP",
780 "0x" + Twine::utohexstr(HW_FP & ~HW_FP_DP));
781 }
782
783 if (hasMVE()) {
784 Builder.defineMacro("__ARM_FEATURE_MVE", hasMVEFloat() ? "3" : "1");
785 }
786
787 if (hasCDE()) {
788 Builder.defineMacro("__ARM_FEATURE_CDE", "1");
789 Builder.defineMacro("__ARM_FEATURE_CDE_COPROC",
790 "0x" + Twine::utohexstr(getARMCDECoprocMask()));
791 }
792
793 Builder.defineMacro("__ARM_SIZEOF_WCHAR_T",
794 Twine(Opts.WCharSize ? Opts.WCharSize : 4));
795
796 Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM", Opts.ShortEnums ? "1" : "4");
797
798 // CMSE
799 if (ArchVersion == 8 && ArchProfile == llvm::ARM::ProfileKind::M)
800 Builder.defineMacro("__ARM_FEATURE_CMSE", Opts.Cmse ? "3" : "1");
801
802 if (ArchVersion >= 6 && CPUAttr != "6M" && CPUAttr != "8M_BASE") {
803 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
804 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
805 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4");
806 Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8");
807 }
808
809 // ACLE 6.4.7 DSP instructions
810 if (DSP) {
811 Builder.defineMacro("__ARM_FEATURE_DSP", "1");
812 }
813
814 // ACLE 6.4.8 Saturation instructions
815 bool SAT = false;
816 if ((ArchVersion == 6 && CPUProfile != "M") || ArchVersion > 6) {
817 Builder.defineMacro("__ARM_FEATURE_SAT", "1");
818 SAT = true;
819 }
820
821 // ACLE 6.4.6 Q (saturation) flag
822 if (DSP || SAT)
823 Builder.defineMacro("__ARM_FEATURE_QBIT", "1");
824
825 if (Opts.UnsafeFPMath)
826 Builder.defineMacro("__ARM_FP_FAST", "1");
827
828 // Armv8.2-A FP16 vector intrinsic
829 if ((FPU & NeonFPU) && HasLegalHalfType)
830 Builder.defineMacro("__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", "1");
831
832 // Armv8.2-A FP16 scalar intrinsics
833 if (HasLegalHalfType)
834 Builder.defineMacro("__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", "1");
835
836 // Armv8.2-A dot product intrinsics
837 if (DotProd)
838 Builder.defineMacro("__ARM_FEATURE_DOTPROD", "1");
839
840 if (HasMatMul)
841 Builder.defineMacro("__ARM_FEATURE_MATMUL_INT8", "1");
842
843 if (HasBFloat16) {
844 Builder.defineMacro("__ARM_FEATURE_BF16", "1");
845 Builder.defineMacro("__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", "1");
846 Builder.defineMacro("__ARM_BF16_FORMAT_ALTERNATIVE", "1");
847 }
848
849 switch (ArchKind) {
850 default:
851 break;
852 case llvm::ARM::ArchKind::ARMV8_1A:
853 getTargetDefinesARMV81A(Opts, Builder);
854 break;
855 case llvm::ARM::ArchKind::ARMV8_2A:
856 getTargetDefinesARMV82A(Opts, Builder);
857 break;
858 case llvm::ARM::ArchKind::ARMV8_3A:
859 case llvm::ARM::ArchKind::ARMV8_4A:
860 case llvm::ARM::ArchKind::ARMV8_5A:
861 case llvm::ARM::ArchKind::ARMV8_6A:
862 getTargetDefinesARMV83A(Opts, Builder);
863 break;
864 }
865 }
866
867 const Builtin::Info ARMTargetInfo::BuiltinInfo[] = {
868 #define BUILTIN(ID, TYPE, ATTRS) \
869 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
870 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
871 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
872 #include "clang/Basic/BuiltinsNEON.def"
873
874 #define BUILTIN(ID, TYPE, ATTRS) \
875 {#ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr},
876 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \
877 {#ID, TYPE, ATTRS, nullptr, LANG, nullptr},
878 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \
879 {#ID, TYPE, ATTRS, HEADER, ALL_LANGUAGES, nullptr},
880 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \
881 {#ID, TYPE, ATTRS, HEADER, LANGS, FEATURE},
882 #include "clang/Basic/BuiltinsARM.def"
883 };
884
getTargetBuiltins() const885 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const {
886 return llvm::makeArrayRef(BuiltinInfo, clang::ARM::LastTSBuiltin -
887 Builtin::FirstTSBuiltin);
888 }
889
isCLZForZeroUndef() const890 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; }
getBuiltinVaListKind() const891 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const {
892 return IsAAPCS
893 ? AAPCSABIBuiltinVaList
894 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList
895 : TargetInfo::VoidPtrBuiltinVaList);
896 }
897
898 const char *const ARMTargetInfo::GCCRegNames[] = {
899 // Integer registers
900 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11",
901 "r12", "sp", "lr", "pc",
902
903 // Float registers
904 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11",
905 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22",
906 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31",
907
908 // Double registers
909 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11",
910 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22",
911 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31",
912
913 // Quad registers
914 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11",
915 "q12", "q13", "q14", "q15"};
916
getGCCRegNames() const917 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const {
918 return llvm::makeArrayRef(GCCRegNames);
919 }
920
921 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = {
922 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"},
923 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"},
924 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"},
925 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"},
926 // The S, D and Q registers overlap, but aren't really aliases; we
927 // don't want to substitute one of these for a different-sized one.
928 };
929
getGCCRegAliases() const930 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const {
931 return llvm::makeArrayRef(GCCRegAliases);
932 }
933
validateAsmConstraint(const char * & Name,TargetInfo::ConstraintInfo & Info) const934 bool ARMTargetInfo::validateAsmConstraint(
935 const char *&Name, TargetInfo::ConstraintInfo &Info) const {
936 switch (*Name) {
937 default:
938 break;
939 case 'l': // r0-r7 if thumb, r0-r15 if ARM
940 Info.setAllowsRegister();
941 return true;
942 case 'h': // r8-r15, thumb only
943 if (isThumb()) {
944 Info.setAllowsRegister();
945 return true;
946 }
947 break;
948 case 's': // An integer constant, but allowing only relocatable values.
949 return true;
950 case 't': // s0-s31, d0-d31, or q0-q15
951 case 'w': // s0-s15, d0-d7, or q0-q3
952 case 'x': // s0-s31, d0-d15, or q0-q7
953 Info.setAllowsRegister();
954 return true;
955 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW)
956 // only available in ARMv6T2 and above
957 if (CPUAttr.equals("6T2") || ArchVersion >= 7) {
958 Info.setRequiresImmediate(0, 65535);
959 return true;
960 }
961 break;
962 case 'I':
963 if (isThumb()) {
964 if (!supportsThumb2())
965 Info.setRequiresImmediate(0, 255);
966 else
967 // FIXME: should check if immediate value would be valid for a Thumb2
968 // data-processing instruction
969 Info.setRequiresImmediate();
970 } else
971 // FIXME: should check if immediate value would be valid for an ARM
972 // data-processing instruction
973 Info.setRequiresImmediate();
974 return true;
975 case 'J':
976 if (isThumb() && !supportsThumb2())
977 Info.setRequiresImmediate(-255, -1);
978 else
979 Info.setRequiresImmediate(-4095, 4095);
980 return true;
981 case 'K':
982 if (isThumb()) {
983 if (!supportsThumb2())
984 // FIXME: should check if immediate value can be obtained from shifting
985 // a value between 0 and 255 left by any amount
986 Info.setRequiresImmediate();
987 else
988 // FIXME: should check if immediate value would be valid for a Thumb2
989 // data-processing instruction when inverted
990 Info.setRequiresImmediate();
991 } else
992 // FIXME: should check if immediate value would be valid for an ARM
993 // data-processing instruction when inverted
994 Info.setRequiresImmediate();
995 return true;
996 case 'L':
997 if (isThumb()) {
998 if (!supportsThumb2())
999 Info.setRequiresImmediate(-7, 7);
1000 else
1001 // FIXME: should check if immediate value would be valid for a Thumb2
1002 // data-processing instruction when negated
1003 Info.setRequiresImmediate();
1004 } else
1005 // FIXME: should check if immediate value would be valid for an ARM
1006 // data-processing instruction when negated
1007 Info.setRequiresImmediate();
1008 return true;
1009 case 'M':
1010 if (isThumb() && !supportsThumb2())
1011 // FIXME: should check if immediate value is a multiple of 4 between 0 and
1012 // 1020
1013 Info.setRequiresImmediate();
1014 else
1015 // FIXME: should check if immediate value is a power of two or a integer
1016 // between 0 and 32
1017 Info.setRequiresImmediate();
1018 return true;
1019 case 'N':
1020 // Thumb1 only
1021 if (isThumb() && !supportsThumb2()) {
1022 Info.setRequiresImmediate(0, 31);
1023 return true;
1024 }
1025 break;
1026 case 'O':
1027 // Thumb1 only
1028 if (isThumb() && !supportsThumb2()) {
1029 // FIXME: should check if immediate value is a multiple of 4 between -508
1030 // and 508
1031 Info.setRequiresImmediate();
1032 return true;
1033 }
1034 break;
1035 case 'Q': // A memory address that is a single base register.
1036 Info.setAllowsMemory();
1037 return true;
1038 case 'T':
1039 switch (Name[1]) {
1040 default:
1041 break;
1042 case 'e': // Even general-purpose register
1043 case 'o': // Odd general-purpose register
1044 Info.setAllowsRegister();
1045 Name++;
1046 return true;
1047 }
1048 break;
1049 case 'U': // a memory reference...
1050 switch (Name[1]) {
1051 case 'q': // ...ARMV4 ldrsb
1052 case 'v': // ...VFP load/store (reg+constant offset)
1053 case 'y': // ...iWMMXt load/store
1054 case 't': // address valid for load/store opaque types wider
1055 // than 128-bits
1056 case 'n': // valid address for Neon doubleword vector load/store
1057 case 'm': // valid address for Neon element and structure load/store
1058 case 's': // valid address for non-offset loads/stores of quad-word
1059 // values in four ARM registers
1060 Info.setAllowsMemory();
1061 Name++;
1062 return true;
1063 }
1064 break;
1065 }
1066 return false;
1067 }
1068
convertConstraint(const char * & Constraint) const1069 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const {
1070 std::string R;
1071 switch (*Constraint) {
1072 case 'U': // Two-character constraint; add "^" hint for later parsing.
1073 case 'T':
1074 R = std::string("^") + std::string(Constraint, 2);
1075 Constraint++;
1076 break;
1077 case 'p': // 'p' should be translated to 'r' by default.
1078 R = std::string("r");
1079 break;
1080 default:
1081 return std::string(1, *Constraint);
1082 }
1083 return R;
1084 }
1085
validateConstraintModifier(StringRef Constraint,char Modifier,unsigned Size,std::string & SuggestedModifier) const1086 bool ARMTargetInfo::validateConstraintModifier(
1087 StringRef Constraint, char Modifier, unsigned Size,
1088 std::string &SuggestedModifier) const {
1089 bool isOutput = (Constraint[0] == '=');
1090 bool isInOut = (Constraint[0] == '+');
1091
1092 // Strip off constraint modifiers.
1093 while (Constraint[0] == '=' || Constraint[0] == '+' || Constraint[0] == '&')
1094 Constraint = Constraint.substr(1);
1095
1096 switch (Constraint[0]) {
1097 default:
1098 break;
1099 case 'r': {
1100 switch (Modifier) {
1101 default:
1102 return (isInOut || isOutput || Size <= 64);
1103 case 'q':
1104 // A register of size 32 cannot fit a vector type.
1105 return false;
1106 }
1107 }
1108 }
1109
1110 return true;
1111 }
getClobbers() const1112 const char *ARMTargetInfo::getClobbers() const {
1113 // FIXME: Is this really right?
1114 return "";
1115 }
1116
1117 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1118 ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1119 switch (CC) {
1120 case CC_AAPCS:
1121 case CC_AAPCS_VFP:
1122 case CC_Swift:
1123 case CC_OpenCLKernel:
1124 return CCCR_OK;
1125 default:
1126 return CCCR_Warning;
1127 }
1128 }
1129
getEHDataRegisterNumber(unsigned RegNo) const1130 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const {
1131 if (RegNo == 0)
1132 return 0;
1133 if (RegNo == 1)
1134 return 1;
1135 return -1;
1136 }
1137
hasSjLjLowering() const1138 bool ARMTargetInfo::hasSjLjLowering() const { return true; }
1139
ARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1140 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple,
1141 const TargetOptions &Opts)
1142 : ARMTargetInfo(Triple, Opts) {}
1143
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1144 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1145 MacroBuilder &Builder) const {
1146 Builder.defineMacro("__ARMEL__");
1147 ARMTargetInfo::getTargetDefines(Opts, Builder);
1148 }
1149
ARMbeTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1150 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple,
1151 const TargetOptions &Opts)
1152 : ARMTargetInfo(Triple, Opts) {}
1153
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1154 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts,
1155 MacroBuilder &Builder) const {
1156 Builder.defineMacro("__ARMEB__");
1157 Builder.defineMacro("__ARM_BIG_ENDIAN");
1158 ARMTargetInfo::getTargetDefines(Opts, Builder);
1159 }
1160
WindowsARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1161 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple,
1162 const TargetOptions &Opts)
1163 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) {
1164 }
1165
getVisualStudioDefines(const LangOptions & Opts,MacroBuilder & Builder) const1166 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts,
1167 MacroBuilder &Builder) const {
1168 // FIXME: this is invalid for WindowsCE
1169 Builder.defineMacro("_M_ARM_NT", "1");
1170 Builder.defineMacro("_M_ARMT", "_M_ARM");
1171 Builder.defineMacro("_M_THUMB", "_M_ARM");
1172
1173 assert((Triple.getArch() == llvm::Triple::arm ||
1174 Triple.getArch() == llvm::Triple::thumb) &&
1175 "invalid architecture for Windows ARM target info");
1176 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6;
1177 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset));
1178
1179 // TODO map the complete set of values
1180 // 31: VFPv3 40: VFPv4
1181 Builder.defineMacro("_M_ARM_FP", "31");
1182 }
1183
1184 TargetInfo::BuiltinVaListKind
getBuiltinVaListKind() const1185 WindowsARMTargetInfo::getBuiltinVaListKind() const {
1186 return TargetInfo::CharPtrBuiltinVaList;
1187 }
1188
1189 TargetInfo::CallingConvCheckResult
checkCallingConvention(CallingConv CC) const1190 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
1191 switch (CC) {
1192 case CC_X86StdCall:
1193 case CC_X86ThisCall:
1194 case CC_X86FastCall:
1195 case CC_X86VectorCall:
1196 return CCCR_Ignore;
1197 case CC_C:
1198 case CC_OpenCLKernel:
1199 case CC_PreserveMost:
1200 case CC_PreserveAll:
1201 case CC_Swift:
1202 return CCCR_OK;
1203 default:
1204 return CCCR_Warning;
1205 }
1206 }
1207
1208 // Windows ARM + Itanium C++ ABI Target
ItaniumWindowsARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1209 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo(
1210 const llvm::Triple &Triple, const TargetOptions &Opts)
1211 : WindowsARMTargetInfo(Triple, Opts) {
1212 TheCXXABI.set(TargetCXXABI::GenericARM);
1213 }
1214
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1215 void ItaniumWindowsARMleTargetInfo::getTargetDefines(
1216 const LangOptions &Opts, MacroBuilder &Builder) const {
1217 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1218
1219 if (Opts.MSVCCompat)
1220 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1221 }
1222
1223 // Windows ARM, MS (C++) ABI
MicrosoftARMleTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1224 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple,
1225 const TargetOptions &Opts)
1226 : WindowsARMTargetInfo(Triple, Opts) {
1227 TheCXXABI.set(TargetCXXABI::Microsoft);
1228 }
1229
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1230 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts,
1231 MacroBuilder &Builder) const {
1232 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1233 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder);
1234 }
1235
MinGWARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1236 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple,
1237 const TargetOptions &Opts)
1238 : WindowsARMTargetInfo(Triple, Opts) {
1239 TheCXXABI.set(TargetCXXABI::GenericARM);
1240 }
1241
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1242 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1243 MacroBuilder &Builder) const {
1244 WindowsARMTargetInfo::getTargetDefines(Opts, Builder);
1245 Builder.defineMacro("_ARM_");
1246 }
1247
CygwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1248 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple,
1249 const TargetOptions &Opts)
1250 : ARMleTargetInfo(Triple, Opts) {
1251 this->WCharType = TargetInfo::UnsignedShort;
1252 TLSSupported = false;
1253 DoubleAlign = LongLongAlign = 64;
1254 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64");
1255 }
1256
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1257 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts,
1258 MacroBuilder &Builder) const {
1259 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1260 Builder.defineMacro("_ARM_");
1261 Builder.defineMacro("__CYGWIN__");
1262 Builder.defineMacro("__CYGWIN32__");
1263 DefineStd(Builder, "unix", Opts);
1264 if (Opts.CPlusPlus)
1265 Builder.defineMacro("_GNU_SOURCE");
1266 }
1267
DarwinARMTargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1268 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple,
1269 const TargetOptions &Opts)
1270 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) {
1271 HasAlignMac68kSupport = true;
1272 // iOS always has 64-bit atomic instructions.
1273 // FIXME: This should be based off of the target features in
1274 // ARMleTargetInfo.
1275 MaxAtomicInlineWidth = 64;
1276
1277 if (Triple.isWatchABI()) {
1278 // Darwin on iOS uses a variant of the ARM C++ ABI.
1279 TheCXXABI.set(TargetCXXABI::WatchOS);
1280
1281 // BOOL should be a real boolean on the new ABI
1282 UseSignedCharForObjCBool = false;
1283 } else
1284 TheCXXABI.set(TargetCXXABI::iOS);
1285 }
1286
getOSDefines(const LangOptions & Opts,const llvm::Triple & Triple,MacroBuilder & Builder) const1287 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts,
1288 const llvm::Triple &Triple,
1289 MacroBuilder &Builder) const {
1290 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion);
1291 }
1292
RenderScript32TargetInfo(const llvm::Triple & Triple,const TargetOptions & Opts)1293 RenderScript32TargetInfo::RenderScript32TargetInfo(const llvm::Triple &Triple,
1294 const TargetOptions &Opts)
1295 : ARMleTargetInfo(llvm::Triple("armv7", Triple.getVendorName(),
1296 Triple.getOSName(),
1297 Triple.getEnvironmentName()),
1298 Opts) {
1299 IsRenderScriptTarget = true;
1300 LongWidth = LongAlign = 64;
1301 }
1302
getTargetDefines(const LangOptions & Opts,MacroBuilder & Builder) const1303 void RenderScript32TargetInfo::getTargetDefines(const LangOptions &Opts,
1304 MacroBuilder &Builder) const {
1305 Builder.defineMacro("__RENDERSCRIPT__");
1306 ARMleTargetInfo::getTargetDefines(Opts, Builder);
1307 }
1308