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