1 //===--- ARM.cpp - Implement ARM target feature support -------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements ARM TargetInfo objects. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "ARM.h" 14 #include "clang/Basic/Builtins.h" 15 #include "clang/Basic/Diagnostic.h" 16 #include "clang/Basic/TargetBuiltins.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/ADT/StringRef.h" 19 #include "llvm/ADT/StringSwitch.h" 20 #include "llvm/TargetParser/ARMTargetParser.h" 21 22 using namespace clang; 23 using namespace clang::targets; 24 25 void ARMTargetInfo::setABIAAPCS() { 26 IsAAPCS = true; 27 28 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 29 BFloat16Width = BFloat16Align = 16; 30 BFloat16Format = &llvm::APFloat::BFloat(); 31 32 const llvm::Triple &T = getTriple(); 33 34 bool IsNetBSD = T.isOSNetBSD(); 35 bool IsOpenBSD = T.isOSOpenBSD(); 36 if (!T.isOSWindows() && !IsNetBSD && !IsOpenBSD) 37 WCharType = UnsignedInt; 38 39 UseBitFieldTypeAlignment = true; 40 41 ZeroLengthBitfieldBoundary = 0; 42 43 // Thumb1 add sp, #imm requires the immediate value be multiple of 4, 44 // so set preferred for small types to 32. 45 if (T.isOSBinFormatMachO()) { 46 resetDataLayout(BigEndian 47 ? "E-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 48 : "e-m:o-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64", 49 "_"); 50 } else if (T.isOSWindows()) { 51 assert(!BigEndian && "Windows on ARM does not support big endian"); 52 resetDataLayout("e" 53 "-m:w" 54 "-p:32:32" 55 "-Fi8" 56 "-i64:64" 57 "-v128:64:128" 58 "-a:0:32" 59 "-n32" 60 "-S64"); 61 } else if (T.isOSNaCl()) { 62 assert(!BigEndian && "NaCl on ARM does not support big endian"); 63 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S128"); 64 } else { 65 resetDataLayout(BigEndian 66 ? "E-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64" 67 : "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 68 } 69 70 // FIXME: Enumerated types are variable width in straight AAPCS. 71 } 72 73 void ARMTargetInfo::setABIAPCS(bool IsAAPCS16) { 74 const llvm::Triple &T = getTriple(); 75 76 IsAAPCS = false; 77 78 if (IsAAPCS16) 79 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 64; 80 else 81 DoubleAlign = LongLongAlign = LongDoubleAlign = SuitableAlign = 32; 82 BFloat16Width = BFloat16Align = 16; 83 BFloat16Format = &llvm::APFloat::BFloat(); 84 85 WCharType = SignedInt; 86 87 // Do not respect the alignment of bit-field types when laying out 88 // structures. This corresponds to PCC_BITFIELD_TYPE_MATTERS in gcc. 89 UseBitFieldTypeAlignment = false; 90 91 /// gcc forces the alignment to 4 bytes, regardless of the type of the 92 /// zero length bitfield. This corresponds to EMPTY_FIELD_BOUNDARY in 93 /// gcc. 94 ZeroLengthBitfieldBoundary = 32; 95 96 if (T.isOSBinFormatMachO() && IsAAPCS16) { 97 assert(!BigEndian && "AAPCS16 does not support big-endian"); 98 resetDataLayout("e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128", "_"); 99 } else if (T.isOSBinFormatMachO()) 100 resetDataLayout( 101 BigEndian 102 ? "E-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 103 : "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32", 104 "_"); 105 else 106 resetDataLayout( 107 BigEndian 108 ? "E-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32" 109 : "e-m:e-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32"); 110 111 // FIXME: Override "preferred align" for double and long long. 112 } 113 114 void ARMTargetInfo::setArchInfo() { 115 StringRef ArchName = getTriple().getArchName(); 116 117 ArchISA = llvm::ARM::parseArchISA(ArchName); 118 CPU = std::string(llvm::ARM::getDefaultCPU(ArchName)); 119 llvm::ARM::ArchKind AK = llvm::ARM::parseArch(ArchName); 120 if (AK != llvm::ARM::ArchKind::INVALID) 121 ArchKind = AK; 122 setArchInfo(ArchKind); 123 } 124 125 void ARMTargetInfo::setArchInfo(llvm::ARM::ArchKind Kind) { 126 StringRef SubArch; 127 128 // cache TargetParser info 129 ArchKind = Kind; 130 SubArch = llvm::ARM::getSubArch(ArchKind); 131 ArchProfile = llvm::ARM::parseArchProfile(SubArch); 132 ArchVersion = llvm::ARM::parseArchVersion(SubArch); 133 134 // cache CPU related strings 135 CPUAttr = getCPUAttr(); 136 CPUProfile = getCPUProfile(); 137 } 138 139 void ARMTargetInfo::setAtomic() { 140 // when triple does not specify a sub arch, 141 // then we are not using inline atomics 142 bool ShouldUseInlineAtomic = 143 (ArchISA == llvm::ARM::ISAKind::ARM && ArchVersion >= 6) || 144 (ArchISA == llvm::ARM::ISAKind::THUMB && ArchVersion >= 7); 145 // Cortex M does not support 8 byte atomics, while general Thumb2 does. 146 if (ArchProfile == llvm::ARM::ProfileKind::M) { 147 MaxAtomicPromoteWidth = 32; 148 if (ShouldUseInlineAtomic) 149 MaxAtomicInlineWidth = 32; 150 } else { 151 MaxAtomicPromoteWidth = 64; 152 if (ShouldUseInlineAtomic) 153 MaxAtomicInlineWidth = 64; 154 } 155 } 156 157 bool ARMTargetInfo::hasMVE() const { 158 return ArchKind == llvm::ARM::ArchKind::ARMV8_1MMainline && MVE != 0; 159 } 160 161 bool ARMTargetInfo::hasMVEFloat() const { 162 return hasMVE() && (MVE & MVE_FP); 163 } 164 165 bool ARMTargetInfo::hasCDE() const { return getARMCDECoprocMask() != 0; } 166 167 bool ARMTargetInfo::isThumb() const { 168 return ArchISA == llvm::ARM::ISAKind::THUMB; 169 } 170 171 bool ARMTargetInfo::supportsThumb() const { 172 return CPUAttr.count('T') || ArchVersion >= 6; 173 } 174 175 bool ARMTargetInfo::supportsThumb2() const { 176 return CPUAttr == "6T2" || (ArchVersion >= 7 && CPUAttr != "8M_BASE"); 177 } 178 179 StringRef 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::ARMV9_5A: 230 return "9_5A"; 231 case llvm::ARM::ArchKind::ARMV9_6A: 232 return "9_6A"; 233 case llvm::ARM::ArchKind::ARMV8MBaseline: 234 return "8M_BASE"; 235 case llvm::ARM::ArchKind::ARMV8MMainline: 236 return "8M_MAIN"; 237 case llvm::ARM::ArchKind::ARMV8R: 238 return "8R"; 239 case llvm::ARM::ArchKind::ARMV8_1MMainline: 240 return "8_1M_MAIN"; 241 } 242 } 243 244 StringRef ARMTargetInfo::getCPUProfile() const { 245 switch (ArchProfile) { 246 case llvm::ARM::ProfileKind::A: 247 return "A"; 248 case llvm::ARM::ProfileKind::R: 249 return "R"; 250 case llvm::ARM::ProfileKind::M: 251 return "M"; 252 default: 253 return ""; 254 } 255 } 256 257 ARMTargetInfo::ARMTargetInfo(const llvm::Triple &Triple, 258 const TargetOptions &Opts) 259 : TargetInfo(Triple), FPMath(FP_Default), IsAAPCS(true), LDREX(0), 260 HW_FP(0) { 261 bool IsFreeBSD = Triple.isOSFreeBSD(); 262 bool IsOpenBSD = Triple.isOSOpenBSD(); 263 bool IsNetBSD = Triple.isOSNetBSD(); 264 bool IsHaiku = Triple.isOSHaiku(); 265 bool IsOHOS = Triple.isOHOSFamily(); 266 267 // FIXME: the isOSBinFormatMachO is a workaround for identifying a Darwin-like 268 // environment where size_t is `unsigned long` rather than `unsigned int` 269 270 PtrDiffType = IntPtrType = 271 (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 272 IsNetBSD) 273 ? SignedLong 274 : SignedInt; 275 276 SizeType = (Triple.isOSDarwin() || Triple.isOSBinFormatMachO() || IsOpenBSD || 277 IsNetBSD) 278 ? UnsignedLong 279 : UnsignedInt; 280 281 // ptrdiff_t is inconsistent on Darwin 282 if ((Triple.isOSDarwin() || Triple.isOSBinFormatMachO()) && 283 !Triple.isWatchABI()) 284 PtrDiffType = SignedInt; 285 286 // Cache arch related info. 287 setArchInfo(); 288 289 // {} in inline assembly are neon specifiers, not assembly variant 290 // specifiers. 291 NoAsmVariants = true; 292 293 // FIXME: This duplicates code from the driver that sets the -target-abi 294 // option - this code is used if -target-abi isn't passed and should 295 // be unified in some way. 296 if (Triple.isOSBinFormatMachO()) { 297 // The backend is hardwired to assume AAPCS for M-class processors, ensure 298 // the frontend matches that. 299 if (Triple.getEnvironment() == llvm::Triple::EABI || 300 Triple.getOS() == llvm::Triple::UnknownOS || 301 ArchProfile == llvm::ARM::ProfileKind::M) { 302 setABI("aapcs"); 303 } else if (Triple.isWatchABI()) { 304 setABI("aapcs16"); 305 } else { 306 setABI("apcs-gnu"); 307 } 308 } else if (Triple.isOSWindows()) { 309 // FIXME: this is invalid for WindowsCE 310 setABI("aapcs"); 311 } else { 312 // Select the default based on the platform. 313 switch (Triple.getEnvironment()) { 314 case llvm::Triple::Android: 315 case llvm::Triple::GNUEABI: 316 case llvm::Triple::GNUEABIT64: 317 case llvm::Triple::GNUEABIHF: 318 case llvm::Triple::GNUEABIHFT64: 319 case llvm::Triple::MuslEABI: 320 case llvm::Triple::MuslEABIHF: 321 case llvm::Triple::OpenHOS: 322 setABI("aapcs-linux"); 323 break; 324 case llvm::Triple::EABIHF: 325 case llvm::Triple::EABI: 326 setABI("aapcs"); 327 break; 328 case llvm::Triple::GNU: 329 setABI("apcs-gnu"); 330 break; 331 default: 332 if (IsNetBSD) 333 setABI("apcs-gnu"); 334 else if (IsFreeBSD || IsOpenBSD || IsHaiku || IsOHOS) 335 setABI("aapcs-linux"); 336 else 337 setABI("aapcs"); 338 break; 339 } 340 } 341 342 // ARM targets default to using the ARM C++ ABI. 343 TheCXXABI.set(TargetCXXABI::GenericARM); 344 345 // ARM has atomics up to 8 bytes 346 setAtomic(); 347 348 // Maximum alignment for ARM NEON data types should be 64-bits (AAPCS) 349 // as well the default alignment 350 if (IsAAPCS && !Triple.isAndroid()) 351 DefaultAlignForAttributeAligned = MaxVectorAlign = 64; 352 353 // Do force alignment of members that follow zero length bitfields. If 354 // the alignment of the zero-length bitfield is greater than the member 355 // that follows it, `bar', `bar' will be aligned as the type of the 356 // zero length bitfield. 357 UseZeroLengthBitfieldAlignment = true; 358 359 if (Triple.getOS() == llvm::Triple::Linux || 360 Triple.getOS() == llvm::Triple::UnknownOS) 361 this->MCountName = Opts.EABIVersion == llvm::EABI::GNU 362 ? "llvm.arm.gnu.eabi.mcount" 363 : "\01mcount"; 364 365 SoftFloatABI = llvm::is_contained(Opts.FeaturesAsWritten, "+soft-float-abi"); 366 } 367 368 StringRef ARMTargetInfo::getABI() const { return ABI; } 369 370 bool ARMTargetInfo::setABI(const std::string &Name) { 371 ABI = Name; 372 373 // The defaults (above) are for AAPCS, check if we need to change them. 374 // 375 // FIXME: We need support for -meabi... we could just mangle it into the 376 // name. 377 if (Name == "apcs-gnu" || Name == "aapcs16") { 378 setABIAPCS(Name == "aapcs16"); 379 return true; 380 } 381 if (Name == "aapcs" || Name == "aapcs-vfp" || Name == "aapcs-linux") { 382 setABIAAPCS(); 383 return true; 384 } 385 return false; 386 } 387 388 bool ARMTargetInfo::isBranchProtectionSupportedArch(StringRef Arch) const { 389 llvm::ARM::ArchKind CPUArch = llvm::ARM::parseCPUArch(Arch); 390 if (CPUArch == llvm::ARM::ArchKind::INVALID) 391 CPUArch = llvm::ARM::parseArch(getTriple().getArchName()); 392 393 if (CPUArch == llvm::ARM::ArchKind::INVALID) 394 return false; 395 396 StringRef ArchFeature = llvm::ARM::getArchName(CPUArch); 397 auto a = 398 llvm::Triple(ArchFeature, getTriple().getVendorName(), 399 getTriple().getOSName(), getTriple().getEnvironmentName()); 400 401 StringRef SubArch = llvm::ARM::getSubArch(CPUArch); 402 llvm::ARM::ProfileKind Profile = llvm::ARM::parseArchProfile(SubArch); 403 return a.isArmT32() && (Profile == llvm::ARM::ProfileKind::M); 404 } 405 406 bool ARMTargetInfo::validateBranchProtection(StringRef Spec, StringRef Arch, 407 BranchProtectionInfo &BPI, 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 Builtin::Info BuiltinInfo[] = { 1078 #define BUILTIN(ID, TYPE, ATTRS) \ 1079 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 1080 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 1081 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, 1082 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 1083 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 1084 #include "clang/Basic/BuiltinsNEON.def" 1085 1086 #define BUILTIN(ID, TYPE, ATTRS) \ 1087 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 1088 #define LANGBUILTIN(ID, TYPE, ATTRS, LANG) \ 1089 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANG}, 1090 #define LIBBUILTIN(ID, TYPE, ATTRS, HEADER) \ 1091 {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, ALL_LANGUAGES}, 1092 #define TARGET_BUILTIN(ID, TYPE, ATTRS, FEATURE) \ 1093 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::NO_HEADER, ALL_LANGUAGES}, 1094 #define TARGET_HEADER_BUILTIN(ID, TYPE, ATTRS, HEADER, LANGS, FEATURE) \ 1095 {#ID, TYPE, ATTRS, FEATURE, HeaderDesc::HEADER, LANGS}, 1096 #include "clang/Basic/BuiltinsARM.def" 1097 }; 1098 1099 ArrayRef<Builtin::Info> ARMTargetInfo::getTargetBuiltins() const { 1100 return llvm::ArrayRef(BuiltinInfo, 1101 clang::ARM::LastTSBuiltin - Builtin::FirstTSBuiltin); 1102 } 1103 1104 bool ARMTargetInfo::isCLZForZeroUndef() const { return false; } 1105 TargetInfo::BuiltinVaListKind ARMTargetInfo::getBuiltinVaListKind() const { 1106 return IsAAPCS 1107 ? AAPCSABIBuiltinVaList 1108 : (getTriple().isWatchABI() ? TargetInfo::CharPtrBuiltinVaList 1109 : TargetInfo::VoidPtrBuiltinVaList); 1110 } 1111 1112 const char *const ARMTargetInfo::GCCRegNames[] = { 1113 // Integer registers 1114 "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", 1115 "r12", "sp", "lr", "pc", 1116 1117 // Float registers 1118 "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", 1119 "s12", "s13", "s14", "s15", "s16", "s17", "s18", "s19", "s20", "s21", "s22", 1120 "s23", "s24", "s25", "s26", "s27", "s28", "s29", "s30", "s31", 1121 1122 // Double registers 1123 "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "d8", "d9", "d10", "d11", 1124 "d12", "d13", "d14", "d15", "d16", "d17", "d18", "d19", "d20", "d21", "d22", 1125 "d23", "d24", "d25", "d26", "d27", "d28", "d29", "d30", "d31", 1126 1127 // Quad registers 1128 "q0", "q1", "q2", "q3", "q4", "q5", "q6", "q7", "q8", "q9", "q10", "q11", 1129 "q12", "q13", "q14", "q15"}; 1130 1131 ArrayRef<const char *> ARMTargetInfo::getGCCRegNames() const { 1132 return llvm::ArrayRef(GCCRegNames); 1133 } 1134 1135 const TargetInfo::GCCRegAlias ARMTargetInfo::GCCRegAliases[] = { 1136 {{"a1"}, "r0"}, {{"a2"}, "r1"}, {{"a3"}, "r2"}, {{"a4"}, "r3"}, 1137 {{"v1"}, "r4"}, {{"v2"}, "r5"}, {{"v3"}, "r6"}, {{"v4"}, "r7"}, 1138 {{"v5"}, "r8"}, {{"v6", "rfp"}, "r9"}, {{"sl"}, "r10"}, {{"fp"}, "r11"}, 1139 {{"ip"}, "r12"}, {{"r13"}, "sp"}, {{"r14"}, "lr"}, {{"r15"}, "pc"}, 1140 // The S, D and Q registers overlap, but aren't really aliases; we 1141 // don't want to substitute one of these for a different-sized one. 1142 }; 1143 1144 ArrayRef<TargetInfo::GCCRegAlias> ARMTargetInfo::getGCCRegAliases() const { 1145 return llvm::ArrayRef(GCCRegAliases); 1146 } 1147 1148 bool ARMTargetInfo::validateAsmConstraint( 1149 const char *&Name, TargetInfo::ConstraintInfo &Info) const { 1150 switch (*Name) { 1151 default: 1152 break; 1153 case 'l': // r0-r7 if thumb, r0-r15 if ARM 1154 Info.setAllowsRegister(); 1155 return true; 1156 case 'h': // r8-r15, thumb only 1157 if (isThumb()) { 1158 Info.setAllowsRegister(); 1159 return true; 1160 } 1161 break; 1162 case 's': // An integer constant, but allowing only relocatable values. 1163 return true; 1164 case 't': // s0-s31, d0-d31, or q0-q15 1165 case 'w': // s0-s15, d0-d7, or q0-q3 1166 case 'x': // s0-s31, d0-d15, or q0-q7 1167 if (FPRegsDisabled) 1168 return false; 1169 Info.setAllowsRegister(); 1170 return true; 1171 case 'j': // An immediate integer between 0 and 65535 (valid for MOVW) 1172 // only available in ARMv6T2 and above 1173 if (CPUAttr == "6T2" || ArchVersion >= 7) { 1174 Info.setRequiresImmediate(0, 65535); 1175 return true; 1176 } 1177 break; 1178 case 'I': 1179 if (isThumb()) { 1180 if (!supportsThumb2()) 1181 Info.setRequiresImmediate(0, 255); 1182 else 1183 // FIXME: should check if immediate value would be valid for a Thumb2 1184 // data-processing instruction 1185 Info.setRequiresImmediate(); 1186 } else 1187 // FIXME: should check if immediate value would be valid for an ARM 1188 // data-processing instruction 1189 Info.setRequiresImmediate(); 1190 return true; 1191 case 'J': 1192 if (isThumb() && !supportsThumb2()) 1193 Info.setRequiresImmediate(-255, -1); 1194 else 1195 Info.setRequiresImmediate(-4095, 4095); 1196 return true; 1197 case 'K': 1198 if (isThumb()) { 1199 if (!supportsThumb2()) 1200 // FIXME: should check if immediate value can be obtained from shifting 1201 // a value between 0 and 255 left by any amount 1202 Info.setRequiresImmediate(); 1203 else 1204 // FIXME: should check if immediate value would be valid for a Thumb2 1205 // data-processing instruction when inverted 1206 Info.setRequiresImmediate(); 1207 } else 1208 // FIXME: should check if immediate value would be valid for an ARM 1209 // data-processing instruction when inverted 1210 Info.setRequiresImmediate(); 1211 return true; 1212 case 'L': 1213 if (isThumb()) { 1214 if (!supportsThumb2()) 1215 Info.setRequiresImmediate(-7, 7); 1216 else 1217 // FIXME: should check if immediate value would be valid for a Thumb2 1218 // data-processing instruction when negated 1219 Info.setRequiresImmediate(); 1220 } else 1221 // FIXME: should check if immediate value would be valid for an ARM 1222 // data-processing instruction when negated 1223 Info.setRequiresImmediate(); 1224 return true; 1225 case 'M': 1226 if (isThumb() && !supportsThumb2()) 1227 // FIXME: should check if immediate value is a multiple of 4 between 0 and 1228 // 1020 1229 Info.setRequiresImmediate(); 1230 else 1231 // FIXME: should check if immediate value is a power of two or a integer 1232 // between 0 and 32 1233 Info.setRequiresImmediate(); 1234 return true; 1235 case 'N': 1236 // Thumb1 only 1237 if (isThumb() && !supportsThumb2()) { 1238 Info.setRequiresImmediate(0, 31); 1239 return true; 1240 } 1241 break; 1242 case 'O': 1243 // Thumb1 only 1244 if (isThumb() && !supportsThumb2()) { 1245 // FIXME: should check if immediate value is a multiple of 4 between -508 1246 // and 508 1247 Info.setRequiresImmediate(); 1248 return true; 1249 } 1250 break; 1251 case 'Q': // A memory address that is a single base register. 1252 Info.setAllowsMemory(); 1253 return true; 1254 case 'T': 1255 switch (Name[1]) { 1256 default: 1257 break; 1258 case 'e': // Even general-purpose register 1259 case 'o': // Odd general-purpose register 1260 Info.setAllowsRegister(); 1261 Name++; 1262 return true; 1263 } 1264 break; 1265 case 'U': // a memory reference... 1266 switch (Name[1]) { 1267 case 'q': // ...ARMV4 ldrsb 1268 case 'v': // ...VFP load/store (reg+constant offset) 1269 case 'y': // ...iWMMXt load/store 1270 case 't': // address valid for load/store opaque types wider 1271 // than 128-bits 1272 case 'n': // valid address for Neon doubleword vector load/store 1273 case 'm': // valid address for Neon element and structure load/store 1274 case 's': // valid address for non-offset loads/stores of quad-word 1275 // values in four ARM registers 1276 Info.setAllowsMemory(); 1277 Name++; 1278 return true; 1279 } 1280 break; 1281 } 1282 return false; 1283 } 1284 1285 std::string ARMTargetInfo::convertConstraint(const char *&Constraint) const { 1286 std::string R; 1287 switch (*Constraint) { 1288 case 'U': // Two-character constraint; add "^" hint for later parsing. 1289 case 'T': 1290 R = std::string("^") + std::string(Constraint, 2); 1291 Constraint++; 1292 break; 1293 case 'p': // 'p' should be translated to 'r' by default. 1294 R = std::string("r"); 1295 break; 1296 default: 1297 return std::string(1, *Constraint); 1298 } 1299 return R; 1300 } 1301 1302 bool ARMTargetInfo::validateConstraintModifier( 1303 StringRef Constraint, char Modifier, unsigned Size, 1304 std::string &SuggestedModifier) const { 1305 bool isOutput = (Constraint[0] == '='); 1306 bool isInOut = (Constraint[0] == '+'); 1307 1308 // Strip off constraint modifiers. 1309 Constraint = Constraint.ltrim("=+&"); 1310 1311 switch (Constraint[0]) { 1312 default: 1313 break; 1314 case 'r': { 1315 switch (Modifier) { 1316 default: 1317 return (isInOut || isOutput || Size <= 64); 1318 case 'q': 1319 // A register of size 32 cannot fit a vector type. 1320 return false; 1321 } 1322 } 1323 } 1324 1325 return true; 1326 } 1327 std::string_view ARMTargetInfo::getClobbers() const { 1328 // FIXME: Is this really right? 1329 return ""; 1330 } 1331 1332 TargetInfo::CallingConvCheckResult 1333 ARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1334 switch (CC) { 1335 case CC_AAPCS: 1336 case CC_AAPCS_VFP: 1337 case CC_Swift: 1338 case CC_SwiftAsync: 1339 case CC_OpenCLKernel: 1340 return CCCR_OK; 1341 default: 1342 return CCCR_Warning; 1343 } 1344 } 1345 1346 int ARMTargetInfo::getEHDataRegisterNumber(unsigned RegNo) const { 1347 if (RegNo == 0) 1348 return 0; 1349 if (RegNo == 1) 1350 return 1; 1351 return -1; 1352 } 1353 1354 bool ARMTargetInfo::hasSjLjLowering() const { return true; } 1355 1356 ARMleTargetInfo::ARMleTargetInfo(const llvm::Triple &Triple, 1357 const TargetOptions &Opts) 1358 : ARMTargetInfo(Triple, Opts) {} 1359 1360 void ARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1361 MacroBuilder &Builder) const { 1362 Builder.defineMacro("__ARMEL__"); 1363 ARMTargetInfo::getTargetDefines(Opts, Builder); 1364 } 1365 1366 ARMbeTargetInfo::ARMbeTargetInfo(const llvm::Triple &Triple, 1367 const TargetOptions &Opts) 1368 : ARMTargetInfo(Triple, Opts) {} 1369 1370 void ARMbeTargetInfo::getTargetDefines(const LangOptions &Opts, 1371 MacroBuilder &Builder) const { 1372 Builder.defineMacro("__ARMEB__"); 1373 Builder.defineMacro("__ARM_BIG_ENDIAN"); 1374 ARMTargetInfo::getTargetDefines(Opts, Builder); 1375 } 1376 1377 WindowsARMTargetInfo::WindowsARMTargetInfo(const llvm::Triple &Triple, 1378 const TargetOptions &Opts) 1379 : WindowsTargetInfo<ARMleTargetInfo>(Triple, Opts), Triple(Triple) { 1380 } 1381 1382 void WindowsARMTargetInfo::getVisualStudioDefines(const LangOptions &Opts, 1383 MacroBuilder &Builder) const { 1384 // FIXME: this is invalid for WindowsCE 1385 Builder.defineMacro("_M_ARM_NT", "1"); 1386 Builder.defineMacro("_M_ARMT", "_M_ARM"); 1387 Builder.defineMacro("_M_THUMB", "_M_ARM"); 1388 1389 assert((Triple.getArch() == llvm::Triple::arm || 1390 Triple.getArch() == llvm::Triple::thumb) && 1391 "invalid architecture for Windows ARM target info"); 1392 unsigned Offset = Triple.getArch() == llvm::Triple::arm ? 4 : 6; 1393 Builder.defineMacro("_M_ARM", Triple.getArchName().substr(Offset)); 1394 1395 // TODO map the complete set of values 1396 // 31: VFPv3 40: VFPv4 1397 Builder.defineMacro("_M_ARM_FP", "31"); 1398 } 1399 1400 TargetInfo::BuiltinVaListKind 1401 WindowsARMTargetInfo::getBuiltinVaListKind() const { 1402 return TargetInfo::CharPtrBuiltinVaList; 1403 } 1404 1405 TargetInfo::CallingConvCheckResult 1406 WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const { 1407 switch (CC) { 1408 case CC_X86StdCall: 1409 case CC_X86ThisCall: 1410 case CC_X86FastCall: 1411 case CC_X86VectorCall: 1412 return CCCR_Ignore; 1413 case CC_C: 1414 case CC_OpenCLKernel: 1415 case CC_PreserveMost: 1416 case CC_PreserveAll: 1417 case CC_Swift: 1418 case CC_SwiftAsync: 1419 return CCCR_OK; 1420 default: 1421 return CCCR_Warning; 1422 } 1423 } 1424 1425 // Windows ARM + Itanium C++ ABI Target 1426 ItaniumWindowsARMleTargetInfo::ItaniumWindowsARMleTargetInfo( 1427 const llvm::Triple &Triple, const TargetOptions &Opts) 1428 : WindowsARMTargetInfo(Triple, Opts) { 1429 TheCXXABI.set(TargetCXXABI::GenericARM); 1430 } 1431 1432 void ItaniumWindowsARMleTargetInfo::getTargetDefines( 1433 const LangOptions &Opts, MacroBuilder &Builder) const { 1434 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1435 1436 if (Opts.MSVCCompat) 1437 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1438 } 1439 1440 // Windows ARM, MS (C++) ABI 1441 MicrosoftARMleTargetInfo::MicrosoftARMleTargetInfo(const llvm::Triple &Triple, 1442 const TargetOptions &Opts) 1443 : WindowsARMTargetInfo(Triple, Opts) { 1444 TheCXXABI.set(TargetCXXABI::Microsoft); 1445 } 1446 1447 void MicrosoftARMleTargetInfo::getTargetDefines(const LangOptions &Opts, 1448 MacroBuilder &Builder) const { 1449 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1450 WindowsARMTargetInfo::getVisualStudioDefines(Opts, Builder); 1451 } 1452 1453 MinGWARMTargetInfo::MinGWARMTargetInfo(const llvm::Triple &Triple, 1454 const TargetOptions &Opts) 1455 : WindowsARMTargetInfo(Triple, Opts) { 1456 TheCXXABI.set(TargetCXXABI::GenericARM); 1457 } 1458 1459 void MinGWARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1460 MacroBuilder &Builder) const { 1461 WindowsARMTargetInfo::getTargetDefines(Opts, Builder); 1462 Builder.defineMacro("_ARM_"); 1463 } 1464 1465 CygwinARMTargetInfo::CygwinARMTargetInfo(const llvm::Triple &Triple, 1466 const TargetOptions &Opts) 1467 : ARMleTargetInfo(Triple, Opts) { 1468 this->WCharType = TargetInfo::UnsignedShort; 1469 TLSSupported = false; 1470 DoubleAlign = LongLongAlign = 64; 1471 resetDataLayout("e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64"); 1472 } 1473 1474 void CygwinARMTargetInfo::getTargetDefines(const LangOptions &Opts, 1475 MacroBuilder &Builder) const { 1476 ARMleTargetInfo::getTargetDefines(Opts, Builder); 1477 Builder.defineMacro("_ARM_"); 1478 Builder.defineMacro("__CYGWIN__"); 1479 Builder.defineMacro("__CYGWIN32__"); 1480 DefineStd(Builder, "unix", Opts); 1481 if (Opts.CPlusPlus) 1482 Builder.defineMacro("_GNU_SOURCE"); 1483 } 1484 1485 AppleMachOARMTargetInfo::AppleMachOARMTargetInfo(const llvm::Triple &Triple, 1486 const TargetOptions &Opts) 1487 : AppleMachOTargetInfo<ARMleTargetInfo>(Triple, Opts) {} 1488 1489 void AppleMachOARMTargetInfo::getOSDefines(const LangOptions &Opts, 1490 const llvm::Triple &Triple, 1491 MacroBuilder &Builder) const { 1492 getAppleMachODefines(Builder, Opts, Triple); 1493 } 1494 1495 DarwinARMTargetInfo::DarwinARMTargetInfo(const llvm::Triple &Triple, 1496 const TargetOptions &Opts) 1497 : DarwinTargetInfo<ARMleTargetInfo>(Triple, Opts) { 1498 HasAlignMac68kSupport = true; 1499 if (Triple.isWatchABI()) { 1500 // Darwin on iOS uses a variant of the ARM C++ ABI. 1501 TheCXXABI.set(TargetCXXABI::WatchOS); 1502 1503 // BOOL should be a real boolean on the new ABI 1504 UseSignedCharForObjCBool = false; 1505 } else 1506 TheCXXABI.set(TargetCXXABI::iOS); 1507 } 1508 1509 void DarwinARMTargetInfo::getOSDefines(const LangOptions &Opts, 1510 const llvm::Triple &Triple, 1511 MacroBuilder &Builder) const { 1512 getDarwinDefines(Builder, Opts, Triple, PlatformName, PlatformMinVersion); 1513 } 1514