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