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