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