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