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