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